From 9203246714aa04a5c8440c55ad407e1c2b0e47b8 Mon Sep 17 00:00:00 2001 From: "nevadita.chatterjee" <nevadita.chatterjee@iopsys.eu> Date: Wed, 8 Sep 2021 15:20:38 +0530 Subject: [PATCH] mapagent:init according to config preference --- src/agent.c | 49 ++++++++++++++-- src/agent.h | 7 ++- src/agent_map.c | 146 ++++++++++++++++++++++++++++++++++-------------- src/config.c | 4 +- 4 files changed, 157 insertions(+), 49 deletions(-) diff --git a/src/agent.c b/src/agent.c index 8d8347185..3fb6cbfd1 100644 --- a/src/agent.c +++ b/src/agent.c @@ -3392,10 +3392,46 @@ int agent_fill_channel_preference_default(struct wifi_radio_element *radio) } } +int agent_switch_according_to_pref(struct agent *a) +{ + uint32_t channel = 0; + uint32_t opclass = 0; + int ret = 0 , l = 0; + struct wifi_radio_element *radio; + + trace("agent: %s: --->\n", __func__); + + for (l = 0; l < a->num_radios; l++) { + radio = a->radios + l; + + ret = agent_get_highest_preference(radio, radio->current_opclass, &channel, + &opclass); + /* The operating class channel preference has been set + * now we want to switch the channel to the max preference */ + trace("agent: %s: opclass is %d channel is %d--->\n", __func__, opclass, channel); + if ((radio->current_opclass == opclass) && (radio->current_channel == channel)) + continue; + if (channel != 0 && opclass != 0 ) { + ret = agent_channel_switch(a, radio->macaddr, channel, opclass); + if (ret == -1) { + + /*Here we need to set the default preference for all the + * channels in that operating class also set the response code as rejected*/ + // agent_set_channel_preference_to_default(radio); + } + } + } + return 0; +} + + static void parse_radio(struct ubus_request *req, int type, struct blob_attr *msg) { - struct wifi_radio_element *re = (struct wifi_radio_element *)req->priv; + struct radio_tmp *re_tmp = (struct wifi_radio_element *)req->priv; + struct wifi_radio_element *re = re_tmp->r; + struct agent *a = re_tmp->a; + fprintf(stdout, "%s ---> %s\n", __func__, re->name); int rem, remm, rem1, j = 0, i = 0; struct blob_attr *tb[12]; @@ -3531,8 +3567,6 @@ static void parse_radio(struct ubus_request *req, int type, re->scanlist->opclass_scanlist[i].bandwidth = blobmsg_get_u32(data[3]); i++; } - //Add the config to preference writing here - // agent_config_opclass(re); } if (tb[6]) re->current_opclass = (uint8_t) blobmsg_get_u32(tb[6]); @@ -3721,6 +3755,8 @@ static void _enumerate_wifi_objects(struct ubus_request *req, int type, struct json_object *radio_array; char *json_str; int i, j, k, len; + struct radio_tmp *radio_tmp_param; + json_str = blobmsg_format_json(msg, true); if (!json_str) @@ -3808,7 +3844,10 @@ static void _enumerate_wifi_objects(struct ubus_request *req, int type, } // On-boot channel scan // ubus call wifi.radio.wl0 status - ubus_call_object(a, r_wobj, "status", parse_radio, &a->radios[i]); + radio_tmp_param = calloc(0, sizeof(struct radio_tmp )); + radio_tmp_param->r = &a->radios[i]; + radio_tmp_param->a = a; + ubus_call_object(a, r_wobj, "status", parse_radio, radio_tmp_param); // ubus call wifi.radio.wl0 scan //ubus_call_object(a, r_wobj, "scan", NULL, &a->radios[i]); @@ -4830,6 +4869,8 @@ int start_agent(void) agent_init_interfaces(w); + agent_switch_according_to_pref(w); /*switch to the channel according to the prefrence*/ + ubus_register_event_handler(ctx, &w->evh, "ethport"); ubus_register_event_handler(ctx, &w->evh, "wifi.*"); ubus_register_event_handler(ctx, &w->evh, "wps_credentials"); diff --git a/src/agent.h b/src/agent.h index 56b39a41a..b5ce3945d 100644 --- a/src/agent.h +++ b/src/agent.h @@ -192,7 +192,7 @@ struct netif_fh { unsigned char bssid[6]; char ssid[33]; char standard[32]; - char radio_name[6]; + char radio_name[16]; bool enabled; bool torndown; int bssload; @@ -404,6 +404,11 @@ enum acs_state { ACS_ACTIVE }; +struct radio_tmp { + struct agent *a; + struct wifi_radio_element *r +}; + struct wifi_radio_element { char name[16]; uint8_t macaddr[6]; diff --git a/src/agent_map.c b/src/agent_map.c index 727d4cdf0..330d9f547 100644 --- a/src/agent_map.c +++ b/src/agent_map.c @@ -1936,28 +1936,38 @@ int get_op_class_bw(int op_class) } } + +int agent_set_channel_preference_to_default(struct wifi_radio_element *radio) +{ + trace("%s: --->\n", __func__); + int found = 0; + int pref = 0; + int l = 0, ret = 0; + + for (l = 0; l < radio->num_supp_opclass; l++) { + int m; + for (m = 0; m <radio->supp_opclass[l]. + num_supported_channels ; m++) { + trace("channel %d\n",radio->supp_opclass[l].supp_chanlist[m].channel ); + trace("channel preference %d\n",radio->supp_opclass[l].supp_chanlist[m].pref ); + radio->supp_opclass[l].supp_chanlist[m].pref = 0x0f; + } + } + + return 0; +} + /*This function return the channel with the highest preference*/ -int agent_get_highest_preference(struct agent *a, uint8_t *radio_id, int op_class_id, int *channel) +int agent_get_highest_preference(struct wifi_radio_element *radio, uint32_t op_class_id, uint32_t *channel, + uint32_t *opclass_to_move) { trace("%s: --->\n", __func__); + int found = 0; int pref = 0; int l = 0, ret = 0; - struct wifi_radio_element *radio = NULL; - trace("\tradio_id: " MACFMT "\n", MAC2STR(radio_id)); - for (l = 0; l < a->num_radios; l++) { - radio = a->radios + l; - ret = memcmp(radio->macaddr, radio_id, 6); - if (ret == 0) { - found = 1; - break; - } - } - if (found == 0) - return -1; - for (l = 0; l < radio->num_supp_opclass; l++) { if (radio->supp_opclass[l].id == op_class_id) { int m; @@ -1968,17 +1978,39 @@ int agent_get_highest_preference(struct agent *a, uint8_t *radio_id, int op_clas if (pref < radio->supp_opclass[l].supp_chanlist[m].pref) { pref = radio->supp_opclass[l].supp_chanlist[m].pref; *channel = radio->supp_opclass[l].supp_chanlist[m].channel; + *opclass_to_move = op_class_id; } } } } + + if (pref == 0x0f) + return; + else { + for (l = 0; l < radio->num_supp_opclass; l++) { + int m; + for (m = 0; m <radio->supp_opclass[l]. + num_supported_channels ; m++) { + trace("channel %d\n",radio->supp_opclass[l].supp_chanlist[m].channel ); + trace("channel preference %d\n",radio->supp_opclass[l].supp_chanlist[m].pref ); + if (pref < radio->supp_opclass[l].supp_chanlist[m].pref) { + pref = radio->supp_opclass[l].supp_chanlist[m].pref; + *channel = radio->supp_opclass[l].supp_chanlist[m].channel; + *opclass_to_move = radio->supp_opclass[l].id; + if (pref == 0x0f) + return 0; + } + } + } + } trace("channel to which channel needs to switch %d\n",*channel ); + return 0; } -static int agent_is_radio_backhaul(struct agent *a, uint8_t *radio_id, struct netif_fh *p) +static int agent_is_radio_backhaul(struct agent *a, uint8_t *radio_id) { -// struct netif_fh *p = NULL; + struct netif_fh *p = NULL; const char *radio_name = NULL; int found = 0; int ret = 0; @@ -2000,12 +2032,12 @@ static int agent_is_radio_backhaul(struct agent *a, uint8_t *radio_id, struct ne if(ret == 0) { trace("I am here %p \n", p->cfg); trace("radio name 51 multi_ap flag is %d\n", p->cfg->multi_ap); - // if (p->cfg->multi_ap != 2) - // continue; - // else { + if (p->cfg->multi_ap != 2) + continue; + else { found = 1; break; - // } + } } } @@ -2025,11 +2057,10 @@ int agent_channel_switch(struct agent *a, uint8_t *radio_id, int channel, int op int freq = 0; int bandwidth = 0; struct netif_fh *p = NULL; -// int found = 0; + int found = 0; const char *radio_name = NULL; trace("channel switch channel %d radio is "MACFMT" \n", channel, MAC2STR(radio_id)); -#if 0 list_for_each_entry(p, &a->fhlist, list) { struct wifi_radio_element *radio = NULL; @@ -2045,19 +2076,17 @@ int agent_channel_switch(struct agent *a, uint8_t *radio_id, int channel, int op trace("radio name 4\n"); if(ret == 0) { trace("I am here %p \n", p->cfg); - //trace("radio name 5 multi_ap flag is %d\n", p->cfg->band); trace("radio name 51 multi_ap flag is %d\n", p->cfg->multi_ap); - // if (p->cfg->multi_ap != 2) - // continue; - // else { + if (p->cfg->multi_ap != 2) + continue; + else { found = 1; break; - // } + } } } -#endif - ret = agent_is_radio_backhaul(a, radio_id, p); - if (ret != 0) + + if (found != 1) return -1; freq = c2f(channel); @@ -2160,8 +2189,7 @@ int agent_process_channel_pref_tlv(void *agent, struct tlv_channel_pref *p, radio = a->radios + l; match = memcmp(radio->macaddr, radio_id, 6); if (match == 0) { - struct netif_fh *p = NULL; - ret = agent_is_radio_backhaul(a, radio_id, p); + ret = agent_is_radio_backhaul(a, radio_id); if (ret != 0) { err("radio is a backhaul radio\n"); memcpy(channel_resp[*channel_resp_nr].radio_id, @@ -2250,21 +2278,35 @@ int agent_process_channel_pref_tlv(void *agent, struct tlv_channel_pref *p, } } } - // break; - // } + } + //Here the global operating class channels have been assigned prefernces if(process == 1) { /* Here we need to see that what is the current operating channel * and that we want to switch to*/ - int channel = 0; - ret = agent_get_highest_preference(a, radio_id, op.class_id, &channel); + uint32_t channel = 0; + uint32_t opclass = 0; + // ret = agent_get_highest_preference(a, radio_id, radio->current_opclass, &channel, + // &opclass); + ret = agent_get_highest_preference(radio, radio->current_opclass, &channel, + &opclass); /* The operating class channel preference has been set * now we want to switch the channel to the max preference */ - if(channel != 0) { - ret = agent_channel_switch(a, radio_id, channel, op.class_id); + if (channel != 0 && opclass != 0 ) { + ret = agent_channel_switch(a, radio_id, channel, opclass); if (ret == -1) { + /*Here we need to set the default preference for all the * channels in that operating class also set the response code as rejected*/ + agent_set_channel_preference_to_default(radio); + memcpy(channel_resp[*channel_resp_nr].radio_id, radio_id, 6); + /* Here response code is a Reserved code + * to decline the request + */ + channel_resp[*channel_resp_nr].response = 0x04; + *channel_resp_nr = *channel_resp_nr + 1; + + return ret; } /* Here we need to write the corresponding preference in the * config file to make preference reboot persistent */ @@ -2273,8 +2315,6 @@ int agent_process_channel_pref_tlv(void *agent, struct tlv_channel_pref *p, } process = 0; } - // break; - } } @@ -2283,10 +2323,34 @@ int agent_process_channel_pref_tlv(void *agent, struct tlv_channel_pref *p, } *channel_resp_nr = *channel_resp_nr + 1; - return ret; } +#if 0 +int agent_switch_according_to_pref(struct wifi_radio_element *radio) +{ + uint32_t channel = 0; + uint32_t opclass = 0; + struct agent *a = this_agent; + int ret = 0; + + ret = agent_get_highest_preference(radio, radio->current_opclass, &channel, + &opclass); + /* The operating class channel preference has been set + * now we want to switch the channel to the max preference */ + if (channel != 0 && opclass != 0 ) { + ret = agent_channel_switch(a, radio->macaddr, channel, opclass); + if (ret == -1) { + + /*Here we need to set the default preference for all the + * channels in that operating class also set the response code as rejected*/ + agent_set_channel_preference_to_default(radio); + } + } + return 0; +} +#endif + int agent_process_transmit_power_tlv(struct agent *a, struct tlv_txpower_limit *p) { int l = 0; diff --git a/src/config.c b/src/config.c index 063f8af99..2cf5c10a2 100644 --- a/src/config.c +++ b/src/config.c @@ -334,8 +334,6 @@ int wifi_set_opclass_preference(char *radio_name, uint32_t opclass_id, set_value(ctx, pkg, s, "radio", radio_name, UCI_TYPE_STRING); set_value(ctx, pkg, s, "channel", channel_str, UCI_TYPE_LIST); -// set_value(ctx, pkg, s, "ifname", ifname, UCI_TYPE_STRING); - out: uci_commit(ctx, &pkg, false); uci_unload(ctx, pkg); @@ -2997,7 +2995,7 @@ static int agent_config_get_opclass(struct wifi_radio_element *radio, num_supported_channels ; m++) { trace("channel %d\n",radio->supp_opclass[l].supp_chanlist[m].channel ); if (radio->supp_opclass[l].supp_chanlist[m].channel == channel) { - trace("I am here NEVA\n"); + trace("I am here NEVA\n pref %d", pref); radio->supp_opclass[l].supp_chanlist[m].pref = pref; } } -- GitLab