diff --git a/src/core/agent.c b/src/core/agent.c index 3112e5cbf40d769afb5a24248913f3607d9710e0..e5573888a3938d901398fcee213ac83ce22da5cd 100644 --- a/src/core/agent.c +++ b/src/core/agent.c @@ -70,15 +70,48 @@ static int signal_pending; static void bsta_steer_cb(struct uloop_timeout *t) { + struct tlv_policy a_policy[] = { + [0] = { + .type = MAP_TLV_BACKHAUL_STEERING_RESPONSE, + .present = TLV_PRESENT_ONE + } + }; + struct tlv_backhaul_steer_resp *p; + struct cmdu_buff *cmdu; + struct tlv *tv[1][16] = {0}; + int ret = -1; struct netif_bk *bk = container_of(t, struct netif_bk, connect_timer); uint8_t *bssid = NULL; + struct agent *a = bk->agent; dbg("|%s:%d| steer timer expired, restoring old bssid (" MACFMT ") for"\ "bsta %s\n", __func__, __LINE__, MAC2STR(bk->bsta_steer.prev_bssid), bk->name); + cmdu = bk->bsta_steer.cmdu; + wifi_set_iface_bssid(bk, bk->bsta_steer.prev_bssid); + + cmdu_parse_tlvs(cmdu, tv, a_policy, 1); + + if (!tv[0][0]) + goto out; + + p = (struct tlv_backhaul_steer_resp *) tv[0][0]; + if (!p) + goto out; + + p->result = 0x01; + if (!agent_gen_tlv_error_code(a, tv[0][0], NULL, 0x05)) + goto out; + + ret = !agent_send_cmdu(a, cmdu); +out: + cmdu_free(cmdu); + bk->bsta_steer.cmdu = NULL; + return ret; + } static void agent_terminate(void) @@ -2214,7 +2247,7 @@ int send_bsta_steer_resp(struct agent *a, struct cmdu_buff *cmdu, if (!tv[0][0]) goto out; - p = (struct tlv_backhaul_steer_resp *) tv[0][0]; + p = (struct tlv_backhaul_steer_resp *) tv[0][0]->data; if (!p) goto out; @@ -2226,6 +2259,20 @@ int send_bsta_steer_resp(struct agent *a, struct cmdu_buff *cmdu, uloop_timeout_cancel(&bk->connect_timer); ret = !agent_send_cmdu(a, cmdu); + + trace("\n\n%s %d bssid = " MACFMT ", target = " MACFMT "\n", __func__, __LINE__, MAC2STR(bssid), MAC2STR(p->target_bssid)); + + /* if steer was successful - write to config */ + if (p->result == 0x00) { + char fmt[64] = {0}; + + trace("%s %d " MACFMT "\n", __func__, __LINE__, MAC2STR(p->target_bssid)); + + wifi_set_iface_bssid(bk, bssid); + snprintf(fmt, sizeof(fmt), "write_bsta_config %s", bk->name); + agent_exec_platform_scripts(fmt); + trace("%s %d\n", __func__, __LINE__); + } out: cmdu_free(cmdu); bk->bsta_steer.cmdu = NULL; @@ -2321,48 +2368,6 @@ static void wifi_bsta_event_handler(void *agent, struct blob_attr *msg) bk->connected = false; wifi_mod_bridge(a, ifname, "remove"); } - - - -// p = (struct tlv_backhaul_steer_resp *) extract_tlv_by_type(cmdu, -// MAP_TLV_BACKHAUL_STEERING_RESPONSE); -// if (!p) -// goto fail_cmdu; -// -// /** -// * if event bssid and tlv target bssid differ, that means steering -// * failed, add an error TLV prior to sending response -// */ -// //TODO: move to if(add)? -// if (memcmp(bssid, p->bssid, 6)) { -// struct tlv_error_code *p1; -// uint8_t **tlvs; -// -// p->res_code = 0x01; -// p1 = (struct tlv_error_code *) calloc(1, -// sizeof(struct tlv_error_code)); -// if (!p1) -// goto fail_cmdu; -// -// p1->tlv_type = MAP_TLV_ERROR_CODE; -// p1->reason_code = 0x05; -// -// cmdu->num_tlvs++; -// -// tlvs = (uint8_t **)realloc(cmdu->tlvs, -// cmdu->num_tlvs * sizeof(uint8_t *)); -// if (!tlvs) { -// free(p1); -// goto fail_cmdu; -// } -// cmdu->tlvs = tlvs; -// cmdu->tlvs[cmdu->num_tlvs - 1] = (uint8_t *) p1; -// } -// -// uloop_timeout_cancel(&bk->connect_timer); -// agent_send_cmdu(a, cmdu); -//fail_cmdu: - } static void wifi_wps_creds_event_handler(void *c, struct blob_attr *msg) diff --git a/src/core/agent_cmdu_generator.c b/src/core/agent_cmdu_generator.c index cb2d25bfad58e9cd39cbb18dec736f35501d80ee..b1bfbf1f74a0032eed8bcc4e79320387fb4824b6 100644 --- a/src/core/agent_cmdu_generator.c +++ b/src/core/agent_cmdu_generator.c @@ -1110,9 +1110,8 @@ int agent_gen_cmdu_backhaul_steer_resp(struct agent *a, uint8_t *target_bssid, u if (ret) goto out; - cmdu_put_eom(frm); - cmdu_set_mid(frm, mid); + return frm; out: cmdu_free(frm); diff --git a/src/core/agent_map.c b/src/core/agent_map.c index 4601500699f3cd27154e614d3c5d73bf38c95dd8..53bf836e11aedc81b309b961149c16c81939c960 100644 --- a/src/core/agent_map.c +++ b/src/core/agent_map.c @@ -3162,6 +3162,7 @@ int handle_backhaul_sta_steer_request(void *agent, int ret = 0, num = 0, i; struct netif_bk *bk; struct cmdu_buff *cmdu; + char fmt[128] = {0}; ret = cmdu_parse_tlvs(rx_cmdu, tv, a_policy, 1); @@ -3186,8 +3187,15 @@ int handle_backhaul_sta_steer_request(void *agent, wifi_get_iface_bssid(bk->name, bk->bsta_steer.prev_bssid); - wifi_set_iface_bssid(bk, req->target_bssid); - uloop_timeout_set(&bk->connect_timer, 20 * 1000); /* TODO: why the long timeout */ + snprintf(fmt, sizeof(fmt), "bsta_steer %s " MACFMT " %u", bk->name, + MAC2STR(req->target_bssid), req->target_channel); + + trace("fmt = %s\n", fmt); + + agent_exec_platform_scripts(fmt); + + //wifi_set_iface_bssid(bk, req->target_bssid); + uloop_timeout_set(&bk->connect_timer, 10 * 1000); /* TODO: why the long timeout */ memcpy(cmdu->origin, rx_cmdu->origin, 6); return 0; diff --git a/src/core/agent_tlv_generator.c b/src/core/agent_tlv_generator.c index 8316d405cbfe3574bd285de2ee336c242b73e81e..e6f3aa11e6ea1bb511f686f116c6bf435d7b8932 100644 --- a/src/core/agent_tlv_generator.c +++ b/src/core/agent_tlv_generator.c @@ -824,19 +824,6 @@ int agent_gen_tlv_error_code(struct agent *a, } return 0; -// struct tlv_error_code *p; -// -// p = (struct tlv_error_code *)calloc(1, -// sizeof(struct tlv_error_code)); -// -// if (!p) -// return NULL; -// -// p->tlv_type = MAP_TLV_ERROR_CODE; -// p->reason_code = reason_code; -// memcpy(p->addr, sta_mac, 6); -// -// return p; } int agent_gen_al_mac(struct agent *a, struct cmdu_buff *frm, uint8_t *hwaddr) @@ -2801,7 +2788,7 @@ int agent_gen_tlv_backhaul_steer_resp(struct agent *a, struct cmdu_buff *frm, uint8_t *target_bssid, uint8_t *macaddr) { struct tlv *t; - struct tlv_backhaul_steer_resp *resp; + struct tlv_backhaul_steer_resp *data; int ret; t = cmdu_reserve_tlv(frm, 256); @@ -2810,11 +2797,11 @@ int agent_gen_tlv_backhaul_steer_resp(struct agent *a, struct cmdu_buff *frm, t->type = MAP_TLV_BACKHAUL_STEERING_RESPONSE; t->len = 13; - resp = (struct tlv_backhaul_steer_resp *) t->data; + data = (struct tlv_backhaul_steer_resp *) t->data; - memcpy(resp->target_bssid, target_bssid, 6); - memcpy(resp->macaddr, macaddr, 6); - resp->result = 0x0; /* default success */ + memcpy(data->target_bssid, target_bssid, 6); + memcpy(data->macaddr, macaddr, 6); + data->result = 0x0; /* default success */ ret = cmdu_put_tlv(frm, t); if (ret) { diff --git a/src/core/config.c b/src/core/config.c index 3207b929fa969d00ec98343a24f5af2a01545f31..c117e2c7066b578b9862bbf26c084339b79fbc10 100644 --- a/src/core/config.c +++ b/src/core/config.c @@ -212,6 +212,7 @@ char *uci_get_bridge(char *ifname, char *bridge) return bridge; } +#if 0 int wifi_get_iface_bssid(char *ifname, uint8_t *bssid) { struct uci_context *ctx = NULL; @@ -247,14 +248,85 @@ out_pkg: uci_free_context(ctx); return ret; } +#endif + +int wifi_get_iface_bssid(char *ifname, uint8_t *bssid) +{ + struct uci_context *ctx = NULL; + struct uci_package *pkg; + struct uci_section *section; + struct uci_ptr ptr = {0}; + int ret = -1; + + if (!bssid) + return ret; + + pkg = uci_load_pkg(&ctx, "mapagent"); + if (!pkg) + return ret; + + section = config_get_section(ctx, pkg, "bk-iface", "ifname", ifname); + if (!section) + goto out_pkg; + + ptr.p = pkg; + ptr.s = section; + ptr.option = "bssid"; + ptr.target = UCI_TYPE_OPTION; + + ret = uci_lookup_ptr(ctx, &ptr, NULL, false); + if (!ret && ptr.o) + hwaddr_aton(ptr.o->v.string, bssid); + else + memset(bssid, 0, 6); + +out_pkg: + uci_unload(ctx, pkg); + uci_free_context(ctx); + return ret; +} + + +int wifi_set_iface_bssid(struct netif_bk *bk, uint8_t *bssid) +{ + struct uci_context *ctx = NULL; + struct uci_package *pkg; + struct uci_section *section; + struct uci_ptr ptr = {0}; + char bssid_str[18] = {0}; + int ret = -1; + + pkg = uci_load_pkg(&ctx, "mapagent"); + if (!pkg) + return ret; + + section = config_get_section(ctx, pkg, "bk-iface", "ifname", bk->name); + if (!section) + goto out_pkg; + if (bssid && !hwaddr_is_zero(bssid)) + hwaddr_ntoa(bssid, bssid_str); + + dbg("|%s:%d| setting bssid to %s\n", bssid_str); + + ret = set_value(ctx, pkg, section, "bssid", bssid_str, UCI_TYPE_STRING); + + uci_commit(ctx, &pkg, false); +out_pkg: + uci_unload(ctx, pkg); + uci_free_context(ctx); + return ret; +} + +#if 0 /* strive to not touch /etc/config/wireless */ /* TODO: can it be generalized? */ int wifi_set_iface_bssid(struct netif_bk *bk, uint8_t *bssid) { struct uci_context *ctx = NULL; struct uci_package *pkg; struct uci_section *section; + struct uci_ptr ptr = {0}; char bssid_str[18] = {0}; int ret = -1; @@ -281,6 +353,7 @@ out_pkg: uci_free_context(ctx); return ret; } +#endif int config_del_iface(const char *config, const char *type, const char *ifname) {