diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 95b0a116a7bdc85e8dd5864706dc8ea0b79a2063..dbbf6b72ff8da59423d334c0d769981982ff1280 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,11 +5,12 @@ include: stages: - static_code_analysis - functional_test - - functional_api_test + - functional_api_test variables: DEBUG: 'TRUE' SOURCE_FOLDER: "src" + RUN_CPPCHECK: "cppcheck --enable=all --error-exitcode=1 --suppress=unusedFunction --suppress=unreadVariable --suppress=variableScope --suppress=syntaxError ." run_functional_test: stage: functional_test diff --git a/src/cmdu_ackq.c b/src/cmdu_ackq.c index 87be96d84f7a6a2d10c512b705f492d099f4a73f..1284f4775b6543e87b21f529e6769dd601da644b 100644 --- a/src/cmdu_ackq.c +++ b/src/cmdu_ackq.c @@ -16,10 +16,13 @@ #include <libubus.h> #include <libubox/utils.h> #include <easy/easy.h> + #include "timer.h" #include "cmdu_ackq.h" +#include "host_config.h" #include "topologyd.h" + static int timeradd_msecs(struct timeval *a, unsigned long msecs, struct timeval *res) { diff --git a/src/config.c b/src/config.c index 3eb60d9d8248a485b0aeb62491eb9b03043089c3..675fb59ac7d7f5d60a861778c4ea03332ff3f43f 100644 --- a/src/config.c +++ b/src/config.c @@ -27,6 +27,7 @@ #include <uci.h> #include "debug.h" +#include "host_config.h" #include "topologyd.h" #include "config.h" diff --git a/src/host.c b/src/host.c index b9c93be30e25d19e27d69b0ff9eee4b5badbc97a..9528087e550375b42775921e8407c6a398394d7d 100644 --- a/src/host.c +++ b/src/host.c @@ -9,27 +9,32 @@ #include <stdbool.h> #include <pthread.h> -#include <json-c/json.h> -#include <libubox/blobmsg.h> - -#include <libubox/blobmsg_json.h> -#include <libubox/uloop.h> -#include <libubus.h> #include <dirent.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <netinet/in.h> #include <net/if.h> + +#include <json-c/json.h> +#include <libubox/blobmsg.h> +#include <libubox/blobmsg_json.h> +#include <libubox/uloop.h> +#include <libubus.h> #include <uci.h> #include <easy/easy.h> -#include "host.h" -#include "host_config.h" + #include "debug.h" +#include "host_config.h" +#include "topologyd.h" +#include "host_nodes.h" #include "config.h" #include "json_utils.h" #include "host_utils.h" +#include "host.h" + + extern const char *ubus_socket; @@ -89,7 +94,7 @@ static void uobjx_lookup(struct ubus_context *ctx, struct ubus_object_data *obj, p = strstr(obj->path, token); if (p != NULL) { - strcpy(str->ifname[str->count], obj->path); + strncpy(str->ifname[str->count], obj->path, 16); str->count = str->count + 1; } } @@ -135,7 +140,6 @@ void host_dump_node_nbr(struct topologyd_private *priv, struct blob_buf *b) char mac_str[18] = { 0x0 }; void *nodes_array; struct host_node *p; - int i; void *table1 = NULL; struct tm *info; time_t tmp_t; @@ -255,7 +259,9 @@ struct host_node *host_check_get_node(struct topologyd_private *priv, uint8_t *m } -struct host_node *host_topo_node_add(struct topologyd_private *priv, struct node *node, uint8_t *mac_addr, uint8_t is_wifi) +struct host_node *host_topo_node_add(struct topologyd_private *priv, + struct node *node, uint8_t *mac_addr, + uint8_t is_wifi) { struct host_node *p = NULL; char mac_str[18] = { 0 }; @@ -278,9 +284,9 @@ struct host_node *host_topo_node_add(struct topologyd_private *priv, struct node return NULL; p->is_ieee1905_node = 1; - // TODO review the if case - if (p->intf_type != HOST_TYPE_WIFI || (p->intf_type == HOST_TYPE_WIFI && is_wifi)) + if (p->intf_type != HOST_TYPE_WIFI || is_wifi) host_change_active_state(priv, p, 1); + host_get_wifi_data(priv, p); } else if (mac_addr != NULL) { @@ -291,7 +297,7 @@ struct host_node *host_topo_node_add(struct topologyd_private *priv, struct node p->is_ieee1905_node = 0; if (p->active != 1) { dbg("%s %d ||||||||| setting node %s to active\n", __func__, __LINE__, mac_str); - if (p->intf_type != HOST_TYPE_WIFI || (p->intf_type == HOST_TYPE_WIFI && is_wifi)) + if (p->intf_type != HOST_TYPE_WIFI || is_wifi) host_change_active_state(priv, p, 1); } @@ -300,14 +306,20 @@ struct host_node *host_topo_node_add(struct topologyd_private *priv, struct node if (ret != 0) err("Unable to fetch interface type\n"); } else { - config_set_host_option("hosts", "host", "macaddr", mac_str, "interface_type", "wifi", priv->host_global_cfg.persistent); + config_set_host_option("hosts", "host", "macaddr", + mac_str, "interface_type", + "wifi", + priv->host_global_cfg.persistent); p->intf_type = HOST_TYPE_WIFI; } - config_set_host_option("hosts", "host", "macaddr", mac_str, "interface_type", - (p->intf_type == HOST_TYPE_WIFI ? "wifi" : "eth"), priv->host_global_cfg.persistent); + config_set_host_option("hosts", "host", "macaddr", mac_str, + "interface_type", + (p->intf_type == HOST_TYPE_WIFI ? "wifi" : "eth"), + priv->host_global_cfg.persistent); } - bool has_ip = p->is_ipaddr; + + //bool has_ip = p->is_ipaddr; ret = host_get_ipaddr_hostname(priv, mac_str, p); if (ret != 0) { @@ -322,12 +334,14 @@ struct host_node *host_topo_node_add(struct topologyd_private *priv, struct node if (p && p->al_node) - host_topo_node_add(priv, p->al_node, NULL, is_wifi); + host_topo_node_add(priv, NULL, p->al_node->hwaddr, is_wifi); return p; } -struct host_node *host_topo_node_del(struct topologyd_private *priv, struct node *node, uint8_t *mac_addr, uint8_t is_wifi) +struct host_node *host_topo_node_del(struct topologyd_private *priv, + struct node *node, uint8_t *mac_addr, + uint8_t is_wifi) { struct host_node *p = NULL; char mac_str[18] = { 0 }; @@ -370,12 +384,15 @@ struct host_node *host_topo_node_del(struct topologyd_private *priv, struct node } } if (p && is_wifi) { - config_set_host_option("hosts", "host", "macaddr", mac_str, "interface_type", "wifi", priv->host_global_cfg.persistent); + config_set_host_option("hosts", "host", "macaddr", mac_str, + "interface_type", + "wifi", + priv->host_global_cfg.persistent); p->intf_type = HOST_TYPE_WIFI; } if (p && p->al_node) - host_topo_node_del(priv, p->al_node, NULL, is_wifi); + host_topo_node_del(priv, NULL, p->al_node->hwaddr, is_wifi); if (p) { p->is_event = 0; @@ -406,7 +423,7 @@ int host_append_dhcpv4_info(char *mac_addr, struct host_node *p) if (leases != NULL) { while (fgets(line, sizeof(line), leases) != NULL) { remove_newline(line); - if (sscanf(line, "%ld %24s %24s %64s %256s", &leasetime, macaddr, ipaddr, hostname, clid) == 5) { + if (sscanf(line, "%ld %23s %23s %63s %255s", &leasetime, macaddr, ipaddr, hostname, clid) == 5) { dbg("%s %d ipv4addr = [%s]\n", __func__, __LINE__, ipaddr); if (strcasecmp(mac_addr, macaddr) == 0) { if (found == 0) { @@ -450,7 +467,7 @@ void host_append_dhcpv6_info(struct host_node *p) while (fgets(line, sizeof(line), hosts6) != NULL) { remove_newline(line); - if (sscanf(line, "%64s %128s", ip6addr, hostname)) { + if (sscanf(line, "%127s %63s", ip6addr, hostname)) { if (strcasecmp(p->hostname, hostname) == 0) { dbg("ipv6 address %s %d\n", __func__, __LINE__); strncpy(p->ipv6addr[p->ipv6addr_count], ip6addr, 128); @@ -540,7 +557,7 @@ void host_get_network(struct topologyd_private *priv, struct host_node *p) for (j = 0; j < ipv4_len; j++) { struct in_addr ip, snet, host, rslt; struct json_object *jobj_ptr, *iface; - char *ipaddr; + const char *ipaddr; int netmask; uint32_t mask = 0; @@ -680,7 +697,7 @@ static void get_ethernet_interface(struct host_node *host, char *bridge, int por struct dirent *ent; FILE *pfile; char path_brif[256]; - char path_portno[512]; + char path_portno[1024]; unsigned int pno = 0; dbg("Inside %s %d\n", __func__, __LINE__); @@ -697,7 +714,7 @@ static void get_ethernet_interface(struct host_node *host, char *bridge, int por if (ent->d_name[0] == '.') continue; - snprintf(path_portno, 512, "/%s/%s/port_no", path_brif, ent->d_name); + snprintf(path_portno, 1024, "/%s/%s/port_no", path_brif, ent->d_name); pfile = fopen(path_portno, "r"); if (pfile != NULL) { @@ -800,7 +817,8 @@ int host_get_ipaddr_hostname(struct topologyd_private *priv, host_get_network(priv, p); get_bridge_info(p, device); - if (p->intf_type == HOST_TYPE_WIFI && p->is_ieee1905_node || (p->intf_type == HOST_TYPE_WIFI && !p->is_in_assoclist)) { + if ((p->intf_type == HOST_TYPE_WIFI && p->is_ieee1905_node) || + (p->intf_type == HOST_TYPE_WIFI && !p->is_in_assoclist)) { strncpy(p->device, device, 16); get_ethernet_interface(p, device, p->port_no); if (p->is_device_mac == 1) { @@ -854,7 +872,7 @@ bool host_is_in_assoclist(struct topologyd_private *priv, uint8_t *hwaddr) len = json_object_array_length(sta_array); for (i = 0; i < len; i++) { - struct json_object *sta_obj, *sta_obj_macaddr, *jobj_ptr, *stat_obj; + struct json_object *sta_obj, *sta_obj_macaddr; unsigned char macaddr[6] = {0}; sta_obj = json_object_array_get_idx(sta_array, i); @@ -1171,9 +1189,11 @@ int host_get_neigh_status(uint8_t *mac_addr) return -1; hwaddr_ntoa(mac_addr, macaddr_str); - snprintf(cmd, 256, NEIGH_CMD, macaddr_str); + snprintf(cmd, 256, + "ip neigh show nud reachable|awk '{print $5}'|grep %s", + macaddr_str); - fp = popen(cmd, "r"); + fp = popen(cmd, "r"); /* flawfinder: ignore */ if (fp == NULL) { err("unable to execute command"); return -1; @@ -1502,10 +1522,11 @@ int topology_update_client_assoc_event(struct topologyd_private *priv, struct tl } int topology_update_host_assoc_client(struct topologyd_private *priv, - struct tlv_assoc_client *tlv) + struct tlv_assoc_client *tlv) { struct host_node *hn = NULL; int i, offset = 0; + uint8_t *pos = (uint8_t *) tlv; if (tlv == NULL || priv == NULL) return -1; @@ -1519,10 +1540,10 @@ int topology_update_host_assoc_client(struct topologyd_private *priv, int j; dbg("\t\tbssid: " MACFMT "\n", - MAC2STR(&tlv[offset])); + MAC2STR(&pos[offset])); offset += 6; - num_client = BUF_GET_BE16(tlv[offset]); + num_client = BUF_GET_BE16(pos[offset]); offset += 2; dbg("\t\tassoc_clients_nr: %u\n", num_client); @@ -1531,25 +1552,25 @@ int topology_update_host_assoc_client(struct topologyd_private *priv, uint8_t client_addr[6]; dbg("\t\t\tclient_addr is: " MACFMT "\n", - MAC2STR(&tlv[offset])); - memcpy(client_addr, &tlv[offset], 6); + MAC2STR(&pos[offset])); + memcpy(client_addr, &pos[offset], 6); //Here look at the host node of this assoc client and update the time - hn = host_node_lookup(priv->host.node_htable, &tlv[offset]); + hn = host_node_lookup(priv->host.node_htable, &pos[offset]); if (!hn) { - hn = host_topo_node_add(priv, NULL, &tlv[offset], 1); + hn = host_topo_node_add(priv, NULL, &pos[offset], 1); if (hn->is_ipaddr) host_send_client_event(priv, hn, 1); } else { if (hn->active == 0) { - hn = host_topo_node_add(priv, NULL, &tlv[offset], 1); + hn = host_topo_node_add(priv, NULL, &pos[offset], 1); if (hn->is_ipaddr) host_send_client_event(priv, hn, 1); } } hn->age_time = time(NULL); offset += 6; - conntime = BUF_GET_BE16(tlv[offset]); + conntime = BUF_GET_BE16(pos[offset]); offset += 2; dbg("\t\t\tuptime: 0x%04x\n", conntime); } @@ -1658,6 +1679,7 @@ void host_send_topology_query_all(struct topologyd_private *priv) } } +#if 0 static void host_mid_response_cb(struct ubus_request *req, int mtype, struct blob_attr *msg) { @@ -1683,6 +1705,7 @@ static void host_mid_response_cb(struct ubus_request *req, return; } +#endif struct cmdu_buff *host_topology_query_map_tlv(void) { @@ -1738,27 +1761,6 @@ int host_send_mid_topology_query(struct topologyd_private *p, uint8_t *dst_mac) return 0; } -void host_event_handler(struct ubus_context *ctx, - struct ubus_event_handler *ev, const char *type, - struct blob_attr *msg) -{ - char *str; - - struct topologyd_private *priv = - container_of(ev, struct topologyd_private, wifi_evh); - - if (!msg) - return; - - str = blobmsg_format_json(msg, true); - if (!str) - return; - - info("[ &Host = %p ] Received [event = %s] [val = %s]\n", - priv, type, str); - host_wifi_sta_event_handler(priv, msg); - free(str); -} void host_wifi_sta_event_handler(void *c, struct blob_attr *msg) { @@ -1824,25 +1826,50 @@ void host_wifi_sta_event_handler(void *c, struct blob_attr *msg) } } +void host_event_handler(struct ubus_context *ctx, + struct ubus_event_handler *ev, const char *type, + struct blob_attr *msg) +{ + char *str; + + struct topologyd_private *priv = + container_of(ev, struct topologyd_private, wifi_evh); + + if (!msg) + return; + + str = blobmsg_format_json(msg, true); + if (!str) + return; + + info("[ &Host = %p ] Received [event = %s] [val = %s]\n", + priv, type, str); + host_wifi_sta_event_handler(priv, msg); + free(str); +} + bool is_local_mapagent_available(void) { bool enable = false; + struct stat sb; int ret = 0; - dbg("Inside %s access %d\n", __func__, access("/etc/config/mapagent", F_OK|R_OK)); - if (!access("/etc/config/mapagent", F_OK|R_OK)) { - ret = host_config_mapagent_get(&enable); - if (ret == 0) { - if (enable == true) - return true; - } + dbg("Inside %s ===>\n", __func__); + ret = stat("/etc/config/mapagent", &sb); + if (ret) + return false; + + ret = host_config_mapagent_get(&enable); + if (ret == 0) { + if (enable == true) + return true; } return false; } bool host_create_file(void) { - if (!access("/var/state/hosts", F_OK|R_OK)) + if (!access("/var/state/hosts", F_OK|R_OK)) /* flawfinder: ignore */ return true; else { FILE *fptr = NULL; diff --git a/src/host.h b/src/host.h index 0611b051360cf04c0bbe5ca12879910d6e175267..71b27b00cd96fad17559af1e401fadca6e7330db 100644 --- a/src/host.h +++ b/src/host.h @@ -154,4 +154,18 @@ int topology_update_client_assoc_event(struct topologyd_private *priv, struct tl int topology_update_host_assoc_client(struct topologyd_private *priv, struct tlv_assoc_client *p); bool host_is_in_assoclist(struct topologyd_private *priv, uint8_t *hwaddr); +void host_change_active_state(struct topologyd_private *priv, struct host_node *p, uint8_t state); + +int host_copy_node_data(struct host_node *src_host, struct host_node *dest_host, + struct topologyd_private *priv); + +void host_send_client_event(struct topologyd_private *priv, struct host_node *p, uint8_t state); + + +bool host_create_file(void); +bool is_local_mapagent_available(void); + +int host_get_wifi_data(struct topologyd_private *priv, struct host_node *p); +void host_send_topology_query_all(struct topologyd_private *priv); + #endif /* HOSTD_H */ diff --git a/src/host_config.c b/src/host_config.c index 36a4046e3303d003f16a0acc6f86f217fb7d788b..0726b75e7efaf7373558b0bb85c10989a92d657f 100644 --- a/src/host_config.c +++ b/src/host_config.c @@ -28,8 +28,9 @@ #include <uci.h> #include "debug.h" -#include "host.h" #include "host_config.h" +#include "topologyd.h" +#include "host.h" struct uci_section *config_get_section(struct uci_context *ctx, struct uci_package *pkg, const char *type, const char *key, @@ -64,9 +65,6 @@ int config_del_section(const char *config, const char *type, const char *value, struct uci_section *section; struct uci_ptr ptr = {0}; int rv = -1; - static const char s[2] = ":"; - char *token; - char mac_name[18] = { 0 }; dbg("Inside %s %d the value is %s\n", __func__, __LINE__, value); @@ -109,20 +107,20 @@ struct uci_section *config_add_section(struct uci_context *ctx, struct uci_ptr ptr = {0}; int rv = -1; char name_section[50] = { 0 }; - - dbg("Inside %s %d\n", __func__, __LINE__); - static const char s[2] = ":"; char *token; char mac_name[18] = { 0 }; - strcpy(mac_name, value); + + dbg("Inside %s %d\n", __func__, __LINE__); + strncpy(mac_name, value, 18); /* get the first token */ token = strtok(mac_name, s); /* walk through other tokens */ while (token != NULL) { - strcat(name_section, token); + snprintf(name_section + strlen(name_section), + sizeof(name_section), "%s", token); token = strtok(NULL, s); } diff --git a/src/host_config.h b/src/host_config.h index a6b728c5c587fbbc7cbacabdf425c567b056ae49..09b514f27b37ec61fa6b1c533eef7035b72b79d8 100644 --- a/src/host_config.h +++ b/src/host_config.h @@ -31,4 +31,8 @@ int config_add_default_host_mac(const char *config, const char *type, bool config_set_host_option(char *package_name, char *section_type, char *search_key, char *search_val, char *option, char *value, bool persistent); + + +bool config_get_al_ifname(char *ifname); + #endif /* HOSTD_CONFIG_H */ diff --git a/src/host_nodes.c b/src/host_nodes.c index fe2ace8b7c05e72cd096f7b7b6ed411af786765d..5d2156dfea223cca7e21965a8bfbc2a99e2963da 100644 --- a/src/host_nodes.c +++ b/src/host_nodes.c @@ -13,10 +13,14 @@ #include <libubox/list.h> #include <libubox/uloop.h> #include <libubus.h> +#include <uci.h> #include <easy/easy.h> + #include "debug.h" +#include "host_config.h" #include "topologyd.h" +#include "host.h" #include "mdns_avahi.h" diff --git a/src/host_nodes.h b/src/host_nodes.h index 0c11a5177ee4bca4b8f02362604a247357e194ae..44e3cdb695465dc82ef2e79420aadd7935a7c2a7 100644 --- a/src/host_nodes.h +++ b/src/host_nodes.h @@ -1,10 +1,7 @@ - -#ifndef NODES_H -#define NODES_H +#ifndef HOST_NODES_H +#define HOST_NODES_H #include <stdint.h> -#include <easy/easy.h> - struct host_node *host_node_create(uint8_t *hwaddr); void host_node_free(struct host_node *n); @@ -13,4 +10,4 @@ int host_node_del(struct hlist_head *table, uint8_t *hwaddr); struct host_node *host_node_lookup(struct hlist_head *table, uint8_t *hwaddr); void host_node_print_all(struct hlist_head *table); -#endif /* NODES_H */ +#endif /* HOST_NODES_H */ diff --git a/src/host_utils.c b/src/host_utils.c index 172fac9c19c3f0120eb0950814bbad7f62b25ea9..8fd19d8ba131152a82e9bc0ebc3d9663e292349d 100644 --- a/src/host_utils.c +++ b/src/host_utils.c @@ -18,12 +18,55 @@ * along with this program; If not, see <http://www.gnu.org/licenses/>. */ +#ifndef _GNU_SOURCE #define _GNU_SOURCE -#include "host_utils.h" - +#endif + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <net/if.h> +#include <sys/ioctl.h> +#include <netpacket/packet.h> +#include <net/ethernet.h> +#include <net/if_arp.h> +#include <netinet/ether.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <string.h> +#include <stdbool.h> +#include <unistd.h> +#include <fcntl.h> +#include <libubus.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> +#include <netlink/netlink.h> +#include <netlink/utils.h> + +#include <netlink/route/rtnl.h> +#include <netlink/route/neighbour.h> +#include <netlink/route/addr.h> +#include <netlink/route/link.h> +#include <netlink/genl/ctrl.h> +#include <netlink/genl/genl.h> +#include <netlink/attr.h> + +#include <uci.h> +#include <easy/easy.h> + +#include "debug.h" +#include "host_config.h" +#include "topologyd.h" +#include "host.h" +#include "host_utils.h" + +#ifndef TLV_TYPE_END_OF_MESSAGE +#define TLV_TYPE_END_OF_MESSAGE 0x00 +#endif struct in_addr src; struct in_addr dst; @@ -38,8 +81,8 @@ struct nl_req_s { struct rtgenmsg gen; }; -static int -send_pack(struct in_addr *src_addr, struct in_addr *dst_addr, struct sockaddr_ll *ME, struct sockaddr_ll *HE) +static int send_pack(struct in_addr *src_addr, struct in_addr *dst_addr, + struct sockaddr_ll *ME, struct sockaddr_ll *HE) { int err; unsigned char buf[256]; @@ -62,8 +105,7 @@ send_pack(struct in_addr *src_addr, struct in_addr *dst_addr, struct sockaddr_ll return err; } -static bool -recv_pack(char *buf, int len, struct sockaddr_ll *FROM) +static bool recv_pack(char *buf, int len, struct sockaddr_ll *FROM) { struct arphdr *ah = (struct arphdr *) buf; unsigned char *p = (unsigned char *) (ah + 1); @@ -104,8 +146,7 @@ recv_pack(char *buf, int len, struct sockaddr_ll *FROM) } -bool -host_send_arping(const char *targetIP, const char *device, int toms, int is_recv) +bool host_send_arping(const char *targetIP, const char *device, int toms, int is_recv) { struct sockaddr_in saddr; struct ifreq ifr; @@ -280,7 +321,9 @@ int host_get_netlink_ip(uint8_t *mac_addr, char *ipv4_str, char *device) nl_socket_free(sk); return -1; } - dbg("intfname = [%s] ipv4addr= [%s] mac=["MACFMT"]\n", device, ipv4_str, MAC2STR(hwaddr)); + dbg("intfname = [%s] ipv4addr= [%s] mac=["MACFMT"]\n", + device, ipv4_str, MAC2STR(hwaddr)); + nl_object_put((struct nl_object *) neigh); break; } @@ -301,11 +344,10 @@ int host_get_netlink_ip6(uint8_t *mac_addr, struct host_node *p) struct rtnl_neigh *neigh; struct nl_object *nobj; struct nl_cache *cache; - uint32_t ifindex = 0; + //uint32_t ifindex = 0; struct nl_sock *sk; int i, num; int ret; - char *ifname = NULL; dbg("Inside %s %d\n", __func__, __LINE__); sk = nl_socket_alloc(); @@ -339,7 +381,7 @@ int host_get_netlink_ip6(uint8_t *mac_addr, struct host_node *p) nl_object_get((struct nl_object *) neigh); - ifindex = rtnl_neigh_get_ifindex(neigh); + //ifindex = rtnl_neigh_get_ifindex(neigh); lladdr = rtnl_neigh_get_lladdr(neigh); if (lladdr) memcpy(hwaddr, nl_addr_get_binary_addr(lladdr), diff --git a/src/host_utils.h b/src/host_utils.h index 8af8b9be2124c6e5a2975397647abf583edc698a..3aa8504ffaa32a88083493cee160ed2f1ba375ce 100644 --- a/src/host_utils.h +++ b/src/host_utils.h @@ -1,29 +1,9 @@ #ifndef HOST_UTILS_H #define HOST_UTILS_H -#include <sys/socket.h> -#include <sys/types.h> -#include <net/if.h> -#include <sys/ioctl.h> -#include <netpacket/packet.h> -#include <net/ethernet.h> -#include <net/if_arp.h> -#include <netinet/ether.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include <stdbool.h> -#include <unistd.h> -#include "debug.h" -#include <fcntl.h> -#include <libubus.h> -#include <easy/easy.h> -#include <linux/rtnetlink.h> -#include "host.h" #define NLMSG_NEIGH 28 #define IFLIST_REPLY_BUFFER 8192 -#define TLV_TYPE_END_OF_MESSAGE 0x00 bool host_send_arping(const char *targetIP, const char *device, int toms, int is_recv); int host_get_neigh(struct nlmsghdr *nlh, char *dev, char *dest_addr, uint8_t *mac_addr); diff --git a/src/json_utils.c b/src/json_utils.c index f7e2436eb8fa1e343022f8e9361296baa79438c2..c6fe8bedb3934e5333251fc4940b6dc107c8f1dd 100644 --- a/src/json_utils.c +++ b/src/json_utils.c @@ -37,8 +37,6 @@ int _json_obj_get_int(json_object *j, const char *key) void json_safe_put(json_object *j) { - if (j != NULL) { + if (j != NULL) json_object_put(j); - j = NULL; - } } diff --git a/src/mdns_avahi.c b/src/mdns_avahi.c index d51a39bb0333a390952c7464461275f3a9848b40..18b883c99465537bf8ab5f6f6073f1b0c048620c 100644 --- a/src/mdns_avahi.c +++ b/src/mdns_avahi.c @@ -24,12 +24,14 @@ #include <libubox/uloop.h> #include <libubus.h> +#include <uci.h> #include <easy/easy.h> #include <time.h> #include "debug.h" #include "nodes.h" +#include "host_config.h" #include "topologyd.h" #include "mdns_avahi.h" @@ -54,8 +56,6 @@ void parse_record(AvahiSRecordBrowser *rr, AvahiRecord *record, AvahiLookupResultFlags flags); -static AvahiSimplePoll *simple_poll; - //TODO: implement log function properly void avahi_log_override(AvahiLogLevel level, const char *txt) { @@ -394,7 +394,7 @@ static void browse_service_type(struct topologyd_private *topo, if (!b) { fprintf(stderr, "avahi_service_browser_new() failed: %s\n", avahi_strerror(avahi_server_errno(server))); - avahi_simple_poll_quit(simple_poll); + avahi_simple_poll_quit(topo->simple_poll); } } @@ -509,12 +509,10 @@ static void server_callback(AvahiServer *server, AvahiServerState state, void mdns_cleanup_poll(struct topologyd_private *topo) { - AvahiSimplePoll *simple_poll = (AvahiSimplePoll *) topo->simple_poll; + AvahiSimplePoll *spoll = (AvahiSimplePoll *) topo->simple_poll; - if (simple_poll) { - avahi_simple_poll_free(simple_poll); - simple_poll = NULL; - } + if (spoll) + avahi_simple_poll_free(spoll); } void mdns_cleanup(struct topologyd_private *topo) @@ -556,7 +554,6 @@ int mdns_init(struct topologyd_private *priv) { AvahiServer *server; AvahiServerConfig config; - AvahiSimplePoll *simple_poll; int error; /* Initialize the pseudo-RNG */ @@ -565,8 +562,8 @@ int mdns_init(struct topologyd_private *priv) avahi_set_log_function(avahi_log_override); /* Allocate main loop object */ - priv->simple_poll = simple_poll = avahi_simple_poll_new(); - if (!simple_poll) { + priv->simple_poll = avahi_simple_poll_new(); + if (!priv->simple_poll) { fprintf(stderr, "Failed to create simple poll object.\n"); return -1; } @@ -580,8 +577,9 @@ int mdns_init(struct topologyd_private *priv) config.enable_wide_area = 0; /* Allocate a new server */ - priv->avahi_serv = server = avahi_server_new(avahi_simple_poll_get(simple_poll), &config, - server_callback, priv, &error); + priv->avahi_serv = server = avahi_server_new(avahi_simple_poll_get(priv->simple_poll), + &config, server_callback, + priv, &error); /* Free the configuration data */ avahi_server_config_free(&config); diff --git a/src/nodes.c b/src/nodes.c index ece763611ea5acb4f731ce8f9d2fb52705efc81e..70ec6f9c13106025ab97cc768e9cede5f140ee3c 100644 --- a/src/nodes.c +++ b/src/nodes.c @@ -13,9 +13,12 @@ #include <libubox/list.h> #include <libubox/uloop.h> #include <libubus.h> +#include <uci.h> #include <easy/easy.h> + #include "debug.h" +#include "host_config.h" #include "topologyd.h" #include "mdns_avahi.h" diff --git a/src/topo_ieee1905.c b/src/topo_ieee1905.c index c6a59b22c9f2b3d4c6c946ddb38c748b9caf0884..887e78678b1a43349fe642c424c9e15d6e2ae08b 100644 --- a/src/topo_ieee1905.c +++ b/src/topo_ieee1905.c @@ -19,12 +19,15 @@ #include <libubox/blobmsg.h> #include <libubox/blobmsg_json.h> #include <libubox/uloop.h> +#include <uci.h> #include <easy/easy.h> #include "debug.h" +#include "host_config.h" #include "topologyd.h" +#include "host.h" #include "mdns_avahi.h" #include "nodes.h" @@ -74,7 +77,7 @@ static int topologyd_copy_update_node(struct node *dest, struct node *src) dest->node_intf[j].role = src->node_intf[j].role; dest->node_intf[j].ap_channel_band = src->node_intf[j].ap_channel_band; dest->node_intf[j].freq_index1 = src->node_intf[j].freq_index1; - dest->node_intf[j].freq_index2 = dest->node_intf[j].freq_index2; + dest->node_intf[j].freq_index2 = src->node_intf[j].freq_index2; } } @@ -307,34 +310,6 @@ void topologyd_algo_run(struct topologyd_private *priv) dbg("\n====== Done Building Topology======\n"); } -void uobj_add_event_handler(struct ubus_context *ctx, - struct ubus_event_handler *ev, - const char *type, - struct blob_attr *msg) -{ - - char path[32] = {0}; - struct topologyd_private *priv = container_of(ev, struct topologyd_private, obj_register); - struct blob_attr *tb[2]; - static const struct blobmsg_policy ev_attr[2] = { - [0] = { .name = "id", .type = BLOBMSG_TYPE_INT32 }, - [1] = { .name = "path", .type = BLOBMSG_TYPE_STRING } - }; - //dbg("msg - %s\n", blobmsg_format_json_indent(msg, true, -1)); - blobmsg_parse(ev_attr, 2, tb, blob_data(msg), blob_len(msg)); - - if (!tb[0] || !tb[1]) { - dbg("%d %d\n", !tb[0], !tb[1]); - return; - } - strncpy(path, blobmsg_data(tb[1]), sizeof(path) - 1); - if (strncmp(path, map_plugin, strlen(map_plugin))) - return; - /* TODO: how to handle failure? */ - topology_subscribe_for_cmdus(priv); -} - - static void topology_sub_remove_cb(struct ubus_context *ctx, struct ubus_subscriber *sub, uint32_t obj) @@ -418,11 +393,6 @@ static void register_cb(struct ubus_request *req, int type, struct blob_attr *ms } } -#ifndef BITx -#define BITx(n) (1U << (n)) -#endif - - void topology_subscribe_for_cmdus(struct topologyd_private *p) { char data[2 * sizeof(struct map_module) + 1] = {0}; @@ -476,3 +446,29 @@ void topology_subscribe_for_cmdus(struct topologyd_private *p) return; } +void uobj_add_event_handler(struct ubus_context *ctx, + struct ubus_event_handler *ev, + const char *type, struct blob_attr *msg) +{ + + char path[32] = {0}; + struct topologyd_private *priv = container_of(ev, struct topologyd_private, obj_register); + struct blob_attr *tb[2]; + static const struct blobmsg_policy ev_attr[2] = { + [0] = { .name = "id", .type = BLOBMSG_TYPE_INT32 }, + [1] = { .name = "path", .type = BLOBMSG_TYPE_STRING } + }; + //dbg("msg - %s\n", blobmsg_format_json_indent(msg, true, -1)); + blobmsg_parse(ev_attr, 2, tb, blob_data(msg), blob_len(msg)); + + if (!tb[0] || !tb[1]) { + dbg("%d %d\n", !tb[0], !tb[1]); + return; + } + strncpy(path, blobmsg_data(tb[1]), sizeof(path) - 1); + if (strncmp(path, map_plugin, strlen(map_plugin))) + return; + /* TODO: how to handle failure? */ + topology_subscribe_for_cmdus(priv); +} + diff --git a/src/topo_ieee1905.h b/src/topo_ieee1905.h index c924214f9646248fecce801745481469357fb5dd..fae29399ee16083c9f836e478189886e24780c92 100644 --- a/src/topo_ieee1905.h +++ b/src/topo_ieee1905.h @@ -1,5 +1,5 @@ /* - * config.h - configuration header file + * topo_ieee1905.h - configuration header file * * Copyright (C) 2020 IOPSYS Software Solutions AB. All rights reserved. * @@ -9,7 +9,10 @@ #define TOPO_IEEE1905_H -void uobj_add_event_handler(void *p, struct blob_attr *msg); +void uobj_add_event_handler(struct ubus_context *ctx, + struct ubus_event_handler *ev, + const char *type, struct blob_attr *msg); + void topology_subscribe_for_cmdus(struct topologyd_private *p); #endif /* TOPO_IEEE1905_H */ diff --git a/src/topologyd.c b/src/topologyd.c index 72c39ec60c6de68832680ce1718c2e1df3978180..6738e15fc8682fdacc1e7c1c00db73ba7685bfca 100644 --- a/src/topologyd.c +++ b/src/topologyd.c @@ -15,22 +15,33 @@ #include <libubus.h> #include <libubox/ustream.h> #include <libubox/utils.h> +#include <uci.h> -#include "nodes.h" #include <easy/easy.h> #include "debug.h" +#include "host_config.h" #include "topologyd.h" +#include "nodes.h" #include "config.h" #include "json_utils.h" #include "topo_ieee1905.h" +#include "host_nodes.h" +#include "host.h" extern const char *ubus_socket; uint32_t topology_log_max; static bool g_registrar_freq_band[3]; +static void topology_send_query_response(struct topologyd_private *priv, + uint16_t msg_type, uint8_t *origin, uint16_t msg_mid); + +void topologyd_process_topology_notification(struct cmdu_buff *cstruct, + struct topologyd_private *priv); + + static void ieee1905_info_response_cb(struct ubus_request *req, int mtype, struct blob_attr *msg) { @@ -66,21 +77,22 @@ static void ieee1905_info_response_cb(struct ubus_request *req, if (!freq_band) return; - if (freq_band) { - dbg(" IEE1905 freq band is %s\n", freq_band); - if ((strcasestr(freq_band, "2.4GHz")) != NULL) - g_registrar_freq_band[0] = 1; - if ((strcasestr(freq_band, "5GHz")) != NULL) - g_registrar_freq_band[1] = 1; - if ((strcasestr(freq_band, "60GHz")) != NULL) - g_registrar_freq_band[2] = 1; - free(freq_band); - } + dbg(" IEE1905 freq band is %s\n", freq_band); + if ((strcasestr(freq_band, "2.4GHz")) != NULL) + g_registrar_freq_band[0] = 1; + if ((strcasestr(freq_band, "5GHz")) != NULL) + g_registrar_freq_band[1] = 1; + if ((strcasestr(freq_band, "60GHz")) != NULL) + g_registrar_freq_band[2] = 1; + free(freq_band); } } } -int ieee1905_msg_from_ubus(struct blob_attr *msg, uint8_t *source, uint8_t *origin, uint16_t *msg_type, uint16_t *msg_mid, uint8_t **tlv, uint32_t *b_len, char *ingress_if_name) +int ieee1905_msg_from_ubus(struct blob_attr *msg, uint8_t *source, + uint8_t *origin, uint16_t *msg_type, + uint16_t *msg_mid, uint8_t **tlv, + uint32_t *b_len, char *ingress_if_name) { json_object *jroot = NULL; char *str; @@ -118,8 +130,11 @@ int ieee1905_msg_from_ubus(struct blob_attr *msg, uint8_t *source, uint8_t *orig } tlv_str = _json_obj_get_string(jroot, "cmdu"); - if (tlv_str == NULL) + if (tlv_str == NULL) { + json_safe_put(jroot); return 1; + } + len = strlen(tlv_str) - 16; // dbg(" The TLV string is %s LENGTH Id %d", tlv_str, len); *b_len = (len/2); @@ -127,14 +142,13 @@ int ieee1905_msg_from_ubus(struct blob_attr *msg, uint8_t *source, uint8_t *orig *tlv = (uint8_t *) malloc((*b_len) * sizeof(uint8_t)); if (*tlv == NULL) { err("No Memory\n"); - if (tlv_str != NULL) - free(tlv_str); + free(tlv_str); + json_safe_put(jroot); return 1; } - strtob(tlv_str+16, *b_len, *tlv); - if (tlv_str != NULL) - free(tlv_str); + strtob(tlv_str+16, *b_len, *tlv); + free(tlv_str); json_safe_put(jroot); } @@ -185,136 +199,6 @@ int topologyd_get_albridge_macaddr(struct topologyd_private *p) return ret; } -void topologyd_event_handler(void *c, struct blob_attr *msg) -{ - struct topologyd_private *priv = (struct topologyd_private *)c; - int ret = 0; - struct cmdu_buff *cstruct = NULL; - uint16_t msg_type = 0; - uint16_t msg_mid = 0; - uint8_t *tlv = NULL; - uint32_t len = 0; - char itfr_name[256] = {0}; - uint8_t source[6] = { 0 }, origin[6] = { 0 }; - - - dbg("Inside %s...\n", __func__); - if (!msg) - return; - - //Calling the function to get the args from json msg - - ret = ieee1905_msg_from_ubus(msg, source, origin, &msg_type, &msg_mid, &tlv, &len, itfr_name); - if (ret != 0) { - err("ieee1905_msg_from_ubus error\n"); - if (tlv != NULL) - free(tlv); - return; - } - - dbg("Inside topology event handler %hu %hu %s", msg_type, msg_mid, itfr_name); - - if (!((msg_type == CMDU_TYPE_TOPOLOGY_RESPONSE) || (msg_type == CMDU_TYPE_TOPOLOGY_NOTIFICATION) || (msg_type == CMDU_TYPE_AP_AUTOCONFIGURATION_RESPONSE) || (msg_type == CMDU_TYPE_HIGHER_LAYER_RESPONSE) || (msg_type == CMDU_TYPE_LINK_METRIC_RESPONSE) || (msg_type == CMDU_TYPE_GENERIC_PHY_RESPONSE) || (msg_type == CMDU_TYPE_TOPOLOGY_QUERY) || (msg_type == CMDU_TYPE_HIGHER_LAYER_QUERY) || (msg_type == CMDU_TYPE_LINK_METRIC_QUERY))) { - if (tlv != NULL) - free(tlv); - return; - } - - if (!((msg_type == CMDU_TYPE_TOPOLOGY_QUERY) || (msg_type == CMDU_TYPE_HIGHER_LAYER_QUERY) || (msg_type == CMDU_TYPE_LINK_METRIC_QUERY) || (msg_type == CMDU_TYPE_AP_AUTOCONFIGURATION_RESPONSE) || (msg_type == CMDU_TYPE_TOPOLOGY_NOTIFICATION))) { - dbg("Inside %s...DEQUEUE msg_type = [%d] msg_mid = [%d] src =["MACFMT"]\n", __func__, - msg_type, msg_mid, MAC2STR(origin)); - ret = cmdu_ackq_dequeue(&priv->cmdu_ack_q, msg_type, - msg_mid, origin); - if (ret) { - err("topologyd: drop unexpected CMDU (mid = %d)\n", - msg_mid); - if (tlv != NULL) - free(tlv); - return; - } - - } - - cstruct = cmdu_alloc_custom(msg_type, &msg_mid, NULL, source, tlv, len); - if (cstruct == NULL) { - if (tlv != NULL) - free(tlv); - return; - } - - dbg("%s: cmdu_alloc_custom() succeeded! cmdu->cdata->hdr.mid %u\n", __func__, cmdu_get_mid(cstruct)); - - dbg("After Event handler\n"); - - switch (msg_type) { - case CMDU_TYPE_TOPOLOGY_QUERY: - { - if (*tlv == MAP_TLV_MULTIAP_PROFILE) { - info("ignore the query with multi-ap tlv\n"); - goto out; - } - dbg("Received query message\n"); - topology_send_query_response(priv, msg_type, origin, msg_mid); - } - break; - case CMDU_TYPE_HIGHER_LAYER_QUERY: - case CMDU_TYPE_LINK_METRIC_QUERY: - { - dbg("Received query message\n"); - topology_send_query_response(priv, msg_type, origin, msg_mid); - } - break; - case CMDU_TYPE_TOPOLOGY_RESPONSE: - { - dbg("Received topology response message\n"); - topologyd_process_topology_response(cstruct, priv, itfr_name); - } - break; - case CMDU_TYPE_TOPOLOGY_NOTIFICATION: - { - /*Here we recieved the topology notification */ - /* we muct run the algo to update the topology*/ - if (!priv->algo_running) - topologyd_algo_run(priv); - topologyd_process_topology_notification(cstruct, priv); - } - break; - case CMDU_TYPE_HIGHER_LAYER_RESPONSE: - { - dbg("Received higher layer response message\n"); - topologyd_process_higherlayer_response(cstruct, priv); - } - break; - case CMDU_TYPE_AP_AUTOCONFIGURATION_RESPONSE: - { - dbg("Received ap autoconfiguration response message\n"); - topologyd_process_autoconfiguration_response(cstruct, priv); - } - break; - case CMDU_TYPE_LINK_METRIC_RESPONSE: - { - dbg("Received link metric response\n"); - topologyd_process_linkmetric_response(cstruct, priv); - - } - break; - case CMDU_TYPE_GENERIC_PHY_RESPONSE: - { - dbg("Received a generic phy response\n"); - //TODO not present in i1905 - //topologyd_process_generic_phy_response(cstruct, priv); - } - break; - default: - dbg("Event handler received default message\n"); - break; - } -out: - if (tlv != NULL) - free(tlv); - if (cstruct != NULL) - cmdu_free(cstruct); -} //int topology_update_devinfo(struct topologyd_private *priv, struct node *n, struct tlv_device_info *tv0) int topology_update_devinfo(struct topologyd_private *priv, struct node *n, struct tlv *t) @@ -326,7 +210,8 @@ int topology_update_devinfo(struct topologyd_private *priv, struct node *n, stru int offset = sizeof(struct tlv_device_info); struct host_node *node; bool is_wifi = false; - int rv = -1; + + //dbg("%s %d we found a node\n", __func__, __LINE__); dbg("|%s:%d| Entry"MACFMT"\n", __func__, __LINE__, MAC2STR(n->hwaddr)); @@ -356,7 +241,6 @@ int topology_update_devinfo(struct topologyd_private *priv, struct node *n, stru */ iface_node = host_node_lookup(priv->host.node_htable, tif->macaddr); if (iface_node) { - int rv = -1; dbg("%s %d we found a node\n", __func__, __LINE__); if (memcmp(node->hwaddr, iface_node->hwaddr, 6)) { @@ -582,7 +466,8 @@ void topologyd_process_topology_response(struct cmdu_buff *cstruct, struct topol int num = 0; while (tv[1][num]) { - ret = topology_update_bridging_info(&n, tv[1][num]->data); + ret = topology_update_bridging_info(&n, + (struct tlv_device_bridge_caps *)tv[1][num]->data); if (ret) break; num++; @@ -595,7 +480,10 @@ void topologyd_process_topology_response(struct cmdu_buff *cstruct, struct topol int list_num = 0; while (tv[2][num]) { - ret = topology_update_non_i1905nbr_list(&n, tv[2][num]->data, BUF_GET_BE16(tv[2][num]->len), &list_num); + ret = topology_update_non_i1905nbr_list(&n, + (struct tlv_non1905_neighbor *)tv[2][num]->data, + BUF_GET_BE16(tv[2][num]->len), + &list_num); if (ret) break; num++; @@ -606,7 +494,10 @@ void topologyd_process_topology_response(struct cmdu_buff *cstruct, struct topol int num = 0; int list_num = 0; while (tv[3][num]) { - ret = topology_update_neigh_list(&n, tv[3][num]->data, BUF_GET_BE16(tv[3][num]->len), &list_num); + ret = topology_update_neigh_list(&n, + (struct tlv_1905neighbor *)tv[3][num]->data, + BUF_GET_BE16(tv[3][num]->len), + &list_num); if (ret) break; num++; @@ -633,12 +524,11 @@ void topologyd_process_topology_response(struct cmdu_buff *cstruct, struct topol } if (tv[6][0]) { - - ret = topology_update_host_assoc_client(priv, tv[6][0]->data); + ret = topology_update_host_assoc_client(priv, + (struct tlv_assoc_client *)tv[6][0]->data); } if (tv[7][0]) { - ret = topology_update_host_vendor_specific_data(&n, priv, tv[7][0]); } @@ -854,22 +744,18 @@ void topologyd_process_higherlayer_response(struct cmdu_buff *cstruct, struct to } if (tv[2][0]) { - - ret = topology_update_device_ident(n, tv[2][0]->data); + ret = topology_update_device_ident(n, (struct tlv_device_identification *)tv[2][0]->data); } if (tv[3][0]) { - - ret = topology_update_control_url(n, tv[3][0]->data, BUF_GET_BE16(tv[3][0]->len)); + ret = topology_update_control_url(n, (struct tlv_control_url *)tv[3][0]->data, BUF_GET_BE16(tv[3][0]->len)); } if (tv[4][0]) { - ret = topology_update_ipv4(n, tv[4][0], aladdr_origin, priv); } if (tv[5][0]) { - ret = topology_update_ipv6(n, tv[5][0]); } } @@ -1044,7 +930,9 @@ void topologyd_process_linkmetric_response(struct cmdu_buff *cstruct, struct top } } - ret = topology_update_tx_link_metric(n, tv[0][num]->data, BUF_GET_BE16(tv[0][num]->len)); + ret = topology_update_tx_link_metric(n, + (struct tlv_tx_linkmetric *)tv[0][num]->data, + BUF_GET_BE16(tv[0][num]->len)); if (ret) break; num++; @@ -1079,7 +967,9 @@ void topologyd_process_linkmetric_response(struct cmdu_buff *cstruct, struct top } } - ret = topology_update_rx_link_metric(n, tv[1][num]->data, BUF_GET_BE16(tv[1][num]->len)); + ret = topology_update_rx_link_metric(n, + (struct tlv_rx_linkmetric *)tv[1][num]->data, + BUF_GET_BE16(tv[1][num]->len)); if (ret) break; num++; @@ -1087,6 +977,149 @@ void topologyd_process_linkmetric_response(struct cmdu_buff *cstruct, struct top return; } +void topologyd_event_handler(void *c, struct blob_attr *msg) +{ + struct topologyd_private *priv = (struct topologyd_private *)c; + int ret = 0; + struct cmdu_buff *cstruct = NULL; + uint16_t msg_type = 0; + uint16_t msg_mid = 0; + uint8_t *tlv = NULL; + uint32_t len = 0; + char itfr_name[256] = {0}; + uint8_t source[6] = { 0 }, origin[6] = { 0 }; + + + dbg("Inside %s...\n", __func__); + if (!msg) + return; + + //Calling the function to get the args from json msg + + ret = ieee1905_msg_from_ubus(msg, source, origin, &msg_type, &msg_mid, + &tlv, &len, itfr_name); + if (ret != 0) { + err("ieee1905_msg_from_ubus error\n"); + if (tlv != NULL) + free(tlv); + return; + } + + dbg("Inside topology event handler %hu %hu %s", msg_type, msg_mid, itfr_name); + if (msg_type != CMDU_TYPE_TOPOLOGY_RESPONSE && + msg_type != CMDU_TYPE_TOPOLOGY_NOTIFICATION && + msg_type != CMDU_TYPE_AP_AUTOCONFIGURATION_RESPONSE && + msg_type != CMDU_TYPE_HIGHER_LAYER_RESPONSE && + msg_type != CMDU_TYPE_LINK_METRIC_RESPONSE && + msg_type != CMDU_TYPE_GENERIC_PHY_RESPONSE && + msg_type != CMDU_TYPE_TOPOLOGY_QUERY && + msg_type != CMDU_TYPE_HIGHER_LAYER_QUERY && + msg_type != CMDU_TYPE_LINK_METRIC_QUERY) { + if (tlv != NULL) + free(tlv); + return; + } + + if (msg_type != CMDU_TYPE_TOPOLOGY_QUERY && + msg_type != CMDU_TYPE_HIGHER_LAYER_QUERY && + msg_type != CMDU_TYPE_LINK_METRIC_QUERY && + msg_type != CMDU_TYPE_AP_AUTOCONFIGURATION_RESPONSE && + msg_type != CMDU_TYPE_TOPOLOGY_NOTIFICATION) { + + dbg("Inside %s...DEQUEUE msg_type = [%d] msg_mid = [%d] src =["MACFMT"]\n", __func__, + msg_type, msg_mid, MAC2STR(origin)); + ret = cmdu_ackq_dequeue(&priv->cmdu_ack_q, msg_type, + msg_mid, origin); + if (ret) { + err("topologyd: drop unexpected CMDU (mid = %d)\n", msg_mid); + if (tlv != NULL) + free(tlv); + return; + } + } + + cstruct = cmdu_alloc_custom(msg_type, &msg_mid, NULL, source, tlv, len); + if (cstruct == NULL) { + if (tlv != NULL) + free(tlv); + return; + } + + dbg("%s: cmdu_alloc_custom() succeeded! cmdu->cdata->hdr.mid %u\n", + __func__, cmdu_get_mid(cstruct)); + + dbg("After Event handler\n"); + + switch (msg_type) { + case CMDU_TYPE_TOPOLOGY_QUERY: + { + if (*tlv == MAP_TLV_MULTIAP_PROFILE) { + info("ignore the query with multi-ap tlv\n"); + goto out; + } + dbg("Received query message\n"); + topology_send_query_response(priv, msg_type, origin, msg_mid); + } + break; + case CMDU_TYPE_HIGHER_LAYER_QUERY: + case CMDU_TYPE_LINK_METRIC_QUERY: + { + dbg("Received query message\n"); + topology_send_query_response(priv, msg_type, origin, msg_mid); + } + break; + case CMDU_TYPE_TOPOLOGY_RESPONSE: + { + dbg("Received topology response message\n"); + topologyd_process_topology_response(cstruct, priv, itfr_name); + } + break; + case CMDU_TYPE_TOPOLOGY_NOTIFICATION: + { + /*Here we recieved the topology notification */ + /* we muct run the algo to update the topology*/ + if (!priv->algo_running) + topologyd_algo_run(priv); + topologyd_process_topology_notification(cstruct, priv); + } + break; + case CMDU_TYPE_HIGHER_LAYER_RESPONSE: + { + dbg("Received higher layer response message\n"); + topologyd_process_higherlayer_response(cstruct, priv); + } + break; + case CMDU_TYPE_AP_AUTOCONFIGURATION_RESPONSE: + { + dbg("Received ap autoconfiguration response message\n"); + topologyd_process_autoconfiguration_response(cstruct, priv); + } + break; + case CMDU_TYPE_LINK_METRIC_RESPONSE: + { + dbg("Received link metric response\n"); + topologyd_process_linkmetric_response(cstruct, priv); + + } + break; + case CMDU_TYPE_GENERIC_PHY_RESPONSE: + { + dbg("Received a generic phy response\n"); + //TODO not present in i1905 + //topologyd_process_generic_phy_response(cstruct, priv); + } + break; + default: + dbg("Event handler received default message\n"); + break; + } +out: + if (tlv != NULL) + free(tlv); + if (cstruct != NULL) + cmdu_free(cstruct); +} + #if 0 void topology_add_txrx_data(uint8_t *metric, struct topologyd_private *priv) { @@ -1313,8 +1346,9 @@ void topologyd_dump_node(struct blob_buf *bb, struct node *p, int is_self) for (i = 0; i < 3; i++) { if (g_registrar_freq_band[i] == 1) { if (flag == 1) - strncat(freq_str, ",", 1); - strncat(freq_str, get_registra_freq_string(i), 15); + strncpy(freq_str + strlen(freq_str), ",", 2); + + strncpy(freq_str + strlen(freq_str), get_registra_freq_string(i), 15); flag = 1; } } @@ -1373,10 +1407,16 @@ void topologyd_dump_node(struct blob_buf *bb, struct node *p, int is_self) hwaddr_ntoa(p->l2_nbr[j].l2_nbr_addr, mac_str); blobmsg_add_string(bb, "local_nbr_id", mac_str); for (k = 0; k < p->l2_nbr[j].behind_intf_nbr; k++) { + size_t len, size; + + len = strlen(behind_mac_str); + size = sizeof(behind_mac_str); + hwaddr_ntoa(p->l2_nbr[j].behind_intf_addr[k], mac_str); if (k != 0) - strcat(behind_mac_str, ","); - strcat(behind_mac_str, mac_str); + snprintf(behind_mac_str + len, size, "%s,", behind_mac_str); + + snprintf(behind_mac_str + len, size, "%s", mac_str); } blobmsg_add_string(bb, "behind_mac_id", behind_mac_str); blobmsg_close_table(bb, table); @@ -1410,7 +1450,6 @@ void topologyd_dump_node(struct blob_buf *bb, struct node *p, int is_self) ipv4_param = blobmsg_open_array(bb, "ipv4_params"); for (j = 0; j < p->ipv4_intf_nbr; j++) { - int k; void *service_arr = NULL; table = blobmsg_open_table(bb, NULL); @@ -2087,153 +2126,82 @@ void changelog_copy_node_info(struct topologyd_private *t, struct node *p, int32 } } -void update_changelog_info(struct topologyd_private *priv, struct node *dest, struct node *src) +static void _update_changelog_info(struct topologyd_private *priv, + struct node *dest, struct node *src, + int change_type) { - dbg("Inside %s..\n", __func__); - int i = 0, j = 0, found = 0; struct topology_changelog elem; - struct host_node *ret = NULL; + struct host_node *hn; + int found; + int i, j; - if (dest == NULL || src == NULL || priv == NULL) - return; - dbg("The dest num [%d] src num [%d]", dest->non1905_nbr_num, src->non1905_nbr_num); - //Check the update in non neighbor node - if (dest->non1905_nbr_num != src->non1905_nbr_num) { - //Here a new non ieee1905 neighbor is added or deleted - if (dest->non1905_nbr_num > src->non1905_nbr_num) { - // non1905 neighbor node is deleted - dbg("Inside %s deleting non neighbor node\n", __func__); - for (i = 0; i < dest->non1905_nbr_num ; i++) { - found = 0; - for (j = 0; j < src->non1905_nbr_num; j++) { - if (memcmp(dest->non1905_nbrlist[i], src->non1905_nbrlist[j], 6) == 0) { - found = 1; - break; - } - } - if (found == 0) { - memcpy(elem.nbr_macaddr, dest->non1905_nbrlist[i], 6); - memcpy(elem.rpt_macaddr, dest->hwaddr, 6); - memcpy(elem.rpt_ifmacaddr, dest->non1905_nbr_localintf, 6); - elem.is1905_nbr = 0; - elem.type = 1; - enqueue_changelog(&(priv->topo), &elem); - //Send event - topology_send_node_event(&elem, src->ingress_ifr_name); - /*Here we need to change the status of node in hosts*/ - dbg("%s %d\n", __func__, __LINE__); - ret = host_node_lookup(priv->host.node_htable, elem.nbr_macaddr); - if (ret && ret->intf_type != HOST_TYPE_WIFI) { - ret = host_topo_node_del(priv, NULL, elem.nbr_macaddr, 0); - if (!ret) - err("Failed to del node in the hosts\n"); - } - } - } - } else { - if (dest->non1905_nbr_num < src->non1905_nbr_num) { - // non1905 neighbor node is added - dbg("Inside %s adding non neighbor node\n", __func__); - for (i = 0; i < src->non1905_nbr_num ; i++) { - found = 0; - for (j = 0; j < dest->non1905_nbr_num; j++) { - if (memcmp(dest->non1905_nbrlist[j], src->non1905_nbrlist[i], 6) == 0) { - found = 1; - break; - } - } - if (found == 0) { - memcpy(elem.nbr_macaddr, src->non1905_nbrlist[i], 6); - memcpy(elem.rpt_macaddr, src->hwaddr, 6); - memcpy(elem.rpt_ifmacaddr, src->non1905_nbr_localintf, 6); - elem.is1905_nbr = 0; - elem.type = 0; - enqueue_changelog(&(priv->topo), &elem); - //Send event - topology_send_node_event(&elem, src->ingress_ifr_name); - /*Here we need to add the node in the host*/ - struct host_node *hn; - hn = host_node_lookup(priv->host.node_htable, elem.nbr_macaddr); - if (!hn) { - hn = host_topo_node_add(priv, NULL, elem.nbr_macaddr, 0); - if (!hn) { - err("Failed to add non1905 node in the hosts\n"); - continue; - } - if (hn->is_ipaddr) - host_send_client_event(priv, hn, 1); - } - } - } - } - } - } else if (dest->non1905_nbr_num == src->non1905_nbr_num) { - //Here a new non ieee1905 neighbor is added or deleted - dbg("Inside %s deleting non neighbor node\n", __func__); - for (i = 0; i < dest->non1905_nbr_num ; i++) { - found = 0; - for (j = 0; j < src->non1905_nbr_num; j++) { - if (memcmp(dest->non1905_nbrlist[i], src->non1905_nbrlist[j], 6) == 0) { - found = 1; - break; - } - } - if (found == 0) { - memcpy(elem.nbr_macaddr, dest->non1905_nbrlist[i], 6); - memcpy(elem.rpt_macaddr, dest->hwaddr, 6); - memcpy(elem.rpt_ifmacaddr, dest->non1905_nbr_localintf, 6); - elem.is1905_nbr = 0; - elem.type = 1; - enqueue_changelog(&(priv->topo), &elem); - //Send event - topology_send_node_event(&elem, src->ingress_ifr_name); - /*Here we need to change the status of node in hosts*/ - dbg("%s %d\n", __func__, __LINE__); - ret = host_node_lookup(priv->host.node_htable, elem.nbr_macaddr); - if (ret && ret->intf_type != HOST_TYPE_WIFI) { - ret = host_topo_node_del(priv, NULL, elem.nbr_macaddr, 0); - if (!ret) - err("Failed to del node in the hosts\n"); - } + dbg("%s() ===>\n", __func__); + for (i = 0; i < dest->non1905_nbr_num; i++) { + found = 0; + for (j = 0; j < src->non1905_nbr_num; j++) { + if (!memcmp(dest->non1905_nbrlist[i], src->non1905_nbrlist[j], 6)) { + found = 1; + break; } } - // non1905 neighbor node is added - dbg("Inside %s adding non neighbor node\n", __func__); - for (i = 0; i < src->non1905_nbr_num ; i++) { - found = 0; - for (j = 0; j < dest->non1905_nbr_num; j++) { - if (memcmp(dest->non1905_nbrlist[j], src->non1905_nbrlist[i], 6) == 0) { - found = 1; - break; - } - } - if (found == 0) { - memcpy(elem.nbr_macaddr, src->non1905_nbrlist[i], 6); - memcpy(elem.rpt_macaddr, src->hwaddr, 6); - memcpy(elem.rpt_ifmacaddr, src->non1905_nbr_localintf, 6); - elem.is1905_nbr = 0; - elem.type = 0; - enqueue_changelog(&(priv->topo), &elem); - //Send event - topology_send_node_event(&elem, src->ingress_ifr_name); - /*Here we need to add the node in the host*/ - struct host_node *hn; - hn = host_node_lookup(priv->host.node_htable, elem.nbr_macaddr); + + if (found == 0) { + memcpy(elem.nbr_macaddr, dest->non1905_nbrlist[i], 6); + memcpy(elem.rpt_macaddr, dest->hwaddr, 6); + memcpy(elem.rpt_ifmacaddr, dest->non1905_nbr_localintf, 6); + elem.is1905_nbr = 0; + elem.type = change_type; + enqueue_changelog(&(priv->topo), &elem); + + //Send event + topology_send_node_event(&elem, src->ingress_ifr_name); + + dbg("%s %d\n", __func__, __LINE__); + + /* Here we need to change the status of node in hosts */ + hn = host_node_lookup(priv->host.node_htable, elem.nbr_macaddr); + if (hn && hn->intf_type != HOST_TYPE_WIFI) { + hn = host_topo_node_del(priv, NULL, elem.nbr_macaddr, 0); + if (!hn) + err("Failed to del node in the hosts\n"); + } else { + //XXX: if (change_type == 0) needed? + hn = host_topo_node_add(priv, NULL, elem.nbr_macaddr, 0); if (!hn) { - hn = host_topo_node_add(priv, NULL, elem.nbr_macaddr, 0); - if (!hn) { - err("Failed to add non1905 node in the hosts\n"); - continue; - } - if (hn->is_ipaddr) - host_send_client_event(priv, hn, 1); + err("Failed to add non1905 node in the hosts\n"); + continue; } + if (hn->is_ipaddr) + host_send_client_event(priv, hn, 1); } } } } +void update_changelog_info(struct topologyd_private *priv, struct node *dest, struct node *src) +{ + dbg("Inside %s..\n", __func__); + + if (dest == NULL || src == NULL || priv == NULL) + return; + + dbg("The dest num [%d] src num [%d]", dest->non1905_nbr_num, + src->non1905_nbr_num); + + /* Check the update in non1905 neighbor node */ + if (dest->non1905_nbr_num != src->non1905_nbr_num) { + if (dest->non1905_nbr_num > src->non1905_nbr_num) + _update_changelog_info(priv, dest, src, NBR_NODE_DEL); + else + _update_changelog_info(priv, src, dest, NBR_NODE_ADD); + } else { + dbg("%s %d\n", __func__, __LINE__); + _update_changelog_info(priv, dest, src, NBR_NODE_DEL); + _update_changelog_info(priv, src, dest, NBR_NODE_ADD); + } +} + struct cmdu_buff *topo_gen_query(uint16_t type) { struct cmdu_buff *resp; @@ -2496,7 +2464,6 @@ void topologyd_update_changelog_firstentry(struct topologyd_private *priv, struc int i = 0; struct topology_changelog elem; uint8_t node_mac[6]; - int ret = 0; struct host_node *hn = NULL; if (dest == NULL || priv == NULL) @@ -2675,7 +2642,7 @@ static void send_buildcmdu_cb(struct ubus_request *req, char *str; char *tlv_str; int len; - uint16_t msg_type; + uint16_t msg_type = 0; uint8_t *tlv = NULL; uint32_t b_len = 0; struct cmdu_buff *cstruct = NULL; @@ -2716,9 +2683,9 @@ static void send_buildcmdu_cb(struct ubus_request *req, json_safe_put(jroot); } cstruct = cmdu_alloc_custom(msg_type, &mid, NULL, priv->selfnode.hwaddr, tlv, b_len); - if (cstruct == NULL) return; + if (msg_type == CMDU_TYPE_TOPOLOGY_RESPONSE) { topologyd_process_topology_response(cstruct, priv, NULL); } else if (msg_type == CMDU_TYPE_HIGHER_LAYER_RESPONSE) { @@ -2784,16 +2751,12 @@ struct cmdu_buff *topo_gen_topology_query(struct topologyd_private *priv, uint8_ cmdu_put_eom(resp); return resp; -out: - cmdu_free(resp); - return NULL; } int topologyd_send_ieee1905_topology_query(struct topologyd_private *p, uint8_t *dest) { struct cmdu_buff *cmdu; - int ret = 0; dbg("Inside %s...\n", __func__); if (dest == NULL) @@ -2809,7 +2772,7 @@ int topologyd_send_ieee1905_topology_query(struct topologyd_private *p, } void topologyd_process_topology_notification(struct cmdu_buff *cstruct, - struct topologyd_private *priv) + struct topologyd_private *priv) { struct tlv *tv[1][16] = {0}; struct tlv_policy a_policy[] = { @@ -2824,7 +2787,8 @@ void topologyd_process_topology_notification(struct cmdu_buff *cstruct, cmdu_parse_tlvs(cstruct, tv, a_policy, 1); if (tv[0][0]) { - topology_update_client_assoc_event(priv, tv[0][0]->data); + topology_update_client_assoc_event(priv, + (struct tlv_client_assoc_event *)tv[0][0]->data); } else { //here the TLv is not present so the //notification is from IEEE1905 running the algo @@ -2838,7 +2802,6 @@ void topologyd_process_topology_notification(struct cmdu_buff *cstruct, uint16_t send_cmdu_query_resp(struct topologyd_private *priv, char *data, uint8_t *dst, uint16_t mid, uint16_t msg_type) { - int copy_index; struct blob_buf b = { 0 }; char dst_addr[18] = { 0 }; uint16_t msgid = 0; @@ -2889,7 +2852,7 @@ out: static void send_topology_buildcmdu_cb(struct ubus_request *req, - int type, struct blob_attr *msg) + int type, struct blob_attr *msg) { dbg("|%s:%d| Entry\n", __func__, __LINE__); @@ -2898,7 +2861,6 @@ static void send_topology_buildcmdu_cb(struct ubus_request *req, char *tlv_str = NULL; uint16_t msg_type = 0; int len = 0; - struct cmdu_buff *cstruct = NULL; struct topologyd_private *priv; uint8_t origin[6] = { 0 }; uint16_t msg_mid; @@ -2908,6 +2870,9 @@ static void send_topology_buildcmdu_cb(struct ubus_request *req, return; msg_ptr = (struct topo_resp_msg *)req->priv; + if (!msg_ptr) + return; + priv = msg_ptr->priv; msg_mid = msg_ptr->msg_mid; memcpy(origin, msg_ptr->origin, 6); @@ -2935,10 +2900,6 @@ static void send_topology_buildcmdu_cb(struct ubus_request *req, if (tlv_str != NULL) free(tlv_str); - if (msg_ptr != NULL) - free(msg_ptr); - if (cstruct != NULL) - cmdu_free(cstruct); } void topology_send_query_response(struct topologyd_private *priv, uint16_t msg_type, uint8_t *origin, uint16_t msg_mid) @@ -2973,18 +2934,19 @@ void topology_send_query_response(struct topologyd_private *priv, uint16_t msg_t if (ubus_lookup_id(priv->ctx, I1905_OBJ, &id)) { dbg("[%s:%d] not present i1905", __func__, __LINE__); - goto out; + goto out_msg; } ret = ubus_invoke(priv->ctx, id, "buildcmdu", b.head, send_topology_buildcmdu_cb, msg_ptr, 5000); - if (ret) { + if (ret) dbg("[%s:%d] ubus call failed for |i1905 buildcmdu|", __func__, __LINE__); - goto out; - } + +out_msg: + free(msg_ptr); out: blob_buf_free(&b); return; diff --git a/src/topologyd.h b/src/topologyd.h index b86e3cedfe4bfa47e4fb776a5d22ce912e14c7c3..62b452966d6102e52580c73aa73de148a142d1b5 100644 --- a/src/topologyd.h +++ b/src/topologyd.h @@ -19,9 +19,8 @@ #include <map_module.h> #include <map2.h> -#include "host.h" #include "cmdu_ackq.h" -#include "host_config.h" + #define IEEE1905_OBJECT "ieee1905" #define IEEE1905_EVENTS "ieee1905" @@ -246,8 +245,6 @@ struct host_ntwk { struct hlist_head node_htable[NODE_HTABLE_SIZE]; }; - - struct topologyd_private { int debug; bool algo_running; @@ -336,4 +333,10 @@ const char *get_ipv6_type(uint8_t ipv6_type); //Function to send the node add or delete event void topology_send_node_event(struct topology_changelog *c, char *ingress); +void topologyd_event_handler(void *c, struct blob_attr *msg); + + +bool config_init_host_data(char *package_name, char *section, + struct topologyd_private *priv); + #endif /* TOPOLOGYD_H */