respondd-module-airtime: improve error handling

- Return either NL_OK or NL_STOP from callback
- Return the generated airtime entry from get_airtime()
This commit is contained in:
Matthias Schiffer 2021-07-15 19:52:14 +02:00 committed by David Bauer
parent b4858b1509
commit 1dd5cd1706
3 changed files with 30 additions and 23 deletions

View File

@ -67,20 +67,26 @@ static const char const* msg_names[NL80211_SURVEY_INFO_MAX + 1] = {
}; };
static int survey_airtime_handler(struct nl_msg *msg, void *arg) { static int survey_airtime_handler(struct nl_msg *msg, void *arg) {
struct json_object *parent_json = (struct json_object *) arg; struct json_object **result = arg;
struct json_object *freq_json = NULL;
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); 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); struct nlattr *survey_info = nla_find(genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NL80211_ATTR_SURVEY_INFO);
if (!survey_info) { if (*result) {
fprintf(stderr, "respondd-module-airtime: survey data missing in netlink message\n"); fprintf(stderr, "respondd-module-airtime: callback called again after NL_STOP\n");
goto abort; return NL_STOP;
} }
struct json_object *freq_json = json_object_new_object(); if (!survey_info) {
fprintf(stderr, "respondd-module-airtime: survey data missing in netlink message\n");
return NL_STOP;
}
freq_json = json_object_new_object();
if (!freq_json) { if (!freq_json) {
fprintf(stderr, "respondd-module-airtime: failed allocating JSON object\n"); fprintf(stderr, "respondd-module-airtime: failed allocating JSON object\n");
goto abort; return NL_STOP;
} }
// This variable counts the number of required attributes that are // This variable counts the number of required attributes that are
@ -129,15 +135,19 @@ static int survey_airtime_handler(struct nl_msg *msg, void *arg) {
json_object_object_add(freq_json, msg_names[type], data_json); json_object_object_add(freq_json, msg_names[type], data_json);
} }
if (req_fields == 3) /* The kernel didn't report all required fields: continue with next
json_object_array_add(parent_json, freq_json); * record, this entry was off-channel */
else if (req_fields != 3) {
json_object_put(freq_json); json_object_put(freq_json);
return NL_OK;
}
abort: *result = freq_json;
return NL_SKIP; return NL_STOP;
} }
bool get_airtime(struct json_object *result, int ifx) { struct json_object * get_airtime(int ifx) {
return nl_send_dump(survey_airtime_handler, result, NL80211_CMD_GET_SURVEY, ifx); struct json_object *result = NULL;
nl_send_dump(survey_airtime_handler, &result, NL80211_CMD_GET_SURVEY, ifx);
return result;
} }

View File

@ -4,4 +4,5 @@
#include <stdint.h> #include <stdint.h>
#include <json-c/json.h> #include <json-c/json.h>
__attribute__((visibility("hidden"))) bool get_airtime(struct json_object *result, int ifx); __attribute__((visibility("hidden")))
struct json_object * get_airtime(int ifx);

View File

@ -7,9 +7,7 @@
#include "ifaces.h" #include "ifaces.h"
static struct json_object *respondd_provider_statistics(void) { static struct json_object *respondd_provider_statistics(void) {
bool ok; struct json_object *result, *wireless;
int newest_element_index;
struct json_object *last, *result, *wireless;
struct iface_list *ifaces; struct iface_list *ifaces;
result = json_object_new_object(); result = json_object_new_object();
@ -24,12 +22,10 @@ static struct json_object *respondd_provider_statistics(void) {
ifaces = get_ifaces(); ifaces = get_ifaces();
while (ifaces != NULL) { while (ifaces != NULL) {
ok = get_airtime(wireless, ifaces->ifx); struct json_object *entry = get_airtime(ifaces->ifx);
if (ok) { if (entry) {
newest_element_index = json_object_array_length(wireless) - 1; json_object_object_add(entry, "phy", json_object_new_int(ifaces->wiphy));
last = json_object_array_get_idx(wireless, newest_element_index); json_object_array_add(wireless, entry);
if (last)
json_object_object_add(last, "phy", json_object_new_int(ifaces->wiphy));
} }
void *freeptr = ifaces; void *freeptr = ifaces;
ifaces = ifaces->next; ifaces = ifaces->next;