diff --git a/README.md b/README.md index ccf8c9c9d594d69283ac55b7d577fc2bd3bf71c1..ba0624c3b752e6b362976348d4afd84bb5790331 100644 --- a/README.md +++ b/README.md @@ -491,6 +491,7 @@ root@iopsys-021000000001:~# ubus -v list map.controller "client_assoc_cntlr":{"agent":"String","bssid":"String","assoc_cntl_mode":"Integer","assoc_valid_timeout":"Integer","stalist":"Array"} "ap_metric_query":{"agent":"String","bsslist":"Array","radiolist":"Array"} "scan":{"agent":"String","radio":"Array","opclass":"Array","channel":"Array","fresh_scan":"Boolean"} + "scan_results":{"radio":"Array"} "sta_metric_query":{"agent":"String","sta":"String"} "unassoc_sta_lm_query":{"agent":"String","opclass":"Integer","metrics":"Array"} "bcn_metrics_query":{"agent":"String","sta":"String","opclass":"Integer","channel":"Integer","bssid":"String","reporting_detail":"Integer","ssid":"String","channel_report":"Array","request_element":"Array"} @@ -500,4 +501,5 @@ root@iopsys-021000000001:~# ubus -v list map.controller "cac_term":{"agent":"String","radiolist":"Array"} "higher_layer_data":{"agent":"String","protocol":"Integer","data":"String"} "send_combined_metrics":{"agent":"String","bssid":"String"} + "sync":{"agent":"String"} ``` diff --git a/src/cntlr_ubus.c b/src/cntlr_ubus.c index 68a8f9e04ad46d9fdb37bfa97c61b1ebc37a4000..30a9a37f3aacdcd3eda6a612949e19a54f15446f 100644 --- a/src/cntlr_ubus.c +++ b/src/cntlr_ubus.c @@ -254,6 +254,15 @@ static const struct blobmsg_policy scan_policy_params[__SCAN_POLICY_MAX] = { [SCAN_POLICY_FRESH_SCAN] = { .name = "fresh_scan", .type = BLOBMSG_TYPE_BOOL } }; +enum { + SCAN_RESULTS_RADIO, + __SCAN_RESULTS_MAX, +}; + +static const struct blobmsg_policy scan_results_params[__SCAN_RESULTS_MAX] = { + [SCAN_RESULTS_RADIO] = { .name = "radio", .type = BLOBMSG_TYPE_ARRAY }, +}; + enum { STA_METRIC_QUERY_AGENT, STA_METRIC_QUERY_STA, @@ -2255,6 +2264,158 @@ static int cntlr_scan(struct ubus_context *ctx, struct ubus_object *obj, return ret; } +static int cntlr_scan_results(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct controller *c = container_of(obj, struct controller, obj); + struct blob_buf bb; + struct node *n; + void *b; + struct blob_attr *tb[__SCAN_RESULTS_MAX]; + int num_radio_queried = 0; + uint8_t radio_ids[MAX_NUM_RADIO][6] = {}; + + blobmsg_parse(scan_results_params, __SCAN_RESULTS_MAX, tb, + blob_data(msg), blob_len(msg)); + + if (tb[SCAN_RESULTS_RADIO]) { + int rem; + struct blob_attr *attr; + char mac_str[18] = {0}; + + if (!blobmsg_check_array(tb[SCAN_RESULTS_RADIO], BLOBMSG_TYPE_STRING)) + return UBUS_STATUS_INVALID_ARGUMENT; + + blobmsg_for_each_attr(attr, tb[SCAN_RESULTS_RADIO], rem) { + if (blobmsg_type(attr) != BLOBMSG_TYPE_STRING) { + dbg("|%s:%d| Radios have to be string.\n", __func__, __LINE__); + return UBUS_STATUS_INVALID_ARGUMENT; + } + + strncpy(mac_str, blobmsg_data(attr), sizeof(mac_str) - 1); + if (!hwaddr_aton(mac_str, radio_ids[num_radio_queried])) { + return UBUS_STATUS_UNKNOWN_ERROR; + } + + num_radio_queried++; + } + } + + memset(&bb, 0, sizeof(bb)); + blob_buf_init(&bb, 0); + + b = blobmsg_open_array(&bb, "radios"); + + list_for_each_entry(n, &c->nodelist, list) { + struct netif_radio *p = NULL; + + list_for_each_entry(p, &n->radiolist, list) { + char macaddrstr[18] = {0}; + void *t1, *t2; + struct wifi_scanres_element *el = NULL; + int i; + + if (num_radio_queried) { + bool is_radio_queried = false; + + for (i = 0; i < num_radio_queried; i++) { + if (!memcmp(p->radio_el->macaddr, radio_ids[i], 6)) + is_radio_queried = true; + } + + if (!is_radio_queried) + /* try next radio from radiolist */ + continue; + } + + hwaddr_ntoa(p->radio_el->macaddr, macaddrstr); + + t1 = blobmsg_open_table(&bb, ""); + + blobmsg_add_string(&bb, "radio", macaddrstr); + blobmsg_add_u32(&bb, "num_scanresult", p->radio_el->num_scanresult); + + t2 = blobmsg_open_array(&bb, "scanlist"); + + list_for_each_entry(el, &p->radio_el->scanlist, list) { + void *tt1, *tt2; + struct wifi_scanres_opclass_element *op = NULL; + + tt1 = blobmsg_open_table(&bb, ""); + + blobmsg_add_string(&bb, "tsp", el->tsp); + blobmsg_add_u32(&bb, "num_opclass_scanned", el->num_opclass_scanned); + + tt2 = blobmsg_open_array(&bb, "opclasses"); + + list_for_each_entry(op, &el->opclass_scanlist, list) { + void *ttt1, *ttt2; + struct wifi_scanres_channel_element *ch = NULL; + + ttt1 = blobmsg_open_table(&bb, ""); + + blobmsg_add_u32(&bb, "opclass", op->opclass); + + ttt2 = blobmsg_open_array(&bb, "channels"); + + list_for_each_entry(ch, &op->channel_scanlist, list) { + void *tttt1, *tttt2; + struct wifi_scanres_neighbor_element *nbr = NULL; + char bssstr[18] = {0}; + + tttt1 = blobmsg_open_table(&bb, ""); + + blobmsg_add_string(&bb, "tsp", ch->tsp); + blobmsg_add_u32(&bb, "channel", ch->channel); + blobmsg_add_u32(&bb, "utilization", ch->utilization); + blobmsg_add_u32(&bb, "anpi", ch->anpi); + blobmsg_add_u32(&bb, "num_neighbors", ch->num_neighbors); + + tttt2 = blobmsg_open_array(&bb, "nbrlist"); + + list_for_each_entry(nbr, &ch->nbrlist, list) { + void *ttttt; + + if (!ch->num_neighbors) + break; + + ttttt = blobmsg_open_table(&bb, ""); + + if (nbr->bssid) { + hwaddr_ntoa(nbr->bssid, bssstr); + } + blobmsg_add_string(&bb, "bssid", bssstr); + blobmsg_add_string(&bb, "ssid", nbr->ssid); + blobmsg_add_u32(&bb, "rssi", nbr->rssi); + blobmsg_add_u32(&bb, "bw", nbr->bw); + blobmsg_add_u32(&bb, "utilization", nbr->utilization); + blobmsg_add_u32(&bb, "num_stations", nbr->num_stations); + + blobmsg_close_table(&bb, ttttt); + } + blobmsg_close_table(&bb, tttt2); + blobmsg_close_table(&bb, tttt1); + } + blobmsg_close_table(&bb, ttt2); + blobmsg_close_table(&bb, ttt1); + } + blobmsg_close_table(&bb, tt2); + blobmsg_close_table(&bb, tt1); + } + blobmsg_close_array(&bb, t2); + blobmsg_close_table(&bb, t1); + } + + } + blobmsg_close_array(&bb, b); + + ubus_send_reply(ctx, req, bb.head); + blob_buf_free(&bb); + + return UBUS_STATUS_OK; +} + static int cntlr_sta_metric_query(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) @@ -3041,6 +3202,8 @@ int cntlr_publish_object(struct controller *c, const char *objname) UBUS_METHOD("ap_metric_query", cntlr_ap_metric_query, ap_metric_query_params), UBUS_METHOD("scan", cntlr_scan, scan_policy_params), + UBUS_METHOD("scan_results", cntlr_scan_results, + scan_results_params), UBUS_METHOD("sta_metric_query", cntlr_sta_metric_query, sta_metric_query_params), UBUS_METHOD("unassoc_sta_lm_query", cntlr_unassoc_sta_lm_query,