17 #include <libmnl/libmnl.h>
18 #include <linux/nl80211.h>
19 #include <linux/genetlink.h>
21 #include <sys/socket.h>
31 #include <nodelet/nodelet.h>
32 #include <pluginlib/class_list_macros.h>
43 BSSID_STRING_LENGTH = 18,
44 SSID_MAX_LENGTH_WITH_NULL = 33
50 BSS_AUTHENTHICATED = 0,
59 uint8_t bssid[BSSID_LENGTH];
61 char ssid[SSID_MAX_LENGTH_WITH_NULL];
62 enum bss_status status;
70 uint8_t bssid[BSSID_LENGTH];
71 char ssid[SSID_MAX_LENGTH_WITH_NULL];
72 enum bss_status status;
74 int8_t signal_avg_dbm;
93 int WifiScanInit(
const char *interface);
139 int WifiScanAll(
struct bss_info *bss_infos,
int bss_infos_length);
142 std::string bssid_to_string(
const uint8_t bssid[BSSID_LENGTH]) {
143 char bssid_buff[BSSID_STRING_LENGTH];
144 snprintf(bssid_buff, BSSID_STRING_LENGTH,
"%02x:%02x:%02x:%02x:%02x:%02x",
145 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);\
151 struct netlink_channel {
152 struct mnl_socket *nl;
162 struct netlink_channel notification_channel;
163 struct netlink_channel command_channel;
170 struct context_CTRL_CMD_GETFAMILY {
171 uint32_t id_NL80211_MULTICAST_GROUP_SCAN;
175 static int InitNetlinkChannel(
struct netlink_channel *channel,
const char *interface);
177 static int GetFamilyAndScanIds(
struct netlink_channel *channel);
179 static int handle_CTRL_CMD_GETFAMILY(
const struct nlmsghdr *nlh,
void *data);
181 static void parse_CTRL_ATTR_MCAST_GROUPS(
struct nlattr *nested,
struct netlink_channel *channel);
184 static void subscribe_NL80211_MULTICAST_GROUP_SCAN(
struct netlink_channel *channel, uint32_t scan_group_id);
189 static void CloseNetlinkChannel(
struct netlink_channel *channel);
195 struct context_NL80211_MULTICAST_GROUP_SCAN {
196 int new_scan_results;
201 static int ReadPastNotifications(
struct netlink_channel *notifications);
203 static int handle_NL80211_MULTICAST_GROUP_SCAN(
const struct nlmsghdr *nlh,
void *data);
205 static int TriggerScanIfNecessary(
struct netlink_channel *commands,
206 struct context_NL80211_MULTICAST_GROUP_SCAN *scanning);
208 static int WaitForNewScanResults(
struct netlink_channel *notifications);
213 struct context_NL80211_CMD_NEW_SCAN_RESULTS {
215 int bss_infos_length;
220 static int GetScan(
struct netlink_channel *channel);
222 static int handle_NL80211_CMD_NEW_SCAN_RESULTS(
const struct nlmsghdr *nlh,
void *data);
224 static void parse_NL80211_ATTR_BSS(
struct nlattr *nested,
struct netlink_channel *channel);
226 static void parse_NL80211_BSS_INFORMATION_ELEMENTS(
struct nlattr *attr,
char SSID_OUT[33]);
228 static void parse_NL80211_BSS_BSSID(
struct nlattr *attr, uint8_t bssid_out[BSSID_LENGTH]);
233 struct context_NL80211_CMD_NEW_STATION {
238 static int GetStation(
struct netlink_channel *channel, uint8_t bssid[BSSID_LENGTH]);
240 static int handle_NL80211_CMD_NEW_STATION(
const struct nlmsghdr *nlh,
void *data);
242 static void parse_NL80211_ATTR_STA_INFO(
struct nlattr *nested,
struct netlink_channel *channel);
251 static struct nlmsghdr *PrepareNlMessage(uint32_t type, uint16_t flags,
252 uint8_t genl_cmd,
struct netlink_channel *channel);
254 static void SendNlMessage(
struct nlmsghdr *nlh,
struct netlink_channel *channel);
256 static int ReceiveNlMessage(
struct netlink_channel *channel, mnl_cb_t callback);
261 struct validation_data {
263 struct nlattr **attribute_table;
265 int attribute_length;
268 int validation_length;
272 static int Validate(
const struct nlattr *attr,
void *data);
277 struct wifi_scan *wifi_;
286 enum mnl_attr_data_type type;
294 {CTRL_ATTR_FAMILY_ID, MNL_TYPE_U16},
295 {CTRL_ATTR_MCAST_GROUPS, MNL_TYPE_NESTED}
298 static constexpr
struct attribute_validation NL80211_MCAST_GROUPS_VALIDATION[2] = {
299 {CTRL_ATTR_MCAST_GRP_ID, MNL_TYPE_U32},
300 {CTRL_ATTR_MCAST_GRP_NAME, MNL_TYPE_STRING}
303 static constexpr
struct attribute_validation NL80211_BSS_VALIDATION[6] = {
304 {NL80211_BSS_BSSID, MNL_TYPE_BINARY, 6},
305 {NL80211_BSS_FREQUENCY, MNL_TYPE_U32},
306 {NL80211_BSS_INFORMATION_ELEMENTS, MNL_TYPE_BINARY},
307 {NL80211_BSS_STATUS, MNL_TYPE_U32},
308 {NL80211_BSS_SIGNAL_MBM, MNL_TYPE_U32},
309 {NL80211_BSS_SEEN_MS_AGO, MNL_TYPE_U32}
312 static constexpr
struct attribute_validation NL80211_NEW_SCAN_RESULTS_VALIDATION[3] = {
313 {NL80211_ATTR_IFINDEX, MNL_TYPE_U32},
314 {NL80211_ATTR_SCAN_SSIDS, MNL_TYPE_NESTED},
315 {NL80211_ATTR_BSS, MNL_TYPE_NESTED}
318 static constexpr
struct attribute_validation NL80211_CMD_NEW_STATION_VALIDATION[1] = {
319 {NL80211_ATTR_STA_INFO, MNL_TYPE_NESTED}
322 static constexpr
struct attribute_validation NL80211_STA_INFO_VALIDATION[4] = {
323 {NL80211_STA_INFO_SIGNAL, MNL_TYPE_U8},
324 {NL80211_STA_INFO_SIGNAL_AVG, MNL_TYPE_U8},
325 {NL80211_STA_INFO_RX_PACKETS, MNL_TYPE_U32},
326 {NL80211_STA_INFO_TX_PACKETS, MNL_TYPE_U32}
329 static constexpr
int NL80211_VALIDATION_LENGTH
330 =
sizeof(NL80211_VALIDATION)/
sizeof(
struct attribute_validation);
331 static constexpr
int NL80211_MCAST_GROUPS_VALIDATION_LENGTH
332 =
sizeof(NL80211_MCAST_GROUPS_VALIDATION)/
sizeof(
struct attribute_validation);
333 static constexpr
int NL80211_BSS_VALIDATION_LENGTH
334 =
sizeof(NL80211_BSS_VALIDATION)/
sizeof(
struct attribute_validation);
335 static constexpr
int NL80211_NEW_SCAN_RESULTS_VALIDATION_LENGTH
336 =
sizeof(NL80211_NEW_SCAN_RESULTS_VALIDATION)/
sizeof(
struct attribute_validation);
337 static constexpr
int NL80211_CMD_NEW_STATION_VALIDATION_LENGTH
338 =
sizeof(NL80211_CMD_NEW_STATION_VALIDATION)/
sizeof(
struct attribute_validation);
339 static constexpr
int NL80211_STA_INFO_VALIDATION_LENGTH
340 =
sizeof(NL80211_STA_INFO_VALIDATION)/
sizeof(
struct attribute_validation);
344 #endif // WIFI_WIFI_H_