Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP][Blocked] enhancement of respondd wifi #188

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 0 additions & 27 deletions net/respondd-module-airtime/Makefile

This file was deleted.

38 changes: 0 additions & 38 deletions net/respondd-module-airtime/src/ifaces.c

This file was deleted.

39 changes: 0 additions & 39 deletions net/respondd-module-airtime/src/respondd.c

This file was deleted.

40 changes: 40 additions & 0 deletions net/respondd-module-wifi/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
include $(TOPDIR)/rules.mk

PKG_NAME:=respondd-module-wifi
PKG_VERSION:=1
PKG_RELEASE:=1

PKG_LICENSE:=BSD-2-Clause

PKG_BUILD_DEPENDS := respondd

include $(INCLUDE_DIR)/package.mk

define Package/respondd-module-wifi/Default
SECTION:=net
CATEGORY:=Network
TITLE:=Add wifi statistics to respondd
DEPENDS:=+respondd +libnl-tiny
endef

TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include/libnl-tiny

define Package/respondd-module-wifi
$(call Package/respondd-module-wifi/Default)
endef

define Package/respondd-module-gluonwifi
$(call Package/respondd-module-wifi/Default)
VARIANT:=gluon
TARGET_CFLAGS += -DGLUON
endef

define Package/respondd-module-wifi/install
$(INSTALL_DIR) $(1)/usr/lib/respondd
$(CP) $(PKG_BUILD_DIR)/respondd.so $(1)/usr/lib/respondd/wifi.so
endef

Package/respondd-module-gluonwifi/install = $(Package/respondd-module-wifi/install)

$(eval $(call BuildPackage,respondd-module-wifi))
$(eval $(call BuildPackage,respondd-module-gluonwifi))
Original file line number Diff line number Diff line change
@@ -1,27 +1,61 @@
This module adds a respondd airtime usage statistics provider.
This module adds a respondd wifi usage statistics provider.
The format is the following:

```json
{
"statistics": {
"clients":{
"wifi24": 3,
"wifi5": 7
},
"wireless": [
{
"frequency": 5220,
"channel_width": 40,
"txpower": 1700,
"active": 366561161,
"busy": 46496566,
"rx": 808415,
"tx": 41711344,
"noise": 162
"noise": 162,
"clients": 5
},
{
"frequency": 5220,
"channel_width": 40,
"txpower": 1700,
"active": 366561161,
"busy": 46496566,
"rx": 808415,
"tx": 41711344,
"noise": 162,
"clients": 2
},
{
"frequency": 2437,
"channel_width": 20,
"txpower": 2000,
"active": 366649704,
"busy": 205221222,
"rx": 108121446,
"tx": 85453679,
"noise": 161
"noise": 161,
"clients": 3
}
]
},
"neighbours": {
"wifi":{
"00:11:22:33:44:55:66":{
"frequency": 5220,
"neighbours":{
"33:22:33:11:22:44":{
"signal": 191,
"inactive": 50
}
}
}
}
}
}
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ all: respondd.so

%.c: %.h

respondd.so: netlink.c airtime.c ifaces.c respondd.c
respondd.so: netlink.c ifaces.c airtime.c clients.c neighbours.c respondd.c
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared -fPIC -D_GNU_SOURCE -lnl-tiny -o $@ $^ $(LDLIBS)

clean:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@
* @__NL80211_SURVEY_INFO_AFTER_LAST: internal use
*/

static const char const* msg_names[NL80211_SURVEY_INFO_MAX + 1] = {
[NL80211_SURVEY_INFO_FREQUENCY] = "frequency",
static const char * airtime_names[NL80211_SURVEY_INFO_MAX + 1] = {
[NL80211_SURVEY_INFO_CHANNEL_TIME] = "active",
[NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY] = "busy",
[NL80211_SURVEY_INFO_CHANNEL_TIME_RX] = "rx",
Expand All @@ -67,26 +66,19 @@ static const char const* msg_names[NL80211_SURVEY_INFO_MAX + 1] = {
};

static int survey_airtime_handler(struct nl_msg *msg, void *arg) {
struct json_object *parent_json = (struct json_object *) arg;
struct json_object *json = (struct json_object *) arg;

struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
struct nlattr *survey_info = nla_find(genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NL80211_ATTR_SURVEY_INFO);

if (!survey_info) {
fprintf(stderr, "respondd-module-airtime: survey data missing in netlink message\n");
goto abort;
}

struct json_object *freq_json = json_object_new_object();
if (!freq_json) {
fprintf(stderr, "respondd-module-airtime: failed allocating JSON object\n");
fputs("respondd-module-wifi: survey data missing in netlink message\n", stderr);
goto abort;
}

// This variable counts the number of required attributes that are
// found in the message and is afterwards checked against the number of
// required attributes.
unsigned int req_fields = 0;

int rem;
struct nlattr *nla;
Expand All @@ -96,15 +88,7 @@ static int survey_airtime_handler(struct nl_msg *msg, void *arg) {
if (type > NL80211_SURVEY_INFO_MAX)
continue;

switch (type) {
// these are the required fields
case NL80211_SURVEY_INFO_IN_USE:
case NL80211_SURVEY_INFO_FREQUENCY:
case NL80211_SURVEY_INFO_CHANNEL_TIME:
req_fields++;
}

if (!msg_names[type])
if (!airtime_names[type])
continue;

struct json_object *data_json = NULL;
Expand All @@ -122,18 +106,13 @@ static int survey_airtime_handler(struct nl_msg *msg, void *arg) {
data_json = json_object_new_int(nla_get_u8(nla));
break;
default:
fprintf(stderr, "respondd-module-airtime: Unexpected NL attribute length: %d\n", nla_len(nla));
fprintf(stderr, "respondd-module-wifi: Unexpected NL attribute length: %d\n", nla_len(nla));
}

if (data_json)
json_object_object_add(freq_json, msg_names[type], data_json);
json_object_object_add(json, airtime_names[type], data_json);
}

if (req_fields == 3)
json_object_array_add(parent_json, freq_json);
else
json_object_put(freq_json);

abort:
return NL_SKIP;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#pragma once

#include <stdbool.h>
#include <stdint.h>
#include <json-c/json.h>

__attribute__((visibility("hidden"))) bool get_airtime(struct json_object *result, int ifx);
16 changes: 16 additions & 0 deletions net/respondd-module-wifi/src/clients.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include <linux/nl80211.h>
#include <netlink/genl/genl.h>

#include "netlink.h"
#include "clients.h"

static int station_client_handler(struct nl_msg *msg, void *arg) {
int *count = (int *) arg;

(*count)++;

return NL_SKIP;
}
bool get_client_counts(int *count, int ifx) {
return nl_send_dump(station_client_handler, count, NL80211_CMD_GET_STATION, ifx);
}
5 changes: 5 additions & 0 deletions net/respondd-module-wifi/src/clients.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

#include <stdbool.h>

__attribute__((visibility("hidden"))) bool get_client_counts(int *count, int ifx);
65 changes: 65 additions & 0 deletions net/respondd-module-wifi/src/ifaces.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#include <linux/nl80211.h>
#include <netlink/genl/genl.h>

#include "ifaces.h"
#include "netlink.h"


//https://github.com/torvalds/linux/blob/master/include/uapi/linux/nl80211.h#L4031
static const int chanwidth[NL80211_SURVEY_INFO_MAX + 1] = {
[NL80211_CHAN_WIDTH_20_NOHT] = 20,
[NL80211_CHAN_WIDTH_20] = 20,
[NL80211_CHAN_WIDTH_40] = 40,
[NL80211_CHAN_WIDTH_80] = 80,
[NL80211_CHAN_WIDTH_80P80] = 160,
[NL80211_CHAN_WIDTH_160] = 160,
[NL80211_CHAN_WIDTH_5] = 5,
[NL80211_CHAN_WIDTH_10] = 10,
};

static int iface_dump_handler(struct nl_msg *msg, void *arg) {
struct nlattr *tb[NL80211_ATTR_MAX + 1];
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
struct iface_list **last_next;

nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL);

if (!tb[NL80211_ATTR_WIPHY] || !tb[NL80211_ATTR_IFINDEX])
goto skip;

#ifdef GLUON
if(nla_strcmp(tb[NL80211_ATTR_IFNAME], "client") == -1 || nla_strcmp(tb[NL80211_ATTR_IFNAME], "ibss") == -1 || nla_strcmp(tb[NL80211_ATTR_IFNAME], "mesh") == -1)
goto skip;
#endif

// TODO fix add to head list - instatt find last item
for (last_next = arg; *last_next != NULL; last_next = &(*last_next)->next) {}

*last_next = malloc(sizeof(**last_next));
if (!*last_next)
goto skip;
(*last_next)->next = NULL;
(*last_next)->wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
(*last_next)->ifx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
(*last_next)->frequency = tb[NL80211_ATTR_WIPHY_FREQ] ? nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]) : 0;
(*last_next)->txpower = tb[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] ? nla_get_u32(tb[NL80211_ATTR_WIPHY_TX_POWER_LEVEL]) : 0;
(*last_next)->type = tb[NL80211_ATTR_IFTYPE] ? nla_get_u32(tb[NL80211_ATTR_IFTYPE]) : 0;

if(tb[NL80211_ATTR_MAC]) {
mac_addr_n2a((*last_next)->mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
}

int chanwidth_id = nla_get_u32(tb[NL80211_ATTR_CHANNEL_WIDTH]);

if(chanwidth[chanwidth_id])
(*last_next)->chanwidth = tb[NL80211_ATTR_CHANNEL_WIDTH] ? chanwidth[chanwidth_id] : 0;

skip:
return NL_SKIP;
}

struct iface_list *get_ifaces() {
struct iface_list *ifaces = NULL;
nl_send_dump(&iface_dump_handler, &ifaces, NL80211_CMD_GET_INTERFACE, 0);
return ifaces;
}
Loading