diff --git a/src/Makefile b/src/Makefile index 3372229ead2da687bccc43ae312264c7011628c1..50c570df80719cc9559d9e5283474f64b62ecbd1 100644 --- a/src/Makefile +++ b/src/Makefile @@ -24,6 +24,7 @@ OBJS = \ cntlr_commands.o \ cntlr_commands_impl.o \ cntlr_ubus.o \ + cntlr_ubus_dbg.o \ cntlr.o \ cntlr_map.o \ cntlr_tlv.o \ diff --git a/src/cntlr.c b/src/cntlr.c index c0f6f7cce879bbec9be3150414c872d18a5ae04d..611b2b13f34fcdb4e560623f4543835f5b02b030 100644 --- a/src/cntlr.c +++ b/src/cntlr.c @@ -54,6 +54,7 @@ #include "wifi_dataelements.h" #include "wifi_opclass.h" #include "steer.h" +#include "cntlr_ubus_dbg.h" #define map_plugin "ieee1905.map" @@ -1498,7 +1499,7 @@ static void cntlr_start(atimer_t *t) if (c->state == CNTLR_INIT) { c->state = CNTLR_START; cntlr_publish_object(c, "map.controller"); - //cntlr_publish_dbg_object(c, "map.controller.dbg"); //TODO: open + cntlr_publish_dbg_object(c, "map.controller.dbg"); } } diff --git a/src/cntlr_ubus_dbg.c b/src/cntlr_ubus_dbg.c index e66a91b048114783dc77edb78a90b65eb1d5233c..f4abea7d0677def82afd29317c2bf86909b22f50 100644 --- a/src/cntlr_ubus_dbg.c +++ b/src/cntlr_ubus_dbg.c @@ -1,290 +1,169 @@ -/* - * cntlr_ubus_dbg.c - for testing purpose only - * - * Copyright (C) 2022 IOPSYS Software Solutions AB. All rights reserved. - * - */ - #include <stdio.h> #include <stdlib.h> #include <stdint.h> +#include <errno.h> #include <string.h> -#include <unistd.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -#include <libubox/blobmsg.h> -#include <libubox/blobmsg_json.h> -#include <libubox/uloop.h> -#include <libubox/ustream.h> -#include <libubox/utils.h> -#include <libubus.h> -#include <uci.h> - -#include <easy/easy.h> -#include <cmdu.h> -#include <i1905_wsc.h> -#include <1905_tlvs.h> +#include <time.h> #include <easymesh.h> -#include <map_module.h> - +#include <easy/easy.h> #include <wifidefs.h> -#include "wifi_dataelements.h" - -#include "timer.h" -#include "utils/utils.h" -#include "utils/debug.h" -#include "config.h" +#include <cmdu.h> +#include <libubox/blobmsg.h> #if (EASYMESH_VERSION > 2) -#include "dpp.h" +#ifdef USE_LIBDPP +#include <dpp_api.h> +#endif #endif + +#include "utils/debug.h" #include "cntlr.h" +#include "acs.h" +#include "cntlr_cmdu.h" +#include "cntlr_commands.h" #include "cntlr_map.h" -#include "cntlr_ubus.h" #include "cntlr_tlv.h" -#include "cntlr_cmdu.h" -#include "topology.h" -#include "cntlr_ubus.h" +#include "config.h" +#include "utils/utils.h" +#include "timer.h" +#include "sta.h" +#include "wifi_opclass.h" +#include "wifi_dataelements.h" +#include "cntlr_extension.h" #define OBJECT_INVALID ((uint32_t)-1) #ifndef MAP_CNTLR_DISABLE_UBUS_DBG -enum { - CLR_STEER_SUMMARY_STA, - __CLR_STEER_SUMMARY_MAX, -}; - -static const struct blobmsg_policy clr_steer_summary_params[__CLR_STEER_SUMMARY_MAX] = { - [CLR_STEER_SUMMARY_STA] = { .name = "sta", .type = BLOBMSG_TYPE_STRING}, -}; - -static int cntlr_dbg_list_macs(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) +static struct bh_topology_dev *topology_get_dev(struct controller *c, uint8_t *mac) { - struct controller *c = container_of(obj, struct controller, obj_dbg); - struct map_macaddr_entry *entry = NULL; - struct blob_buf bb = {0}; - char macaddrstr[18] = {0}; - void *t, *tt; - int i; - - memset(&bb, 0, sizeof(bb)); - blob_buf_init(&bb, 0); - t = blobmsg_open_table(&bb, "mac_table"); - - for (i = 0; i < MAC_HTBL_SIZE; i++) { - if (hlist_empty(&c->mac_table.table[i])) - continue; - - hlist_for_each_entry(entry, &c->mac_table.table[i], hlist) { - tt = blobmsg_open_table(&bb, ""); + struct bh_topology_dev *dev; - hwaddr_ntoa(entry->macaddr, macaddrstr); - blobmsg_add_string(&bb, "macaddr", macaddrstr); - blobmsg_add_string(&bb, "type", macaddr_type2str(entry->type)); - - blobmsg_close_table(&bb, tt); - } + list_for_each_entry(dev, &c->topology.dev_list, list) { + if (!memcmp(dev->al_macaddr, mac, 6)) + return dev; } - blobmsg_close_table(&bb, t); - ubus_send_reply(ctx, req, bb.head); - blob_buf_free(&bb); - - return UBUS_STATUS_OK; + return NULL; } -static int cntlr_dbg_clear_steer_summary(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) +static bool topology_dev_any_leaf(struct controller *c, struct bh_topology_dev *dev) { - struct controller *c = container_of(obj, struct controller, obj_dbg); - struct blob_attr *tb[__CLR_STEER_SUMMARY_MAX]; - uint8_t macaddr[6] = {0}; - char sta[18] = {0}; - struct sta *s = NULL; - struct node *n = NULL; - - blobmsg_parse(clr_steer_summary_params, __CLR_STEER_SUMMARY_MAX, tb, - blob_data(msg), blob_len(msg)); - - if (tb[CLR_STEER_SUMMARY_STA]) { - strncpy(sta, blobmsg_data(tb[CLR_STEER_SUMMARY_STA]), - sizeof(sta) - 1); - if (!hwaddr_aton(sta, macaddr)) { - dbg("|%s:%d|Must provide valid STA address!\n", - __func__, __LINE__); - return UBUS_STATUS_UNKNOWN_ERROR; - } - } - - if (!hwaddr_is_zero(macaddr)) { - s = cntlr_find_sta(c, macaddr); - if (s) { - s->de_sta->mapsta.stats.no_candidate_cnt = 0; - s->de_sta->mapsta.stats.blacklist_attempt_cnt = 0; - s->de_sta->mapsta.stats.blacklist_success_cnt = 0; - s->de_sta->mapsta.stats.blacklist_failure_cnt = 0; - s->de_sta->mapsta.stats.btm_attempt_cnt = 0; - s->de_sta->mapsta.stats.btm_success_cnt = 0; - s->de_sta->mapsta.stats.btm_failure_cnt = 0; - s->de_sta->mapsta.stats.btm_query_resp_cnt = 0; - s->de_sta->mapsta.failed_steer_attempts = 0; - timestamp_reset(&s->de_sta->mapsta.stats.last_attempt_tsp); - timestamp_reset(&s->de_sta->mapsta.stats.last_steer_tsp); - - } - return UBUS_STATUS_OK; - } + int i, j; - list_for_each_entry(n, &c->nodelist, list) { - s = NULL; - list_for_each_entry(s, &n->stalist, list) { - struct wifi_multiap_sta *msta = - s->de_sta->mapsta; - - msta.stats.no_candidate_cnt = 0; - msta.stats.blacklist_attempt_cnt = 0; - msta.stats.blacklist_success_cnt = 0; - msta.stats.blacklist_failure_cnt = 0; - msta.stats.btm_attempt_cnt = 0; - msta.stats.btm_success_cnt = 0; - msta.stats.btm_failure_cnt = 0; - msta.stats.btm_query_resp_cnt = 0; - msta.stats.failed_steer_attempts = 0; - timestamp_reset(&msta.stats.last_attempt_tsp); - timestamp_reset(&msta.stats.last_steer_tsp); + for (i = 0; i < dev->number_of_interfaces; i++) { + if (dev->ifaces[i].number_of_neighbors == 0) + continue; + for (j = 0; j < dev->ifaces[i].number_of_neighbors; j++) { + struct bh_topology_dev *subdev; + subdev = topology_get_dev(c, dev->ifaces[i].neighbors_al_macs[j]); + if (subdev && subdev->bh.parent == dev) + return true; } } - c->dlem.network.steer_summary.no_candidate_cnt = 0; - c->dlem.network.steer_summary.blacklist_attempt_cnt = 0; - c->dlem.network.steer_summary.blacklist_success_cnt = 0; - c->dlem.network.steer_summary.blacklist_failure_cnt = 0; - c->dlem.network.steer_summary.btm_attempt_cnt = 0; - c->dlem.network.steer_summary.btm_success_cnt = 0; - c->dlem.network.steer_summary.btm_failure_cnt = 0; - c->dlem.network.steer_summary.btm_query_resp_cnt = 0; + return false; +} - return UBUS_STATUS_OK; +static void topology_print_radio(struct controller *c, struct netif_radio *r, struct blob_buf *bb) +{ + char radio[256] = {}; + + /* Keep it short, user friendly */ + snprintf(radio, sizeof(radio), "%u/%u", + ctrl_radio_cur_opclass_ctrl_chan(r->radio_el), + ctrl_radio_cur_opclass_max_bw(r->radio_el)); + + switch(r->radio_el->band) { + case BAND_2: + blobmsg_add_string(bb, "2g", radio); + break; + case BAND_5: + blobmsg_add_string(bb, "5g", radio); + break; + case BAND_6: + blobmsg_add_string(bb, "6g", radio); + break; + default: + break; + } } -static struct wifi_radio_opclass * -cntlr_dbg_get_cur_opclass_by_bssid(struct controller *c, const unsigned char *bssid) +static void topology_print_node(struct controller *c, uint8_t *alid, struct blob_buf *bb) { - struct node *node = NULL; + struct netif_radio *r = NULL; + struct node *n; - list_for_each_entry(node, &c->nodelist, list) { - struct netif_radio *radio = NULL; + n = cntlr_find_node(c, alid); + if (!n) + return; - list_for_each_entry(radio, &node->radiolist, list) { - struct netif_iface *iface = NULL; + list_for_each_entry(r, &n->radiolist, list) + topology_print_radio(c, r, bb); +} - list_for_each_entry(iface, &radio->iflist, list) { - if (!iface->bss) - continue; - if (!iface->bss->enabled) - continue; - if (!iface->bss->is_bbss) - continue; - if (memcmp(iface->bss->bssid, bssid, 6)) - continue; +static void topology_add_hostname(struct bh_topology_dev *dev, struct blob_buf *bb) +{ + char buf[255] = {}; + char macaddr[18] = {}; - return &radio->radio_el->cur_opclass; - } - } - } + hwaddr_ntoa(dev->al_macaddr, macaddr); + if (dev->bh.depth == 0) + chrCmd(buf, sizeof(buf), "uci get system.@system[0].hostname"); + else + chrCmd(buf, sizeof(buf), "grep %s /tmp/dhcp.leases | awk '{print $4}'", &macaddr[3]); - return NULL; + if (strlen(buf)) + blobmsg_add_string(bb, "hostname", buf); } -static int cntlr_dbg_csr(struct ubus_context *ctx, - struct ubus_object *obj, - struct ubus_request_data *req, - const char *method, struct blob_attr *msg) +static void topology_print_dev(struct controller *c, struct bh_topology_dev *dev, + struct blob_buf *bb) { - struct controller *c = container_of(obj, struct controller, obj_dbg); - struct node *node = NULL; - - list_for_each_entry(node, &c->nodelist, list) { - struct netif_radio *r = NULL; - - list_for_each_entry(r, &node->radiolist, list) { - cntlr_send_channel_selection(c, node->almacaddr, r->radio_el->macaddr, 0, 0, 0); + void *t, *a; + int i, j; + + t = blobmsg_open_table(bb, ""); + blobmsg_add_macaddr(bb, "alid", dev->al_macaddr); + topology_add_hostname(dev, bb); + if (dev->bh.own_iface) + blobmsg_add_string(bb, "media", i1905_media_type_to_str(dev->bh.own_iface->media_type)); + topology_print_node(c, dev->al_macaddr, bb); + + if (topology_dev_any_leaf(c, dev)) { + a = blobmsg_open_array(bb, "leafs"); + for (i = 0; i < dev->number_of_interfaces; i++) { + if (dev->ifaces[i].number_of_neighbors == 0) + continue; + + for (j = 0; j < dev->ifaces[i].number_of_neighbors; j++) { + struct bh_topology_dev *subdev; + + subdev = topology_get_dev(c, dev->ifaces[i].neighbors_al_macs[j]); + if (subdev && subdev->bh.parent == dev) + topology_print_dev(c, subdev, bb); + } } + blobmsg_close_array(bb, a); } - - return UBUS_STATUS_OK; + blobmsg_close_table(bb, t); } -static int cntlr_dbg_bh_topology_dump(struct ubus_context *ctx, - struct ubus_object *obj, - struct ubus_request_data *req, - const char *method, struct blob_attr *msg) +static int cntlr_dbg_topology(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_dbg); - struct node *node = NULL; - struct blob_buf bb = { 0 }; - char macaddrstr[18] = { 0 }; + struct blob_buf bb = {}; + struct bh_topology_dev *dev = NULL; blob_buf_init(&bb, 0); - blobmsg_add_string(&bb, "topology_model_valid", is_bh_topology_valid() ? "Yes":"No"); - - if (is_bh_topology_valid()) { - void *devs_arr = blobmsg_open_array(&bb, "bh_topology_devs"); - - list_for_each_entry(node, &c->nodelist, list) { - const struct bh_topology_dev *topo_dev = topology_find_device(node->almacaddr); - if (topo_dev && - topo_dev->bh_info.level_in_tree != UNKNOWN_TREE_LEVEL) { - void *dev_table = blobmsg_open_table(&bb, ""); - const struct backhaul_info *bh_info = - &topo_dev->bh_info; - - blobmsg_add_string(&bb, "al_mac", - hwaddr_ntoa(topo_dev->al_macaddr, macaddrstr)); - blobmsg_add_u16(&bb, "hops_from_root", bh_info->level_in_tree); - blobmsg_add_u16(&bb, "wifi_hops_from_root", bh_info->wifi_hops_from_root); - - /* If device is not root device */ - if (bh_info->parent_in_tree) { - void *bh_table = blobmsg_open_table(&bb, "bh_info"); - struct wifi_radio_opclass *opclass; - - blobmsg_add_string(&bb, "parent_in_tree", - hwaddr_ntoa(bh_info->parent_in_tree->al_macaddr, macaddrstr)); - blobmsg_add_string(&bb, "link_type", - i1905_media_type_to_str(bh_info->parent_iface->media_type)); - blobmsg_add_string(&bb, "parent_iface", - hwaddr_ntoa(bh_info->parent_iface->macaddr, macaddrstr)); - - if (bh_info->own_iface) { - blobmsg_add_string(&bb, "own_iface", - hwaddr_ntoa(bh_info->own_iface->macaddr, macaddrstr)); - } - - if ((bh_info->parent_iface->media_type >> 8) == 1) { - opclass = cntlr_dbg_get_cur_opclass_by_bssid(c, bh_info->parent_iface->macaddr); - if (opclass) - cntlr_status_add_opclass(&bb, opclass, "cur_opclass", 0); - } - - blobmsg_close_table(&bb, bh_table); - } - - blobmsg_add_u32(&bb, "time_since_topo_response", - timestamp_elapsed_sec(&topo_dev->last_topo_response)); - - blobmsg_close_table(&bb, dev_table); - } + list_for_each_entry(dev, &c->topology.dev_list, list) { + if (dev->bh.depth == 0) { + topology_print_dev(c, dev, &bb); + break; } - blobmsg_close_array(&bb, devs_arr); } ubus_send_reply(ctx, req, bb.head); @@ -299,11 +178,7 @@ int cntlr_publish_dbg_object(struct controller *c, const char *objname) struct ubus_object_type *obj_type; struct ubus_method *obj_methods; struct ubus_method m[] = { - UBUS_METHOD_NOARG("list_macs", cntlr_dbg_list_macs), - UBUS_METHOD("clear_steer_summary", cntlr_dbg_clear_steer_summary, - clr_steer_summary_params), - UBUS_METHOD_NOARG("bh_topology_dump", cntlr_dbg_bh_topology_dump), - UBUS_METHOD_NOARG("csr", cntlr_dbg_csr), + UBUS_METHOD_NOARG("topology", cntlr_dbg_topology), }; int num_methods = ARRAY_SIZE(m); int ret;