84 lines
2.2 KiB
C
84 lines
2.2 KiB
C
#include <linux/nl80211.h>
|
|
#include <netlink/genl/genl.h>
|
|
|
|
#include "netlink.h"
|
|
#include "neighbours.h"
|
|
|
|
static const char * neighbours_names[NL80211_STA_INFO_MAX + 1] = {
|
|
[NL80211_STA_INFO_SIGNAL] = "signal",
|
|
[NL80211_STA_INFO_INACTIVE_TIME] = "inactive",
|
|
};
|
|
|
|
static int station_neighbours_handler(struct nl_msg *msg, void *arg) {
|
|
struct json_object *neighbour, *json = (struct json_object *) arg;
|
|
|
|
neighbour = json_object_new_object();
|
|
if (!neighbour) {
|
|
//TODO why needed? : json_object_put(result);
|
|
goto abort;
|
|
}
|
|
|
|
struct nlattr *tb[NL80211_ATTR_MAX + 1];
|
|
|
|
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
|
|
struct nlattr *station_info = nla_find(genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NL80211_ATTR_STA_INFO);
|
|
|
|
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL);
|
|
|
|
if (!station_info) {
|
|
fputs("respondd-module-wifi: station data missing in netlink message\n", stderr);
|
|
goto abort;
|
|
}
|
|
|
|
char mac_addr[20];
|
|
|
|
if (!tb[NL80211_ATTR_MAC])
|
|
goto abort;
|
|
mac_addr_n2a(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
|
|
|
|
int rem;
|
|
struct nlattr *nla;
|
|
nla_for_each_nested(nla, station_info, rem) {
|
|
int type = nla_type(nla);
|
|
|
|
if (type > NL80211_STA_INFO_MAX)
|
|
continue;
|
|
|
|
if (!neighbours_names[type])
|
|
continue;
|
|
|
|
struct json_object *data_json = NULL;
|
|
switch (nla_len(nla)) {
|
|
case sizeof(uint64_t):
|
|
data_json = json_object_new_int64(nla_get_u64(nla));
|
|
break;
|
|
case sizeof(uint32_t):
|
|
data_json = json_object_new_int(nla_get_u32(nla));
|
|
break;
|
|
case sizeof(uint8_t):
|
|
data_json = json_object_new_int(nla_get_u8(nla));
|
|
break;
|
|
default:
|
|
fprintf(stderr, "respondd-module-wifi: Unexpected NL attribute length: %d\n", nla_len(nla));
|
|
}
|
|
if (data_json)
|
|
json_object_object_add(neighbour, neighbours_names[type], data_json);
|
|
}
|
|
json_object_object_add(json, mac_addr, neighbour);
|
|
|
|
abort:
|
|
return NL_SKIP;
|
|
}
|
|
|
|
bool get_neighbours(struct json_object *result, int ifx) {
|
|
struct json_object *neighbours;
|
|
neighbours = json_object_new_object();
|
|
if (!neighbours)
|
|
return false;
|
|
if(!nl_send_dump(station_neighbours_handler, neighbours, NL80211_CMD_GET_STATION, ifx))
|
|
return false;
|
|
json_object_object_add(result, "neighbours", neighbours);
|
|
return true;
|
|
|
|
}
|