diff --git a/src/agent.c b/src/agent.c index df3d6e7e197fe7f14c8a93ca0fd3eb4500c802cf..a3ac92505890b8daba1fd5a6418a4a566a65ff6a 100644 --- a/src/agent.c +++ b/src/agent.c @@ -1919,7 +1919,7 @@ static void wifi_chan_change_event_handler(void *c, struct blob_attr *msg) ifname = blobmsg_data(tb[0]); event = blobmsg_data(tb[1]); - radio = wifi_radio_to_radio_element(a, ifname); + radio = wifi_ifname_to_radio_element(a, ifname); if (!radio) return; @@ -4159,7 +4159,7 @@ static void parse_radio(struct ubus_request *req, int type, [9] = { .name = "txpower", .type = BLOBMSG_TYPE_INT32 }, [10] = { .name = "macaddr", .type = BLOBMSG_TYPE_STRING }, [11] = { .name = "diagnostics", .type = BLOBMSG_TYPE_TABLE }, - [12] = { .name = "bandwidth", .type = BLOBMSG_TYPE_STRING }, + [12] = { .name = "bandwidth", .type = BLOBMSG_TYPE_INT32 }, }; struct blob_attr *tb[ARRAY_SIZE(radio_attr)]; @@ -4475,6 +4475,9 @@ void parse_scanresults(struct ubus_request *req, int type, struct blob_attr *msg static void _enumerate_wifi_objects(struct ubus_request *req, int type, struct blob_attr *msg) { + + trace("%s: --->\n", __func__); + struct agent *a = (struct agent *)req->priv; struct json_object *json_msg; struct json_object *radio_array; @@ -4497,7 +4500,12 @@ static void _enumerate_wifi_objects(struct ubus_request *req, int type, if (len > WIFI_DEVICE_MAX_NUM) len = WIFI_DEVICE_MAX_NUM; - a->num_radios = len; + trace("%s: num_radios(len) = %d\n", __func__, len); + if (len) { + agent_free_radios(a); + clear_fhlist(a); + a->num_radios = len; + } for (i = 0; i < len; i++) { struct json_object *radio_obj, *radio_obj_name; @@ -4567,6 +4575,7 @@ static void _enumerate_wifi_objects(struct ubus_request *req, int type, } // On-boot channel scan // ubus call wifi.radio.wl0 status + dbg("%s: getting radio status = radios[%d]\n", __func__, i); ubus_call_object(a, r_wobj, "status", parse_radio, &a->radios[i]); /* Get fresh opclass preferences after scan */ @@ -4591,23 +4600,30 @@ out_str: static int enumerate_wifi_objects(struct agent *a) { + trace("%s: --->\n", __func__); + struct blob_buf bb = {}; - int ret; + int ret, retry = 0; blob_buf_init(&bb, 0); while ((ret = ubus_invoke(a->ubus_ctx, a->wifi, "status", bb.head, - _enumerate_wifi_objects, a, 2 * 1000) || !a->num_radios)) { - - if (ret == UBUS_STATUS_NOT_FOUND) - a->wifi = ubus_get_object(a->ubus_ctx, "wifi"); + _enumerate_wifi_objects, a, 2 * 1000) || !a->num_radios) + && retry < 5) { - err("Failed to get wifi status(ret = %d), OR num_radios is 0 (%d) retry in 0.5s\n", ret, a->num_radios); + err("|%s:%d| Failed to get wifi status(ret = %d), OR "\ + "num_radios is 0 (%d) retry in 0.5s, wifi object:%u, "\ + "retry:%d\n", __func__, __LINE__, ret, a->num_radios, + a->wifi, retry); usleep(500 * 1000); /* 0.5s sleep */ + retry++; + a->wifi = ubus_get_object(a->ubus_ctx, "wifi"); } + trace("%s: num of retries = %d\n", __func__, retry); blob_buf_free(&bb); return 0; } + /* TODO: global visibility */ int agent_get_wifi_interfaces(struct wifi_netdev *wifi) { @@ -4991,7 +5007,8 @@ int agent_init_interfaces(struct agent *a) struct netif_bkcfg *b; wifi_object_t wifi_obj; uint32_t ieee1905_obj = 0; - int ret; + int ret, retry = 0; + ret = ubus_lookup_id(a->ubus_ctx, "ieee1905", &ieee1905_obj); if (ret) @@ -5000,14 +5017,21 @@ int agent_init_interfaces(struct agent *a) ubus_call_object(a, ieee1905_obj, "info", parse_i1905_info, a); wifi_obj = ubus_get_object(a->ubus_ctx, "wifi"); - if (wifi_obj != WIFI_OBJECT_INVALID) { - a->wifi = wifi_obj; - enumerate_wifi_objects(a); - } else { - warn("Object 'wifi' not present!\n"); + while (wifi_obj == WIFI_OBJECT_INVALID && retry < 5) { + err("|%s:%d| Failed to get wifi object (%u) retry in 0.5s, try num:%d\n", __func__, __LINE__, wifi_obj, retry); + usleep(500 * 1000); /* 0.5s sleep */ + wifi_obj = ubus_get_object(a->ubus_ctx, "wifi"); + retry++; + } + + if (wifi_obj == WIFI_OBJECT_INVALID) { + warn("|%s:%d| Object 'wifi' not present!\n", __func__, __LINE__); return -1; } + a->wifi = wifi_obj; + enumerate_wifi_objects(a); + a->connected = false; list_for_each_entry(f, &cfg->fhlist, list) { @@ -5180,10 +5204,6 @@ static void agent_init_ifaces_cb(struct uloop_timeout *t) trace("%s: --->\n", __func__); struct agent *a = container_of(t, struct agent, init_ifaces_scheduler); - /* tear down existing data */ - agent_free_radios(a); - clear_fhlist(a); - agent_init_interfaces(a); if (a->cfg.ts_enabled && a->ts.requested) @@ -5753,6 +5773,7 @@ void agent_free_radios(struct agent *a) { int i; + trace("%s: a->num_radios to free = %d\n", __func__, a->num_radios); for (i = 0; i < a->num_radios; i++) { struct wifi_radio_element *re; int j; @@ -5971,10 +5992,27 @@ int wifiagent_get_status(struct ubus_context *ctx, struct neighbor *n; struct blob_buf bb; void *a, *b, *t; + int i; memset(&bb, 0, sizeof(bb)); blob_buf_init(&bb, 0); + a = blobmsg_open_array(&bb, "radios"); + for (i = 0; i < agent->num_radios; i++) { + struct wifi_radio_element *re = &agent->radios[i]; + char macaddrstr[18] = {0}; + + hwaddr_ntoa(re->macaddr, macaddrstr); + t = blobmsg_open_table(&bb, ""); + blobmsg_add_string(&bb, "name", re->name); + blobmsg_add_string(&bb, "macaddr", macaddrstr); + blobmsg_add_u32(&bb, "channel", re->current_channel); + blobmsg_add_u32(&bb, "bandwidth", re->current_bandwidth); + blobmsg_add_u32(&bb, "opclass", re->current_opclass); + blobmsg_close_table(&bb, t); + } + blobmsg_close_array(&bb, a); + a = blobmsg_open_array(&bb, "fronthaul"); list_for_each_entry(p, &agent->fhlist, list) { struct sta *s;