diff --git a/src/cntlr.h b/src/cntlr.h index e7510ba4111def7370d07a2c9b073618dc5e9712..ce5b05970966dbff6beb0d3a1e87e531787837ec 100644 --- a/src/cntlr.h +++ b/src/cntlr.h @@ -30,6 +30,7 @@ #include "config.h" #include "steer.h" #include "allmac.h" +#include "backhaul_topology.h" #ifndef EASYMESH_VENDOR_EXT_OUI #define EASYMESH_VENDOR_EXT_OUI (uint8_t *)"\x00\x11\x22" @@ -307,6 +308,7 @@ struct controller { struct list_head stalist; /* list of sta */ struct list_head bcnreqlist; struct list_head linklist; + struct bh_topology_dev_list bh_topo_dev_list; #if (EASYMESH_VERSION > 2) struct dpp_context dpp_ctx; #endif diff --git a/src/cntlr_map.c b/src/cntlr_map.c index 07c26f88368fc567d874ebf2523f46afb72a83df..b592fb3deb0a668fb84683139bb0e6d4cd2fdb92 100644 --- a/src/cntlr_map.c +++ b/src/cntlr_map.c @@ -52,6 +52,7 @@ #include "utils/utils.h" #include "utils/debug.h" #include "utils/liblist.h" +#include "backhaul_topology.h" #include "config.h" #include "cntlr.h" #include "cntlr_ubus.h" @@ -301,9 +302,12 @@ static int topology_response_vext(struct controller *c, struct node *n, struct t int handle_topology_response(void *cntlr, struct cmdu_buff *cmdu, struct node *n) { + int tlv_index; + trace("%s: --->\n", __func__); struct controller *c = (struct controller *) cntlr; struct tlv *tv[12][16] = {0}; + struct bh_topology_dev *bh_topo_dev = NULL; cntlr_set_link_profile(c, n, cmdu); @@ -313,6 +317,120 @@ int handle_topology_response(void *cntlr, struct cmdu_buff *cmdu, struct node *n return -1; } + + /* Device Information Type TLV */ + if (tv[0][0]) { + const uint8_t *tlv_data = (uint8_t *)tv[0][0]->data; + const struct tlv_device_info *dev_info = + (struct tlv_device_info *)tlv_data; + int i = 0; + size_t offset = 0; + + dbg("%s: Device Info TLV from " MACFMT "\n", __func__, MAC2STR(cmdu->origin)); + + bh_topo_dev = + find_bh_topology_device(dev_info->aladdr, &c->bh_topo_dev_list); + + if (!bh_topo_dev) { + bh_topo_dev = + add_bh_topology_device(dev_info->aladdr, &c->bh_topo_dev_list); + + if (!bh_topo_dev) { + err("%s: Error in memory alloc\n", __func__); + return -1; + } + } + + /* Clear all interfaces data, including neighbor info */ + clear_bh_topology_device_info(bh_topo_dev); + + bh_topo_dev->number_of_interfaces = dev_info->num_interface; + offset += sizeof(dev_info->aladdr) + sizeof(dev_info->num_interface); + + dbg("%s: dev_info->num_interface %d\n", __func__, dev_info->num_interface); + + for (i = 0; i < dev_info->num_interface; ++i) { + struct local_interface *interface = + (struct local_interface *)(tlv_data + offset); + + memcpy(bh_topo_dev->ifaces[i].macaddr, interface->macaddr, 6); + bh_topo_dev->ifaces[i].media_type = + BUF_GET_BE16(interface->mediatype); + + offset += sizeof(struct local_interface) + + interface->sizeof_mediainfo; + + if (i == IFACE_MAX_NUM - 1) { + err("%s: Currently max %d interfaces supported!\n", + __func__, IFACE_MAX_NUM); + + break; + } + } + } + + + /* 1905.1 neighbor device TLVs */ + tlv_index = 0; + while (tv[3][tlv_index] && (tlv_index < 16)) { + const uint8_t *tlv_data = (uint8_t *)tv[3][tlv_index]->data; + const uint16_t tlv_len = tlv_length(tv[3][tlv_index]); + const struct tlv_1905neighbor *tlv_1905neighbor = + (struct tlv_1905neighbor *) tlv_data; + struct local_iface *local_iface = NULL; + const uint8_t neighbors_num = + (tlv_len - sizeof(tlv_1905neighbor->local_macaddr)) / + sizeof(struct i1905_neighbor); + int i; + + ++tlv_index; + + if (!bh_topo_dev) { + err("%s: 1905 dev.info is missing. Logical error in\n", __func__); + break; + } + + /* Each TLV represents neighbors from given local interface */ + if (tlv_index == IFACE_MAX_NUM) { + err("%s: Currently max %d interfaces supported!\n", __func__, IFACE_MAX_NUM); + break; + } + + for (i = 0; i < bh_topo_dev->number_of_interfaces; ++i) { + /* + * Because different local physical interfaces can use the same MAC address, + * find a one with matching MAC and no neighbors added yet. + */ + if (hwaddr_equal(bh_topo_dev->ifaces[i].macaddr, + tlv_1905neighbor->local_macaddr) && + bh_topo_dev->ifaces[i].number_of_neighbors == 0) { + + local_iface = &bh_topo_dev->ifaces[i]; + break; + } + } + + if (local_iface) { + dbg("%s: adding neighbors for local_iface[%d], macaddr: " MACFMT "\n", + __func__, i, MAC2STR(local_iface->macaddr)); + + local_iface->number_of_neighbors = neighbors_num; + + for (i = 0; i < neighbors_num && i < NEIGHBORS_MAX_NUM; ++i) { + dbg("%s: neighbor[%d].aladdr:" MACFMT "\n", + __func__, i, MAC2STR(tlv_1905neighbor->nbr[i].aladdr)); + + memcpy(&local_iface->neighbors_al_macs[i][0], + tlv_1905neighbor->nbr[i].aladdr, 6); + } + + } else { + err("%s: No iface found, adding neighbors failed for local_macaddr: " MACFMT "\n", + __func__, MAC2STR(tlv_1905neighbor->local_macaddr)); + } + } + + if (tv[7][0]) { struct tlv_ap_oper_bss *tlv; uint8_t *tv_data;