diff --git a/src/Makefile b/src/Makefile index 86b626e99f7df0678da0f39e21fc883b07fbc1b5..226a4c81952ebbf5dca308950a9cc487acc96b18 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,10 +1,10 @@ CC ?= gcc -EXECS = mapagent dynbh/dynbhd +EXECS = mapagent #dynbh/dynbhd CFLAGS+=-I. -Iutils -D_GNU_SOURCE -DCONFIG_ALL_RADIOS #DEBUG=1 CFLAGS+= -ggdb3 -Wall -Werror CFLAGS += -I/usr/include/libnl3 -CFLAGS += -DVENDOR_EXTENSION +CFLAGS += -DVENDOR_EXTENSION -DDYNBH ifeq (,$(findstring EASYMESH_VERSION,$(CFLAGS))) $(info EASYMESH_VERSION is not set. Build for 6) @@ -47,7 +47,10 @@ AGENT_OBJS = \ dppfrag.o \ dpphandler.o \ qos.o \ - unasta.o + unasta.o \ + dynbh/dynbh.o \ + dynbh/dbh_nl.o \ + dynbh/dbh_config.o ifneq (,$(findstring VENDOR_EXTENSION,$(CFLAGS))) AGENT_OBJS += extension.o @@ -82,8 +85,8 @@ all: $(EXECS) extensions mapagent: $(OBJS) $(AGENT_OBJS) $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) -dynbh/dynbhd: $(OBJS) dynbh/dynbh.o dynbh/dbh_nl.o dynbh/dbh_config.o - $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) +#dynbh/dynbhd: $(OBJS) dynbh/dynbh.o dynbh/dbh_nl.o dynbh/dbh_config.o +# $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) extensions: @echo "$(plugin_subdirs)" diff --git a/src/agent.c b/src/agent.c index 89a0439a05b8d6d7b58ff7ecc80543c41314161e..d109f4ddebbc21172aef4979df31ed59849b0c88 100644 --- a/src/agent.c +++ b/src/agent.c @@ -51,6 +51,12 @@ #include "backhaul.h" #include "backhaul_blacklist.h" #include "config.h" +#ifdef DYNBH +#ifdef PERSIST_CONTROLLER +#include "dynbh/dbh_config.h" +#endif +#include "dynbh/dynbh.h" +#endif #if (EASYMESH_VERSION >= 3) #ifdef USE_LIBDPP #include "dpp.h" @@ -471,14 +477,14 @@ void wifiagent_log_cntlrinfo(struct agent *a) agent_notify_event(a, "map.agent", ev); } -int ubus_call_object_args(struct agent *a, wifi_object_t wobj, +int ubus_call_object_args(struct ubus_context *ctx, wifi_object_t wobj, struct blob_buf *bb, const char *method, void (*response_cb)(struct ubus_request *, int, struct blob_attr *), void *priv) { int ret; - ret = ubus_invoke(a->ubus_ctx, wobj, method, bb->head, + ret = ubus_invoke(ctx, wobj, method, bb->head, response_cb, priv, 2 * 1000); if (ret) { err("Failed to get '%s' (ret = %d)\n", method, ret); @@ -488,7 +494,7 @@ int ubus_call_object_args(struct agent *a, wifi_object_t wobj, return 0; } -int ubus_call_object(struct agent *a, wifi_object_t wobj, +int ubus_call_object(struct ubus_context *ctx, wifi_object_t wobj, const char *method, void (*response_cb)(struct ubus_request *, int, struct blob_attr *), void *priv) @@ -497,7 +503,7 @@ int ubus_call_object(struct agent *a, wifi_object_t wobj, int ret; blob_buf_init(&bb, 0); - ret = ubus_invoke(a->ubus_ctx, wobj, method, bb.head, + ret = ubus_invoke(ctx, wobj, method, bb.head, response_cb, priv, 2 * 1000); if (ret) { err("Failed to get '%s' (ret = %d)\n", method, ret); @@ -4257,7 +4263,7 @@ static void uobj_add_event_handler(void *agent, struct blob_attr *msg) if (ret) return; - ubus_call_object(a, ieee1905_obj, "info", parse_i1905_info, a); + ubus_call_object(a->ubus_ctx, ieee1905_obj, "info", parse_i1905_info, a); } else if (!strncmp(path, "wpa_supplicant.", 15)) { char *ifname = path + 15; @@ -5798,7 +5804,7 @@ static int init_wifi_radios(struct agent *a) } dbg("%s: getting radio:%s status\n", __func__, re->name); - ret = ubus_call_object(a, r_wobj, "status", parse_radio, re); + ret = ubus_call_object(a->ubus_ctx, r_wobj, "status", parse_radio, re); /* Get fresh opclass preferences after scan */ wifi_radio_update_opclass_preferences(a, re, 1); @@ -6797,7 +6803,7 @@ int agent_init_interfaces(struct agent *a) return -1; } - ubus_call_object(a, ieee1905_obj, "info", parse_i1905_info, a); + ubus_call_object(a->ubus_ctx, ieee1905_obj, "info", parse_i1905_info, a); ret = init_wifi_radios(a); if (ret || list_empty(&a->radiolist)) { @@ -6897,7 +6903,7 @@ int agent_init_interfaces(struct agent *a) continue; } - ret = ubus_call_object(a, uobj_id, "status", fn_parser, fn); + ret = ubus_call_object(a->ubus_ctx, uobj_id, "status", fn_parser, fn); if (ret) { err("Failed to get '%s' (ret = %d) name:%s\n", "status", ret, objname); timer_set(&a->init_ifaces_scheduler, @@ -6917,8 +6923,8 @@ int agent_init_interfaces(struct agent *a) if (band) blobmsg_add_u32(&bb, "band", band); #endif - ubus_call_object_args(a, uobj_id, &bb, "stats", parse_ap_stats, bss); - ubus_call_object_args(a, uobj_id, &bb, "dump_beacon", parse_beacon_params, bss); + ubus_call_object_args(a->ubus_ctx, uobj_id, &bb, "stats", parse_ap_stats, bss); + ubus_call_object_args(a->ubus_ctx, uobj_id, &bb, "dump_beacon", parse_beacon_params, bss); blob_buf_free(&bb); } @@ -6986,7 +6992,7 @@ int agent_init_interfaces(struct agent *a) objname, b->name); continue; } - ret = ubus_call_object(a, uobj_id, "status", bk_parser, bn); + ret = ubus_call_object(a->ubus_ctx, uobj_id, "status", bk_parser, bn); if (ret) { err("Failed to get '%s' (ret = %d) name:%s\n", "status", ret, objname); timer_set(&a->init_ifaces_scheduler, @@ -7168,7 +7174,7 @@ static void agent_fetch_ap_stats(struct agent *a) if (band) blobmsg_add_u32(&bb, "band", band); #endif - ubus_call_object_args(a, uobj_id, &bb, "stats", parse_ap_stats, bss); + ubus_call_object_args(a->ubus_ctx, uobj_id, &bb, "stats", parse_ap_stats, bss); blob_buf_free(&bb); } } @@ -7224,7 +7230,7 @@ static void agent_radio_stats_cb(atimer_t *t) if (r_wobj == WIFI_OBJECT_INVALID) continue; - ubus_call_object(a, r_wobj, "stats", parse_radio_stats, re); + ubus_call_object(a->ubus_ctx, r_wobj, "stats", parse_radio_stats, re); } timer_set(&a->radio_stats_scheduler, RADIO_STATS_TIMER); @@ -7414,15 +7420,18 @@ static void agent_dispatch_autoconfig(atimer_t *t) list_for_each_entry(re, &a->radiolist, list) { struct cmdu_buff *cmdu; + uint8_t ieee1905band; if (!a->active_cntlr) { trace("|%s:%d| No active Controller present!\n", __func__, __LINE__); re->state = AUTOCFG_ACTIVE; } - cmdu = agent_gen_ap_autoconfig_search(a, re, 0x02); + ieee1905band = wifi_band_to_ieee1905band(re->band); + cmdu = agent_gen_ap_autoconfig_search(a, ieee1905band, 0x02); if (!cmdu) continue; + trace("|%s:%d| Sending Autoconfig Search for radio %s(%s)\n", __func__, __LINE__, re->name, (re->band == BAND_2 ? "2.4GHz" : "5GHz")); @@ -8116,6 +8125,23 @@ void run_agent(void *opts) timestamp_update(&w->start_t); +#ifdef DYNBH +#ifdef PERSIST_CONTROLLER + dbh_config_load(priv); +#endif + int num = 0; + char ifs[16][16] = {0}; + int i; + + memcpy(w->priv.almac, w->almac, 6); + w->priv.ubus_ctx = ctx; + strncpy(w->priv.al_bridge, w->cfg.al_bridge, sizeof(w->priv.al_bridge) - 1); + INIT_LIST_HEAD(&w->priv.ethportlist); + get_ethportslist(&num, ifs); + for (i = 0; i < num; i++) + alloc_ethport_search(&w->priv, ifs[i]); +#endif + uloop_run(); /* out_and_exit: */ diff --git a/src/agent.h b/src/agent.h index d68738db7b1de65ec61e59eb37cf5b8a880c8c1a..758b5b2bb2940fc6171c2e126d41e8bf351cfd1c 100644 --- a/src/agent.h +++ b/src/agent.h @@ -24,6 +24,7 @@ #include <stdbool.h> #include <wifidefs.h> +#include "dynbh/dynbh.h" #include "utils/allmac.h" #include "utils/debug.h" #include "config.h" @@ -962,6 +963,9 @@ struct agent { atimer_t dpp_legacy_timeout; #endif /* dynamic backhaul */ +#ifdef DYNBH + struct dynbh_ctx priv; +#endif atimer_t dynbh_scheduler; bool dynbh_upgrade_ongoing; /* when true upgrade attempt ongoing */ int dynbh_attempts; /* number of upgrade attempts since connection */ @@ -1070,7 +1074,11 @@ int prepare_tunneled_message(void *agent, const char *ifname, uint8_t protocol, const char *framestr); int wifi_mod_bridge(struct agent *a, struct netif_bk *bk, bool add); uint32_t ubus_get_object(struct ubus_context *ctx, const char *name); -int ubus_call_object(struct agent *a, wifi_object_t wobj, const char *method, +int ubus_call_object_args(struct ubus_context *ctx, wifi_object_t wobj, + struct blob_buf *bb, const char *method, + void (*response_cb)(struct ubus_request *, int, struct blob_attr *), + void *priv); +int ubus_call_object(struct ubus_context *ctx, wifi_object_t wobj, const char *method, void (*response_cb)(struct ubus_request *, int, struct blob_attr *), void *priv); int wifi_radio_scan_req(struct agent *a, struct wifi_radio_element *re, const char *ssid, int num_opclass, diff --git a/src/agent_cmdu.c b/src/agent_cmdu.c index 4d4d580be62145ed35c2e92d4f86dd7766e4168b..9d32c252c6c38f5b5d3f1aff798a30c2571ff405 100644 --- a/src/agent_cmdu.c +++ b/src/agent_cmdu.c @@ -39,7 +39,7 @@ struct cmdu_buff *agent_gen_ap_autoconfig_search(struct agent *a, - struct wifi_radio_element *radio, uint8_t profile) + uint8_t ieee1905band, uint8_t profile) { struct cmdu_buff *frm = NULL; int ret = 0; @@ -63,9 +63,6 @@ struct cmdu_buff *agent_gen_ap_autoconfig_search(struct agent *a, if (ret) goto out; - band = wifi_band_to_ieee1905band(radio->band); - trace("radio band = %d, band = %d\n", radio->band, band); - ret = agent_gen_autoconf_freq_band(a, frm, band); if (ret) goto out; @@ -102,7 +99,7 @@ struct cmdu_buff *agent_gen_ap_autoconfig_search(struct agent *a, memcpy(frm->origin, origin, 6); cmdu_put_eom(frm); - dbg("%s:%d: radio = %s\n", __func__, __LINE__, radio->name); + dbg("%s:%d: band = 0x%x\n", __func__, __LINE__, ieee1905band); return frm; out: cmdu_free(frm); @@ -1811,7 +1808,8 @@ error: return NULL; } -struct cmdu_buff *agent_gen_topology_discovery(struct agent *a) +struct cmdu_buff *agent_gen_topology_discovery(struct agent *a, uint8_t *almac, + uint8_t *macaddr) { struct cmdu_buff *frm = NULL; uint16_t mid = 0; @@ -1824,11 +1822,11 @@ struct cmdu_buff *agent_gen_topology_discovery(struct agent *a) return NULL; } - ret = agent_gen_al_mac(a, frm, a->almac); + ret = agent_gen_al_mac(a, frm, almac); if (ret) goto out; - ret = agent_gen_mac(a, frm, a->almac); + ret = agent_gen_mac(a, frm, macaddr); if (ret) goto out; diff --git a/src/agent_cmdu.h b/src/agent_cmdu.h index fd100dc763bacceca911a29862d190fa9d79b2cc..e3f1684d997e2f3e6f2e58badaba2addbac1421d 100644 --- a/src/agent_cmdu.h +++ b/src/agent_cmdu.h @@ -30,7 +30,7 @@ struct wifi_scan_request_radio; #define CH_SCAN_RESP_CMDU_MAX_LEN 1400 struct cmdu_buff *agent_gen_ap_autoconfig_search(struct agent *a, - struct wifi_radio_element *radio, uint8_t profile); + uint8_t ieee1905band, uint8_t profile); struct cmdu_buff *agent_gen_ap_metrics_response(struct agent *a, struct cmdu_buff *rec_cmdu, struct node *n); struct cmdu_buff *agent_gen_higher_layer_response(struct agent *a, @@ -62,7 +62,7 @@ struct cmdu_buff *agent_gen_ap_caps_response(struct agent *a, struct cmdu_buff *rec_cmdu); struct cmdu_buff *agent_gen_bk_caps_response(struct agent *a, struct cmdu_buff *cmdu); -struct cmdu_buff *agent_gen_topology_notification (struct agent *agent, +struct cmdu_buff *agent_gen_topology_notification(struct agent *agent, struct sta *s, uint8_t *bssid, uint8_t assoc_event); struct cmdu_buff *agent_gen_ap_autoconfig_wsc(struct agent *a, uint8_t *origin, struct wifi_radio_element *radio); @@ -96,7 +96,8 @@ struct cmdu_buff *agent_gen_assoc_sta_metric_responsex(struct agent *a, struct cmdu_buff *agent_gen_oper_channel_response(struct agent *a, struct wifi_radio_element *radio, uint32_t channel, uint32_t bandwidth, bool all); -struct cmdu_buff *agent_gen_topology_discovery(struct agent *a); +struct cmdu_buff *agent_gen_topology_discovery(struct agent *a, uint8_t *almac, + uint8_t *macaddr); struct cmdu_buff *agent_gen_failed_connection(struct agent *a, uint8_t *sta, int status_code, int reason_code); diff --git a/src/agent_map.c b/src/agent_map.c index dd1cc0ccef7dd7f442e757d6ef94d5676d41c6f0..868d638f6462d2d496f039ae468d94e78675edd2 100644 --- a/src/agent_map.c +++ b/src/agent_map.c @@ -1375,7 +1375,7 @@ int handle_ap_autoconfig_search(void *agent, struct cmdu_buff *rx_cmdu, } } } - + dbh_handle_autoconfig_search(&a->priv, rx_cmdu->dev_ifname, cmdu_get_mid(rx_cmdu), tv); return 0; } @@ -1619,6 +1619,7 @@ int handle_ap_autoconfig_response(void *agent, struct cmdu_buff *rx_cmdu, agent_reschedule_heartbeat_autocfg(a, HEARTBEAT_AUTOCFG_INTERVAL); } + dbh_handle_autoconfig_response(&a->priv, rx_cmdu->dev_ifname, cmdu_get_mid(rx_cmdu), tv); return 0; } diff --git a/src/backhaul.c b/src/backhaul.c index 50beae76e342791eb07d16c381e1927047b15905..05d0c6c514713a740d909b3383df5cc41aa155c1 100644 --- a/src/backhaul.c +++ b/src/backhaul.c @@ -542,7 +542,7 @@ void agent_check_bsta_connections(struct agent *a) #endif uobjid = ubus_get_object(a->ubus_ctx, objname); - ubus_call_object(a, uobjid, "status", cb, bk); + ubus_call_object(a->ubus_ctx, uobjid, "status", cb, bk); } /* reloading is costly - only do it once after all parsing is done */ diff --git a/src/dynbh/dbh_config.c b/src/dynbh/dbh_config.c index 29fcade160fe5d37eb70239ab6a5354c45f097ae..6d35b04fa7736e002807bddd723b821ad9762fc7 100644 --- a/src/dynbh/dbh_config.c +++ b/src/dynbh/dbh_config.c @@ -1,3 +1,4 @@ +#if DYNBH #include "dbh_config.h" #include <stdbool.h> @@ -102,3 +103,4 @@ int dbh_config_load(struct dynbh_ctx *cfg) return 0; } #endif +#endif diff --git a/src/dynbh/dbh_config.h b/src/dynbh/dbh_config.h index 97c684be589aabd706ca7a7fb6d1eb156277814a..ff6ea73831333b9dbdaf787d570378ae47893dde 100644 --- a/src/dynbh/dbh_config.h +++ b/src/dynbh/dbh_config.h @@ -1,3 +1,4 @@ +#ifdef DYNBH #ifndef DBH_CONFIG_H #define DBH_CONFIG_H @@ -9,4 +10,5 @@ int set_value_by_string(const char *package, const char *section, const char *key, const char *value, enum uci_option_type type); int dbh_config_load(struct dynbh_ctx *cfg); #endif +#endif #endif \ No newline at end of file diff --git a/src/dynbh/dbh_nl.c b/src/dynbh/dbh_nl.c index 46b40c3f8b7ba4e5eca70c756448e39ebdfc9c88..5d31ff2e0b8d9ab14f00e0dced80ac2544fc9359 100644 --- a/src/dynbh/dbh_nl.c +++ b/src/dynbh/dbh_nl.c @@ -1,14 +1,16 @@ /* - * i1905_netlink.c - netlink interface to kernel. + * dbh_nl.c - netlink interface to kernel. * - * Copyright (C) 2021 IOPSYS Software Solutions AB. All rights reserved. + * Copyright (C) 2021-2024 IOPSYS Software Solutions AB. All rights reserved. + * Copyright (C) 2025 Genexis AB. * - * Author: anjan.chanda@iopsys.eu + * Author: jakob.olsson@genexis.eu * * See LICENSE file for license related information. * */ +#ifdef DYNBH #include "dbh_nl.h" #include <time.h> @@ -251,3 +253,4 @@ void i1905_unregister_nlevents(struct dynbh_ctx *priv) rtnl_event.sock = NULL; } } +#endif diff --git a/src/dynbh/dbh_nl.h b/src/dynbh/dbh_nl.h index a65f459804fe3ff65def1f093e86fe3d3345a459..ead974e78e6bb35cdf8e9e7b470d0f838b4e2d33 100644 --- a/src/dynbh/dbh_nl.h +++ b/src/dynbh/dbh_nl.h @@ -1,3 +1,4 @@ +#ifdef DYNBH #ifndef DBH_NL_H #define DBH_NL_H @@ -6,4 +7,5 @@ struct dynbh_ctx; int i1905_register_nlevents(struct dynbh_ctx *priv); void i1905_unregister_nlevents(struct dynbh_ctx *priv); -#endif \ No newline at end of file +#endif +#endif diff --git a/src/dynbh/dynbh.c b/src/dynbh/dynbh.c index afc2d421435ecd00876f5f91829e376e08ce624a..e3dc26e2ca06de421851961ecfb0e7c73652a51d 100644 --- a/src/dynbh/dynbh.c +++ b/src/dynbh/dynbh.c @@ -1,7 +1,7 @@ +#ifdef DYNBH #include "dynbh.h" #include <1905_tlvs.h> -#include <cmdu.h> #include <easy/if_utils.h> #include <easy/utils.h> #include <easymesh.h> @@ -20,6 +20,10 @@ #include <ubusmsg.h> #include <linux/if.h> +#include "agent.h" +#include "agent_cmdu.h" +#include "backhaul.h" +#include "1905_ubus.h" #include "dbh_config.h" #include "dbh_nl.h" #include "../utils/utils.h" @@ -30,18 +34,97 @@ #define BIT(n) (1U << (n)) #endif -const char *PROG_NAME = "dynbhd"; -bool syslogging; -bool usefifo; -const char *outfile_path; -const char *objname; - #define map_plugin IEEE1905_OBJECT_MULTIAP #define HEARTBEAT_PROBE_TIMEOUT 30 #define APCONF_MAX_RETRIES 5 #define APCONF_INTERVAL 2 +#if 0 +issue_discovery() { + local iface="$1" + + ubus list ieee1905 > /dev/null 2>&1 + + [ "$?" != 0 ] && return + + res=$(ubus -t2 call ieee1905 buildcmdu "{\"type\":0, \"ifname\":\"${iface}\"}") + json_load "$res" > /dev/null 2>&1 + json_get_var data data + + [ "$data" == "" ] && return + + ubus -t1 wait_for ieee1905.al.$iface > /dev/null 2>&1 + [ "$?" != 0 ] && return + + ubus call ieee1905.al.$iface cmdu "{\"dst\":\"01:80:c2:00:00:13\", \"type\":0, \"data\":\"${data}\"}" +} +#endif +static void issue_discovery(struct dynbh_ctx *priv, struct ethport *port) +{ + struct agent *a = container_of(priv, struct agent, priv); + struct cmdu_buff *resp; + + resp = agent_gen_topology_discovery(a, priv->almac, port->macaddr); + if (resp) { + // agent_send_cmdu(a, resp); + // cmdu_free(resp); + } +} + +static void bridge_delif(struct dynbh_ctx *priv, struct ethport *port) +{ + br_delif(priv->al_bridge, port->ifname); + issue_discovery(priv, port); +} + +static void bridge_addif(struct dynbh_ctx *priv, struct ethport *port) +{ + br_addif(priv->al_bridge, port->ifname); + issue_discovery(priv, port); +} + +static void i1905_modif(struct dynbh_ctx *priv, struct ethport *port, bool add) +{ + uint32_t uobj_id = WIFI_OBJECT_INVALID; + const char *fn = (add ? "add_interface" : "del_interface"); + int ret; + struct blob_buf bb = {0}; + //char objname[32]; + //TODO: IF OBJECT ALREADY EXISTS AND ADDIF NOP + + //snprintf(objname, sizeof(objname), "ieee1905.al.%s", port->ifname); + + uobj_id = ubus_get_object(priv->ubus_ctx, "ieee1905"); + if (uobj_id == WIFI_OBJECT_INVALID) { + err("%s: ieee1905 not present\n", __func__); + return; + } + //if (uobj_id == WIFI_OBJECT_INVALID && add + // || uobj_id != WIFI_OBJECT_INVALID && !del) { + // err("%s not present! skipping '%s' from config\n", + // objname, f->name); + // continue; + blob_buf_init(&bb, 0); + blobmsg_add_string(&bb, "ifname", port->ifname); + ret = ubus_call_object_args(priv->ubus_ctx, uobj_id, &bb, fn, NULL, NULL); + if (ret) { + err("%s: Failed to get '%s' (ret = %d) name:%s\n", __func__, fn, ret, "ieee1905"); + } + blob_buf_free(&bb); +} + +static void i1905_addif(struct dynbh_ctx *priv, struct ethport *port) +{ + i1905_modif(priv, port, true); +} + +static void i1905_delif(struct dynbh_ctx *priv, struct ethport *port) +{ + i1905_modif(priv, port, false); +} + + /** * disconnect & disable bstas * create /var/run/multiap/map.agent.bsta_global_disable @@ -49,7 +132,7 @@ const char *objname; */ static void link_up(struct ethport *port) { - fprintf(stderr, "|%s:%d|\n", __func__, __LINE__); + err("|%s:%d|\n", __func__, __LINE__); runCmd("/lib/wifi/dynbhd/api up %s", port->ifname); runCmd("/lib/wifi/multiap set_uplink eth %s", port->ifname); } @@ -60,20 +143,20 @@ static void link_up(struct ethport *port) */ static void link_down(void) { - fprintf(stderr, "|%s:%d|\n", __func__, __LINE__); + err("|%s:%d|\n", __func__, __LINE__); runCmd("/lib/wifi/dynbhd/api down"); } #ifdef PERSIST_CONTROLLER static void controller_discovery_persist(void) { - fprintf(stderr, "|%s:%d|\n", __func__, __LINE__); + err("|%s:%d|\n", __func__, __LINE__); runCmd("/lib/wifi/dynbhd/api persist_cntlr"); } static void controller_discovery_disable(void) { - fprintf(stderr, "|%s:%d|\n", __func__, __LINE__); + err("|%s:%d|\n", __func__, __LINE__); runCmd("/lib/wifi/dynbhd/api disable_cntlr"); } @@ -81,18 +164,20 @@ static int controller_discovery_dhcp(void) { char rc[2] = {0}; - fprintf(stderr, "|%s:%d|\n", __func__, __LINE__); + err("|%s:%d|\n", __func__, __LINE__); chrCmd(rc, 2, "/lib/wifi/dynbhd/api dhcp_discovery"); return atoi(rc); } #endif -void delif(struct ethport *port) +void delif(struct dynbh_ctx *priv, struct ethport *port) { - runCmd("/lib/wifi/dynbhd/api bridge_delif %s", port->ifname); - runCmd("ubus call ieee1905 add_interface '{\"ifname\":\"%s\"}'", port->ifname); - fprintf(stderr, "brctl delif %s %s\n", port->ctx->al_bridge, port->ifname); + //runCmd("/lib/wifi/dynbhd/api bridge_delif %s", port->ifname); + bridge_delif(priv, port); + //runCmd("ubus call ieee1905 add_interface '{\"ifname\":\"%s\"}'", port->ifname); + i1905_addif(port->ctx, port); + err("brctl delif %s %s\n", port->ctx->al_bridge, port->ifname); } void addif(struct ethport *port) @@ -100,9 +185,11 @@ void addif(struct ethport *port) if (if_isbridge_interface(port->ifname)) return; - runCmd("ubus call ieee1905 del_interface '{\"ifname\":\"%s\"}'", port->ifname); - runCmd("/lib/wifi/dynbhd/api bridge_addif %s", port->ifname); /* add back to bridge */ - fprintf(stderr, "cmd: brctl addif %s %s\n", port->ctx->al_bridge, port->ifname); /* add back to bridge */ + //runCmd("ubus call ieee1905 del_interface '{\"ifname\":\"%s\"}'", port->ifname); + i1905_delif(port->ctx, port); + bridge_addif(port->ctx, port); + //runCmd("/lib/wifi/dynbhd/api bridge_addif %s", port->ifname); /* add back to bridge */ + err("cmd: brctl addif %s %s\n", port->ctx->al_bridge, port->ifname); /* add back to bridge */ } struct ethport *ethport_by_ifname(struct dynbh_ctx *p, @@ -122,13 +209,13 @@ struct ethport *ethport_by_mid(struct dynbh_ctx *p, uint16_t mid) { struct ethport *port = NULL; - fprintf(stderr, "%s %d mid %d\n", __func__, __LINE__, mid); + err("%s %d mid %d\n", __func__, __LINE__, mid); list_for_each_entry(port, &p->ethportlist, list) { int i; for (i = 0; i < port->num_mid; i++) { - fprintf(stderr, "%s %d mid[%d] %d\n", __func__, __LINE__, i, port->mid[i]); + err("%s %d mid[%d] %d\n", __func__, __LINE__, i, port->mid[i]); if (port->mid[i] == mid) return port; @@ -148,7 +235,7 @@ static void bridge_readd(atimer_t *t) if (port->active_uplink) link_down(); - fprintf(stderr, "|%s:%d| link timed out for iface:%s mid:%d, %d, add back to bridge\n", __func__, __LINE__, port->ifname, port->mid[0], port->mid[1]); + err("|%s:%d| link timed out for iface:%s mid:%d, %d, add back to bridge\n", __func__, __LINE__, port->ifname, port->mid[0], port->mid[1]); port->loop = false; port->active_uplink = false; addif(port); @@ -158,7 +245,7 @@ static void bridge_readd(atimer_t *t) if (timeout > HEARTBEAT_PROBE_TIMEOUT) timeout = HEARTBEAT_PROBE_TIMEOUT; - fprintf(stderr, "|%s:%d| timeout = %d\n", __func__, __LINE__, timeout); + err("|%s:%d| timeout = %d\n", __func__, __LINE__, timeout); port->retries++; timer_set(&port->send_apconf, timeout * 1000); @@ -186,24 +273,25 @@ static void bridge_readd(atimer_t *t) static void send_apconf_cb(atimer_t *t) { struct ethport *port = container_of(t, struct ethport, send_apconf); - char mid[16] = {0}; + struct agent *a = container_of(port->ctx, struct agent, priv); + struct cmdu_buff *cmdu; + uint16_t mid = 0; - fprintf(stderr, "|%s:%d| sending query num %d for ifname:%s alid:%s \n", __func__, __LINE__, (port->num_mid+1), port->ifname, port->ctx->alidstr); - runCmd("[ -n \"$(ubus list ieee1905.al.%s)\" ] || ubus call ieee1905 add_interface '{\"ifname\":\"%s\"}'", port->ifname, port->ifname); + err("|%s:%d| sending query num %d for ifname:%s alid:"MACFMT" \n", __func__, __LINE__, (port->num_mid+1), port->ifname, MAC2STR(port->ctx->almac)); + //runCmd("[ -n \"$(ubus list ieee1905.al.%s)\" ] || ubus call ieee1905 add_interface '{\"ifname\":\"%s\"}'", port->ifname, port->ifname); + i1905_addif(port->ctx, port); /* ubus call ieee1905 cmdu '{"ifname":"eth0", "dst":"01:80:C2:00:00:13", "type":7, "mid":0, "data":"010006A6CEDA6DAF8412s0d0001000e00010080000201018100020100b3000102000000"}' */ - chrCmd(mid, 16, "ubus call ieee1905.al.%s cmdu '{\"dst\":\"01:80:C2:00:00:13\", \"type\":7, \"mid\":0, \"data\":\"010006%12s0d0001000e00010080000201018100020100b3000102000000\"}' | grep mid | cut -d' ' -f2", port->ifname, port->ctx->alidstr); - runCmd("ubus list ieee1905.al.%s", port->ifname); - fprintf(stderr, "mid = %s\n", mid); - errno = 0; - port->mid[port->num_mid] = (uint16_t) strtoul(mid, NULL, 10); - if (errno) { - fprintf(stderr, "Invalid mid value: %s\n", mid); - port->mid[port->num_mid] = 0; - } - fprintf(stderr, "mid[%d] = %u\n", port->num_mid, port->mid[port->num_mid]); + //chrCmd(mid, 16, "ubus call ieee1905.al.%s cmdu '{\"dst\":\"01:80:C2:00:00:13\", \"type\":7, \"mid\":0, \"data\":\"010006%12s0d0001000e00010080000201018100020100b3000102000000\"}' | grep mid | cut -d' ' -f2", port->ifname, port->ctx->alidstr); + //SEND AUTOCONF SEARCH + cmdu = agent_gen_ap_autoconfig_search(a, 0x01, 0x03); + ieee1905_ubus_send_al_cmdu(port->ctx->ubus_ctx, cmdu, &mid, port->ifname, a->pvid); + //runCmd("ubus list ieee1905.al.%s", port->ifname); + err("mid = %d\n", mid); + port->mid[port->num_mid] = mid; + err("mid[%d] = %d\n", port->num_mid, port->mid[port->num_mid]); if (port->num_mid < 31) port->num_mid++; @@ -232,7 +320,7 @@ static void send_dhcp_discovery_cb(atimer_t *t) * uplink and take no action */ - fprintf(stderr, "%s: sending dhcp discovery num:%d\n", __func__, port->dhcp_retries); + err("%s: sending dhcp discovery num:%d\n", __func__, port->dhcp_retries); rc = controller_discovery_dhcp(); if (rc) { @@ -245,44 +333,6 @@ static void send_dhcp_discovery_cb(atimer_t *t) } #endif - -/* check for eth uplink existence */ -static bool is_backhaul_type_eth(void) -{ - struct blob_buf bk = { 0 }; - char *type; - struct blob_attr *tb[4]; - static const struct blobmsg_policy bk_attr[4] = { - [0] = { .name = "type", .type = BLOBMSG_TYPE_STRING }, - [1] = { .name = "macaddr", .type = BLOBMSG_TYPE_STRING }, - [2] = { .name = "backhaul_device_id", .type = BLOBMSG_TYPE_TABLE }, - [3] = { .name = "backhaul_device_macaddr", .type = BLOBMSG_TYPE_TABLE }, - }; - - blob_buf_init(&bk, 0); - - if (!blobmsg_add_json_from_file(&bk, MAP_UPLINK_PATH)) { - fprintf(stderr, "Failed to parse %s\n", MAP_UPLINK_PATH); - goto out; - } - - blobmsg_parse(bk_attr, 4, tb, blob_data(bk.head), blob_len(bk.head)); - - if (!tb[0]) - goto out; - - type = blobmsg_data(tb[0]); - - fprintf(stderr, "---- type = %s ------\n", type); - - blob_buf_free(&bk); - - return !strncmp(type, "eth", 4); -out: - blob_buf_free(&bk); - return false; -} - void dynbh_handle_port_down(struct dynbh_ctx *priv, struct ethport *port) { timer_del(&port->send_apconf); @@ -332,7 +382,7 @@ void dynbh_handle_port_up(struct ethport *port) timer_set(&port->bridge_add, (APCONF_MAX_RETRIES * APCONF_INTERVAL) * 1000); /* remove iface from brdige */ - delif(port); + delif(port->ctx, port); } struct ethport *alloc_ethport_search(struct dynbh_ctx *priv, @@ -401,7 +451,7 @@ static void mapagent_event_handler(void *agent, struct blob_attr *msg) blobmsg_data(tb[1]), blobmsg_data_len(tb[1])); if (!tb2[0] || !tb2[1]) { - fprintf(stderr, "|%s:%d| event parse error.\n", __func__, __LINE__); + err("|%s:%d| event parse error.\n", __func__, __LINE__); return; } @@ -440,7 +490,7 @@ static void agent_event_handler(struct ubus_context *ctx, if (!str) return; - fprintf(stderr, "[ &agent = %p ] Received [event = %s] [val = %s]\n", + err("[ &agent = %p ] Received [event = %s] [val = %s]\n", a, type, str); for (i = 0; i < ARRAY_SIZE(evs); i++) { if (!strcmp(type, evs[i].ev_type)) { @@ -453,79 +503,17 @@ static void agent_event_handler(struct ubus_context *ctx, } #endif -static char *agent_get_backhaul_ifname(char *ifname) -{ - struct blob_buf bk = { 0 }; - struct blob_attr *tb[1]; - static const struct blobmsg_policy bk_attr[1] = { - [0] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING }, - }; - - blob_buf_init(&bk, 0); - - if (!blobmsg_add_json_from_file(&bk, MAP_UPLINK_PATH)) { - fprintf(stderr, "Failed to parse %s\n", MAP_UPLINK_PATH); - goto out; - } - blobmsg_parse(bk_attr, 1, tb, blob_data(bk.head), blob_len(bk.head)); - - if (!tb[0]) - goto out; - - strncpy(ifname, blobmsg_data(tb[0]), 15); - ifname[15] = '\0'; - - blob_buf_free(&bk); - return ifname; -out: - blob_buf_free(&bk); - return NULL; -} - -static int handle_autoconfig_response(const char *ifname, uint8_t *src, - uint8_t *from, uint16_t mid, - struct cmdu_buff *rxdata, size_t rxlen, - void *priv, void *cookie) +int dbh_handle_autoconfig_response(struct dynbh_ctx *priv, char *ifname, + uint16_t mid, struct tlv *tv[][TLV_MAXNUM]) { - struct dynbh_ctx *p = (struct dynbh_ctx *) priv; + struct agent *a = container_of(priv, struct agent, priv); char almac_str[18] = {0}; struct ethport *port; - struct tlv_policy a_policy[] = { - [0] = { - .type = TLV_TYPE_SUPPORTED_ROLE, - .present = TLV_PRESENT_ONE - }, - [1] = { - .type = MAP_TLV_SUPPORTED_SERVICE, - .present = TLV_PRESENT_OPTIONAL_ONE - }, - [2] = { - .type = MAP_TLV_MULTIAP_PROFILE, - .present = TLV_PRESENT_ONE - }, - [3] = { - .type = TLV_TYPE_SUPPORTED_FREQ_BAND, - .present = TLV_PRESENT_ONE - } - }; - struct tlv *tv[4][TLV_MAXNUM] = {0}; bool has_cntlr = false; int timeout = HEARTBEAT_PROBE_TIMEOUT; - int ret; - - fprintf(stderr, "mapclient: %s ===>\n", __func__); - - ret = cmdu_parse_tlvs(rxdata, tv, a_policy, 4); - if (ret) { - fprintf(stderr, "%s: parse_tlv failed\n", __func__); - return -1; - } - if (!tv[0][0] || !tv[1][0] || !tv[2][0] || !tv[3][0]) { - fprintf(stderr, "malformed data %d %d %d %d\n", !!tv[0][0], !!tv[1][0], !!tv[2][0], !!tv[3][0]); - return -1; - } + err("mapclient: %s ===>\n", __func__); if (tv[1][0]->data[0] > 0) { int i; @@ -539,36 +527,33 @@ static int handle_autoconfig_response(const char *ifname, uint8_t *src, } } if (!has_cntlr) { - fprintf(stderr, "Response did not support controller!\n"); + err("Response did not support controller!\n"); return -1; } - port = ethport_by_mid(p, mid); + port = ethport_by_mid(priv, mid); if (!port) { - fprintf(stderr, "No matching mid found\n"); + err("No matching mid found\n"); - port = ethport_by_ifname(p, ifname); + port = ethport_by_ifname(priv, ifname); if (!port) { - fprintf(stderr, "No interface matching %s found - no action\n", ifname); + err("No interface matching %s found - no action\n", ifname); return -1; } else if (port->active_uplink || port->loop) { - fprintf(stderr, "Interface %s already known to be connected to a controller - no action\n", ifname); + err("Interface %s already known to be connected to a controller - no action\n", ifname); goto out; } else { - fprintf(stderr, "Interface %s is not known to have a controller\n", ifname); + err("Interface %s is not known to have a controller\n", ifname); } } - memcpy(port->backhaul_mac, src, 6); - memcpy(port->backhaul_device_id, from, 6); - - if (!is_backhaul_type_eth()) { + if (!agent_is_backhaul_type_eth()) { /* if there is no active eth backhaul use this link as backhaul */ port->active_uplink = true; port->loop = false; link_up(port); - fprintf(stderr, "|%s:%d| Interface %s is active uplink\n", __func__, __LINE__, port->ifname); + err("|%s:%d| Interface %s is active uplink\n", __func__, __LINE__, port->ifname); addif(port); #ifdef PERSIST_CONTROLLER if (port->ctx->discovery_mode == DYNAMIC_CNTLR_MODE_AUTO) { @@ -580,23 +565,24 @@ static int handle_autoconfig_response(const char *ifname, uint8_t *src, } else if (port->active_uplink) { char ul_ifname[16] = {0}; - if (agent_get_backhaul_ifname(ul_ifname)) { + if (agent_get_backhaul_ifname(a, ul_ifname)) { if (strncmp(ul_ifname, port->ifname, 16)) link_up(port); } else link_up(port); - fprintf(stderr, "|%s:%d| Interface %s is already known as active uplink\n", __func__, __LINE__, port->ifname); + err("|%s:%d| Interface %s is already known as active uplink\n", __func__, __LINE__, port->ifname); goto out; } - fprintf(stderr, "|%s:%d| active controller (%s) found for iface:%s mid:%d, keep out of bridge\n", + err("|%s:%d| active controller (%s) found for iface:%s mid:%d, keep out of bridge\n", __func__, __LINE__, almac_str, port->ifname, mid); if (if_isbridge_interface(port->ifname)) - runCmd("/lib/wifi/dynbhd/api bridge_delif %s", port->ifname); /* add back to bridge */ + bridge_delif(priv, port); - runCmd("ubus call ieee1905 del_interface '{\"ifname\":\"%s\"}'", port->ifname); + //runCmd("ubus call ieee1905 del_interface '{\"ifname\":\"%s\"}'", port->ifname); + i1905_delif(port->ctx, port); port->loop = true; out: @@ -608,57 +594,14 @@ out: return 0; } -static int handle_autoconfig_search(const char *ifname, uint8_t *src, - uint8_t *from, uint16_t mid, - struct cmdu_buff *rxdata, size_t rxlen, - void *priv, void *cookie) +int dbh_handle_autoconfig_search(struct dynbh_ctx *priv, char *ifname, uint16_t mid, struct tlv *tv[][TLV_MAXNUM]) { - struct dynbh_ctx *p = (struct dynbh_ctx *) priv; - char almac_str[18] = {0}; + struct agent *a = container_of(priv, struct agent, priv); struct ethport *port; - struct tlv_policy a_policy[] = { - [0] = { .type = TLV_TYPE_AL_MAC_ADDRESS_TYPE, - .present = TLV_PRESENT_ONE, - .len = 6, /* macaddr */ - }, - [1] = { .type = TLV_TYPE_SEARCHED_ROLE, - .present = TLV_PRESENT_ONE, - .len = 1, /* tlv_searched_role */ - }, - [2] = { .type = TLV_TYPE_AUTOCONFIG_FREQ_BAND, - .present = TLV_PRESENT_ONE, - .len = 1, /* tlv_autoconfig_band */ - }, - [3] = { .type = MAP_TLV_SUPPORTED_SERVICE, - .present = TLV_PRESENT_OPTIONAL_ONE, - .minlen = 1, /* num of services */ - }, - [4] = { .type = MAP_TLV_SEARCHED_SERVICE, - .present = TLV_PRESENT_OPTIONAL_ONE, - .minlen = 1, /* num of services */ - }, - [5] = { .type = MAP_TLV_MULTIAP_PROFILE, - .present = TLV_PRESENT_ONE, - .len = 1, /* tlv_map_profile */ - }, - }; - struct tlv *tv[6][TLV_MAXNUM] = {0}; bool has_cntlr = false; int timeout = HEARTBEAT_PROBE_TIMEOUT; - int ret; - - fprintf(stderr, "mapclient: %s ===>\n", __func__); - - ret = cmdu_parse_tlvs(rxdata, tv, a_policy, 6); - if (ret) { - fprintf(stderr, "%s: parse_tlv failed\n", __func__); - return -1; - } - if (!tv[0][0] || !tv[1][0] || !tv[2][0] || !tv[5][0]) { - fprintf(stderr, "malformed data %d %d %d %d\n", !!tv[0][0], !!tv[1][0], !!tv[2][0], !!tv[3][0]); - return -1; - } + err("mapclient: %s ===>\n", __func__); if (tv[3][0]->data[0] > 0) { int i; @@ -672,31 +615,29 @@ static int handle_autoconfig_search(const char *ifname, uint8_t *src, } } if (!has_cntlr) { - fprintf(stderr, "Search did not support controller!\n"); + err("Search did not support controller!\n"); return -1; } - port = ethport_by_ifname(p, ifname); + port = ethport_by_ifname(priv, ifname); if (!port) { - fprintf(stderr, "No interface matching %s found - no action\n", ifname); + err("No interface matching %s found - no action\n", ifname); return -1; } else if (port->active_uplink || port->loop) { - fprintf(stderr, "Interface %s already known to be connected to a controller - no action\n", ifname); - return -1; + err("Interface %s already known to be connected to a controller - no action\n", ifname); + goto out; } else { - fprintf(stderr, "Interface %s is not known to have a controller\n", ifname); + err("Interface %s is not known to have a controller\n", ifname); } - memcpy(port->backhaul_mac, src, 6); - memcpy(port->backhaul_device_id, from, 6); - if (!is_backhaul_type_eth()) { + if (!agent_is_backhaul_type_eth()) { /* if there is no active eth backhaul use this link as backhaul */ port->active_uplink = true; port->loop = false; link_up(port); - fprintf(stderr, "|%s:%d| Interface %s is active uplink\n", __func__, __LINE__, port->ifname); + err("|%s:%d| Interface %s is active uplink\n", __func__, __LINE__, port->ifname); addif(port); #ifdef PERSIST_CONTROLLER if (port->ctx->discovery_mode == DYNAMIC_CNTLR_MODE_AUTO) { @@ -708,23 +649,24 @@ static int handle_autoconfig_search(const char *ifname, uint8_t *src, } else if (port->active_uplink) { char ul_ifname[16] = {0}; - if (agent_get_backhaul_ifname(ul_ifname)) { + if (agent_get_backhaul_ifname(a, ul_ifname)) { if (strncmp(ul_ifname, port->ifname, 16)) link_up(port); } else link_up(port); - fprintf(stderr, "|%s:%d| Interface %s is already known as active uplink\n", __func__, __LINE__, port->ifname); + err("|%s:%d| Interface %s is already known as active uplink\n", __func__, __LINE__, port->ifname); goto out; } - fprintf(stderr, "|%s:%d| active controller (%s) found for iface:%s mid:%d, keep out of bridge\n", - __func__, __LINE__, almac_str, port->ifname, mid); + //err("|%s:%d| active controller (%s) found for iface:%s mid:%d, keep out of bridge\n", + // __func__, __LINE__, almac_str, port->ifname, mid); if (if_isbridge_interface(port->ifname)) - runCmd("/lib/wifi/dynbhd/api bridge_delif %s", port->ifname); /* add back to bridge */ + bridge_delif(priv, port); - runCmd("ubus call ieee1905 del_interface '{\"ifname\":\"%s\"}'", port->ifname); + //runCmd("ubus call ieee1905 del_interface '{\"ifname\":\"%s\"}'", port->ifname); + i1905_delif(port->ctx, port); port->loop = true; out: @@ -736,211 +678,16 @@ out: return 0; } +#if 0 static int handle_1905_ack(const char *ifname, uint8_t *src, uint8_t *from, uint16_t mid, struct cmdu_buff *rxdata, size_t rxlen, void *priv, void *cookie) { - fprintf(stderr, "mapclient: %s ===>\n", __func__); + err("mapclient: %s ===>\n", __func__); return 0; } - -typedef int (*cmdu_handler_t)(const char *ifname, uint8_t *src, uint8_t *from, - uint16_t mid, struct cmdu_buff *rxdata, - size_t rxlen, void *priv, void *cookie); - - -static const cmdu_handler_t i1905ftable[] = { - [0x00] = NULL, - [0x01] = NULL, - [0x02] = NULL, - [0x03] = NULL, - [0x04] = NULL, - [0x05] = NULL, - [0x06] = NULL, - [0x07] = handle_autoconfig_search, - [0x08] = handle_autoconfig_response, - [0x09] = NULL, - [0x0a] = NULL, -}; - -#define CMDU_TYPE_MAP_START 0x8000 -#define CMDU_TYPE_MAP_END 0x8001 - -static const cmdu_handler_t mapclient_ftable[] = { - [0x00] = handle_1905_ack, -}; - - -static int mapclient_handle_cmdu_notification(struct blob_attr *msg, struct dynbh_ctx *priv) -{ - static const struct blobmsg_policy cmdu_attrs[6] = { - [0] = { .name = "type", .type = BLOBMSG_TYPE_INT16 }, - [1] = { .name = "mid", .type = BLOBMSG_TYPE_INT16 }, - [2] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING }, - [3] = { .name = "source", .type = BLOBMSG_TYPE_STRING }, - [4] = { .name = "origin", .type = BLOBMSG_TYPE_STRING }, - [5] = { .name = "cmdu", .type = BLOBMSG_TYPE_STRING }, - }; - char in_ifname[16] = {0}; - struct blob_attr *tb[6]; - char src[18] = { 0 }, src_origin[18] = { 0 }; - uint8_t *tlv = NULL; - char *tlvstr = NULL; - uint16_t type; - uint8_t srcmac[6], origin[6]; - uint16_t mid = 0; - int len = 0; - struct cmdu_buff *cmdu; - int ret = 0; - int idx; - const cmdu_handler_t *f; - - blobmsg_parse(cmdu_attrs, 6, tb, blob_data(msg), blob_len(msg)); - - if (!tb[0] || !tb[1]) - return -1; - - if (tb[0]) { - int t; - - t = blobmsg_get_u16(tb[0]); - if (t < 0) - return -1; - - type = (uint16_t)t; - } - - if (tb[1]) - mid = (uint16_t)blobmsg_get_u16(tb[1]); - - - if (tb[2]) - strncpy(in_ifname, blobmsg_data(tb[2]), 15); - - if (tb[3]) { - strncpy(src, blobmsg_data(tb[3]), 17); - hwaddr_aton(src, srcmac); - } - - if (tb[4]) { - strncpy(src_origin, blobmsg_data(tb[4]), 17); - hwaddr_aton(src_origin, origin); - } - - - if (tb[5]) { - len = blobmsg_data_len(tb[5]) - 16; - - tlvstr = calloc(1, len + 1); - - if (!tlvstr) - return -1; - - strncpy(tlvstr, (blobmsg_data(tb[5]) + 16), len); - len = (len - 1) / 2; - tlv = calloc(1, len); - if (!tlv) { - free(tlvstr); - return -1; - } - - strtob(tlvstr, len, tlv); - free(tlvstr); - } - - cmdu = cmdu_alloc_custom(type, &mid, in_ifname, srcmac, tlv, len); - if (!cmdu) { - fprintf(stderr, "%s: cmdu_alloc_custom() failed!\n", __func__); - if (tlv) - free(tlv); - return -1; - } - memcpy(cmdu->origin, origin, 6); - fprintf(stderr, "%s: cmdu_alloc_custom() succeeded! cmdu->cdata->hdr.mid %u\n", __func__, cmdu_get_mid(cmdu)); - - - if (type >= CMDU_TYPE_MAP_START) { - idx = type - CMDU_TYPE_MAP_START; - f = mapclient_ftable; - if (ARRAY_SIZE(mapclient_ftable) < idx) - goto error; - } else { - idx = type; - f = i1905ftable; - if (ARRAY_SIZE(i1905ftable) < idx) - goto error; - } - - if (f[idx]) { - ret = f[idx](in_ifname, srcmac, origin, mid, cmdu, len, priv, NULL); - } - - - -error: - if (tlv) - free(tlv); - cmdu_free(cmdu); - return ret; -} - -int dynbh_map_sub_cb(void *bus, void *priv, void *data) -{ - struct blob_attr *msg = (struct blob_attr *)data; - char *str; - - - str = blobmsg_format_json(msg, true); - fprintf(stderr, "Received notification '%s'\n", str); - free(str); - - mapclient_handle_cmdu_notification(msg, priv); - - return 0; -} - -int dynbh_map_del_cb(void *bus, void *priv, void *data) -{ - uint32_t *obj = (uint32_t *)data; - - fprintf(stderr, "Object 0x%x no longer present\n", *obj); - return 0; -} - -static int dynbh_subscribe_for_cmdus(struct dynbh_ctx *priv) -{ - mapmodule_cmdu_mask_t cmdu_mask = {0}; - int ret; - uint32_t map_id; - - - map_prepare_cmdu_mask(cmdu_mask, - CMDU_TYPE_AP_AUTOCONFIGURATION_SEARCH, - CMDU_TYPE_AP_AUTOCONFIGURATION_RESPONSE, - -1); - - ret = ubus_lookup_id(priv->ctx, map_plugin, &map_id); - if (ret) { - fprintf(stderr, "%s: %s\n", map_plugin, ubus_strerror(ret)); - return -1; - } - - priv->map_oid = map_id; - ret = map_subscribe(priv->ctx, - &priv->map_oid, - "dynbhd", &cmdu_mask, priv, - dynbh_map_sub_cb, - dynbh_map_del_cb, - &priv->subscriber); - if (ret) { - fprintf(stderr, "dynbh: Failed to 'register' with %s (err = %s)\n", - map_plugin, ubus_strerror(ret)); - } - - return ret; -} - +#endif void remove_newline(char *buf) { int len; @@ -984,7 +731,6 @@ static int dynbhd_status(struct ubus_context *ctx, struct ubus_object *obj, } - int cntlr_publish_object(struct dynbh_ctx *c, const char *objname) { struct ubus_object *obj; @@ -1019,20 +765,21 @@ int cntlr_publish_object(struct dynbh_ctx *c, const char *objname) obj_type->methods = obj->methods; obj->type = obj_type; - ret = ubus_add_object(c->ctx, obj); + ret = ubus_add_object(c->ubus_ctx, obj); if (ret) { - fprintf(stderr, "Failed to add '%s' err = %s\n", + err("Failed to add '%s' err = %s\n", objname, ubus_strerror(ret)); free(obj_methods); free(obj_type); return ret; } - fprintf(stderr, "Published '%s' object\n", objname); + err("Published '%s' object\n", objname); return 0; } +#if 0 int main(int argc, char **argv) { const char *ubus_socket = NULL; @@ -1063,7 +810,7 @@ int main(int argc, char **argv) uloop_init(); priv->ctx = ubus_connect(ubus_socket); if (!priv->ctx) { - fprintf(stderr, "Failed to connect to ubus\n"); + err("Failed to connect to ubus\n"); free(priv); return -1; } @@ -1100,3 +847,5 @@ int main(int argc, char **argv) return 0; } +#endif +#endif diff --git a/src/dynbh/dynbh.h b/src/dynbh/dynbh.h index 68b14ed12459d9e12435cc36ea956e113c3b14b2..1d381aaa598d43a6868d4d87b8e622941ae50db4 100644 --- a/src/dynbh/dynbh.h +++ b/src/dynbh/dynbh.h @@ -1,8 +1,10 @@ +#ifdef DYNBH #ifndef DYNBH_H #define DYNBH_H #include <libubox/list.h> #include <libubus.h> +#include <cmdu.h> #include <stdbool.h> #include <stdint.h> #include <timer_impl.h> @@ -19,12 +21,11 @@ enum cntlr_discovery_mode { struct ethport { + char ifname[16]; + uint8_t macaddr[6]; bool connected; bool loop; bool active_uplink; - char ifname[16]; - uint8_t backhaul_mac[6]; - uint8_t backhaul_device_id[6]; uint8_t num_mid; uint16_t mid[32]; atimer_t bridge_add; @@ -37,14 +38,9 @@ struct ethport { }; struct dynbh_ctx { - char alidstr[16]; /* 6 octet macaddr without separators */ + uint8_t almac[6]; char al_bridge[16]; - uint16_t cmdu_mask; - struct ubus_context *ctx; - uint32_t oid; - uint32_t map_oid; - void *subscriber; - struct ubus_event_handler evh; + struct ubus_context *ubus_ctx; int queued_searches; struct list_head ethportlist; /* */ atimer_t heartbeat; @@ -55,10 +51,11 @@ struct dynbh_ctx { }; -void delif(struct ethport *port); +void delif(struct dynbh_ctx *priv, struct ethport *port); void addif(struct ethport *port); - +struct ethport *alloc_ethport_search(struct dynbh_ctx *priv, + char *ifname); struct ethport *ethport_by_ifname(struct dynbh_ctx *p, const char *ifname); struct ethport *ethport_by_mid(struct dynbh_ctx *p, uint16_t mid); @@ -68,4 +65,9 @@ void dynbh_handle_port_down(struct dynbh_ctx *priv, struct ethport *port); void free_ethport_search(struct ethport *port); +int dbh_handle_autoconfig_response(struct dynbh_ctx *priv, char *ifname, + uint16_t mid, struct tlv *tv[][TLV_MAXNUM]); +int dbh_handle_autoconfig_search(struct dynbh_ctx *priv, char *ifname, uint16_t mid, struct tlv *tv[][TLV_MAXNUM]); + +#endif #endif diff --git a/src/nl.h b/src/nl.h index 800b5dc1785ac18132e3ca4d0c091d80db36fdf3..92568327b334e64305d31908333ab46cce13524f 100644 --- a/src/nl.h +++ b/src/nl.h @@ -8,7 +8,6 @@ #include <easy/utils.h> #include <easy/if_utils.h> #include <linux/if_bridge.h> -#include <net/if.h> #include <stdbool.h> #include <stdint.h> #include <wifidefs.h> @@ -17,7 +16,7 @@ struct agent; struct nl_sock; struct ts_iface { - char name[IFNAMSIZ]; + char name[16]; uint16_t vid; int ifi_index; struct bridge_vlan_info cur_vinfo[MAX_VIDS]; diff --git a/src/utils/1905_ubus.c b/src/utils/1905_ubus.c index 31604b597762ff35ef1b82aeb17b60e6b49e2850..e3b6d70739e4a564ee3338dcfe13a5a965d23b69 100644 --- a/src/utils/1905_ubus.c +++ b/src/utils/1905_ubus.c @@ -231,9 +231,9 @@ out: return -1; } -int ieee1905_ubus_send_cmdu(struct ubus_context *ubus_ctx, - struct cmdu_buff *cmdu, uint16_t *msgid, - uint16_t vid) +static int ieee1905_send_cmdu(struct ubus_context *ubus_ctx, + struct cmdu_buff *cmdu, char *objname, + uint16_t *msgid, uint16_t vid) { struct blob_buf bb = {}; char dst_addr[18] = {}; @@ -244,7 +244,7 @@ int ieee1905_ubus_send_cmdu(struct ubus_context *ubus_ctx, }; int ret = 0; - ret = ubus_lookup_id(ubus_ctx, "ieee1905", &id); + ret = ubus_lookup_id(ubus_ctx, objname, &id); if (ret != UBUS_STATUS_OK) return -1; @@ -264,7 +264,7 @@ int ieee1905_ubus_send_cmdu(struct ubus_context *ubus_ctx, if (vid) blobmsg_add_u32(&bb, "vid", (uint32_t)vid); - trace("|%s:%d|cmdu:0x%04x|dst:%s|mid:%u|datalen:%u|ifname:%s|vid:%u\n", + err("|%s:%d|cmdu:0x%04x|dst:%s|mid:%u|datalen:%u|ifname:%s|vid:%u\n", __func__, __LINE__, cmdu_get_type(cmdu), dst_addr, cmdu_get_mid(cmdu), cmdu->datalen, cmdu->dev_ifname, vid); if (cmdu->datalen) { @@ -283,7 +283,7 @@ int ieee1905_ubus_send_cmdu(struct ubus_context *ubus_ctx, tlv_str[len-1] = '\0'; blobmsg_add_string(&bb, "data", tlv_str); - trace("|%s:%d|data:%s|\n", __func__, __LINE__, tlv_str); + err("|%s:%d|data:%s|\n", __func__, __LINE__, tlv_str); free(tlv_str); } @@ -294,20 +294,38 @@ int ieee1905_ubus_send_cmdu(struct ubus_context *ubus_ctx, ret = ctx.status; if (ret) { - trace("[%s:%d] ubus call failed for |ieee1905 send| rc: %d\n", + err("[%s:%d] ubus call failed for |ieee1905 send| rc: %d\n", __func__, __LINE__, ret); goto out; } *msgid = ctx.mid; - trace("|%s:%d| msgid = %d\n", __func__, __LINE__, *msgid); + err("|%s:%d| msgid = %d\n", __func__, __LINE__, *msgid); out: blob_buf_free(&bb); - trace("%s ret %d\n", __func__, ret); + err("%s ret %d\n", __func__, ret); return ret; } +/* send CMDU using an ieee1905.al.X object */ +int ieee1905_ubus_send_al_cmdu(struct ubus_context *ubus_ctx, + struct cmdu_buff *cmdu, uint16_t *msgid, + char *ifname, uint16_t vid) +{ + char objname[32] = {0}; + + snprintf(objname, 31, "ieee1905.al.%s", ifname); + return ieee1905_send_cmdu(ubus_ctx, cmdu, objname, msgid, vid); +} + +int ieee1905_ubus_send_cmdu(struct ubus_context *ubus_ctx, + struct cmdu_buff *cmdu, uint16_t *msgid, + uint16_t vid) +{ + return ieee1905_send_cmdu(ubus_ctx, cmdu, "ieee1905", msgid, vid); +} + int ieee1905_ubus_set_vid(struct ubus_context *ubus_ctx, uint16_t vid) { diff --git a/src/utils/1905_ubus.h b/src/utils/1905_ubus.h index 885432ac5a94d91e20f941bf783b59122e50519f..a2ae1ff28e5b8d60693c9e7acaecdfe2772ca857 100644 --- a/src/utils/1905_ubus.h +++ b/src/utils/1905_ubus.h @@ -16,6 +16,9 @@ struct ubus_context; struct cmdu_buff *ieee1905_ubus_buildcmdu(struct ubus_context *ubus_ctx, uint16_t msg_type, char *ifname); int ieee1905_ubus_send_frag_scheme(struct ubus_context *ubus_ctx, uint8_t *origin, int frag_scheme); +int ieee1905_ubus_send_al_cmdu(struct ubus_context *ubus_ctx, + struct cmdu_buff *cmdu, uint16_t *msgid, + char *ifname, uint16_t vid); int ieee1905_ubus_send_cmdu(struct ubus_context *ubus_ctx, struct cmdu_buff *cmdu, uint16_t *msgid, uint16_t vid);