diff --git a/src/agent.c b/src/agent.c index 7338d09226b65684264738cfccb8bbf9c8c7e286..cf58c182ff82106890f868b94f8179a038788f66 100644 --- a/src/agent.c +++ b/src/agent.c @@ -3515,6 +3515,8 @@ 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]); @@ -3565,10 +3567,11 @@ static void parse_radio(struct ubus_request *req, int type, ((blobmsg_get_u64(tb1[3]) * 255) / 100) & 0xff; } - //TODO Here we need to read the preference of the opclass from the config - //TODO see if needed First time when no preference is set for the operating class + //ret = agent_fill_channel_preference_default(re); - //TODONEV Add the config to preference writing here + + //Add the config to preference writing here + agent_config_opclass(re); } struct wifi_scanres_channel_element *wifi_get_scanres_ch_element(struct wifi_radio_element *re, uint8_t ch) diff --git a/src/agent_map.c b/src/agent_map.c index ac8122e5d1789c828468165e2f78777dfd05be5d..791f9a070b466a51b77304dd588d27dd09857db6 100644 --- a/src/agent_map.c +++ b/src/agent_map.c @@ -1841,7 +1841,7 @@ int send_channel_sel_response(void *agent, struct cmdu_buff *rx_cmdu, /* send a report message for each radio. specifying current operating channels * as per the spec pg 30*/ - //send_oper_channel_report(agent, rx_cmdu); + send_oper_channel_report(agent, rx_cmdu); return 0; error: @@ -1983,8 +1983,6 @@ 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; - struct netif_fh *fh; - char ifname[16]; int found = 0; const char *radio_name = NULL; trace("channel switch channel %d radio is "MACFMT" \n", channel, MAC2STR(radio_id)); @@ -2038,6 +2036,56 @@ int agent_channel_switch(struct agent *a, uint8_t *radio_id, int channel, int op return 0; } +int agent_config_channel_preference(struct agent *a, uint8_t *radio_id, uint32_t opclass_id) +{ + int l = 0; + struct wifi_radio_element *radio; + int ret = 0, found = 0; + trace("%s: --->\n", __func__); + + /* Here we need to write the preferences in the config file + * only the channels in which the preferences are not + * highest preferences + */ + 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 == opclass_id) { + int m = 0, j = 0; + int channel_list[20]; + int pref = 0x0f; + for (m = 0; m <radio->supp_opclass[l]. + num_supported_channels ; m++) { + trace("channel NEV%d\n",radio->supp_opclass[l].supp_chanlist[m].channel ); + trace("channel preference NEV%d\n",radio->supp_opclass[l].supp_chanlist[m].pref ); + if (radio->supp_opclass[l].supp_chanlist[m].pref != 0x0f) { + trace("I am here in config1 NEVA\n"); + pref = radio->supp_opclass[l].supp_chanlist[m].pref; + channel_list[j++] = radio->supp_opclass[l].supp_chanlist[m].channel; + } + } + if (pref != 0x0f) { + trace("I am here in config2 NEVA\n"); + ret = wifi_set_opclass_preference(radio->name, opclass_id, pref, + channel_list, j); + if (ret != 0) + err("cannot write preference in config\n"); + + } + } + } +} int agent_process_channel_pref_tlv(void *agent, struct tlv_channel_pref *p, struct channel_response *channel_resp, @@ -2164,10 +2212,11 @@ int agent_process_channel_pref_tlv(void *agent, struct tlv_channel_pref *p, /*Here we need to set the default preference for all the * channels in that operating class also set the response code as rejected*/ } + /* Here we need to write the corresponding preference in the + * config file to make preference reboot persistent */ + trace("I am here in the config NEV\n"); + ret = agent_config_channel_preference(a, radio_id, op.class_id); } - /* Here we need to write the corresponding preference in the - * config file to make preference reboot persistent */ - // ret = agent_config_channel_preference(); process = 0; } // break; diff --git a/src/config.c b/src/config.c index 20c283bf2292a665f33248c947cbeed76fd397f6..063f8af992080cf0178b834eefbafc4efe080177 100644 --- a/src/config.c +++ b/src/config.c @@ -286,6 +286,63 @@ out_pkg: return ret; } +int wifi_set_opclass_preference(char *radio_name, uint32_t opclass_id, + uint32_t preference, uint32_t *channel_list, int channel_num) +{ + + struct uci_section *s; + struct uci_package *pkg; + int ret = 0, i = 0; + char pref_str[20]; + char opclassid_str[20]; + char channel_str[200]; + struct uci_context *ctx; + + trace("Inside %s %d\n", __func__, __LINE__); + + ctx = uci_alloc_context(); + if (!ctx) + goto out; + + if (uci_load(ctx, UCI_AGENT, &pkg) != UCI_OK) { + err("config file 'mapagent' not found!\n"); + ret = -1; + goto out; + } + + trace("Inside iNEV1%s %d\n", __func__, __LINE__); + snprintf(opclassid_str, 20, "%d", opclass_id); + trace("Inside iNEV11%s %d %s %d\n", __func__, __LINE__, opclassid_str, channel_num); + s = config_add_section(ctx, pkg, UCI_AGENT, "opclass", "opclassid", + opclassid_str); + if (!s) { + ret = -1; + goto out; + } + memset(channel_str, 0, sizeof(channel_str)); + trace("Inside iNEV2%s %d\n", __func__, __LINE__); + sprintf(pref_str, "%d", preference); + char chan_str[4]; + for (i = 0; i < channel_num; i++) { + memset(chan_str, 0, sizeof(chan_str)); + sprintf(chan_str,"%d ",channel_list[i]); + trace("Inside iNEV32%s %d %s\n", __func__, __LINE__, chan_str); + strcat(channel_str, chan_str); + } + trace("Inside iNEV22%s %d %s\n", __func__, __LINE__, channel_str); + set_value(ctx, pkg, s, "preference", pref_str, UCI_TYPE_STRING); + 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); + uci_free_context(ctx); + return ret; + +} int wifi_set_iface_bssid(struct netif_bk *bk, uint8_t *bssid) { @@ -2877,3 +2934,107 @@ out_pkg: return ret; } +static int agent_config_get_opclass(struct wifi_radio_element *radio, + struct uci_section *s) +{ + enum { + OP_CLASSID, + OP_PREF, + OP_RADIO, + OP_CHANNEL, + NUM_POLICIES + }; + + const struct uci_parse_option opts[] = { + { .name = "opclassid", .type = UCI_TYPE_STRING }, + { .name = "preference", .type = UCI_TYPE_STRING }, + { .name = "radio", .type = UCI_TYPE_STRING }, + { .name = "channel", .type = UCI_TYPE_LIST }, + }; + + struct uci_option *tb[NUM_POLICIES]; + int opclassid = 0; + int pref = 0; + + trace("Inside %s %d\n", __func__, __LINE__); + + uci_parse_section(s, opts, NUM_POLICIES, tb); + + if (tb[OP_RADIO]) { + struct uci_element *xi; + const char *ifname; + + ifname = tb[OP_RADIO]->v.string; + trace("radio name [%s] ifname [%s]\n", radio->name, ifname); + int ret = strcmp(radio->name, ifname); + if (ret != 0) + return 0; + } + + if (tb[OP_CLASSID]) { + opclassid = atoi(tb[OP_CLASSID]->v.string); + } + + if (tb[OP_PREF]) { + pref = atoi(tb[OP_PREF]->v.string); + } + + if (tb[OP_CHANNEL]) { + struct uci_element *xi; + + dbg("Channel: param: classid %d pref %d\n", opclassid, pref); + uci_foreach_element(&tb[OP_CHANNEL]->v.list, xi) { + int l = 0; + uint32_t channel = 0; + + trace(" NEV %s \n ", xi->name); + channel = atoi(xi->name); + for (l = 0; l < radio->num_supp_opclass; l++) { + if (radio->supp_opclass[l].id == opclassid) { + int m = 0; + trace(" NEV2 \n "); + for (m = 0; m < radio->supp_opclass[l]. + 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"); + radio->supp_opclass[l].supp_chanlist[m].pref = pref; + } + } + } + } + } + + dbg("\n"); + } + return 0; +} + +int agent_config_opclass(struct wifi_radio_element *radio) +{ + struct uci_context *ctx; + struct uci_package *pkg; + struct uci_element *e; + + trace("Inside %s %d\n", __func__, __LINE__); + + ctx = uci_alloc_context(); + if (!ctx) + return -1; + + if (uci_load(ctx, "mapagent", &pkg)) { + uci_free_context(ctx); + return -1; + } + + uci_foreach_element(&pkg->sections, e) { + struct uci_section *s = uci_to_section(e); + + if (!strcmp(s->type, "opclass")) + agent_config_get_opclass(radio, s); + } + + uci_free_context(ctx); + return 0; +} + diff --git a/src/config.h b/src/config.h index 1678f157d76a8439eb3f4e18a86be8b27e447eaa..2cb2bd4895732552e07b5fc1bffa7e9eea5f4e97 100644 --- a/src/config.h +++ b/src/config.h @@ -277,5 +277,7 @@ int uci_add_fw(struct agent_config *cfg, char *interface); void config_disable_bstas(struct agent_config *cfg); int config_disable_bsta(struct netif_bkcfg *bk); void uci_apply_traffic_sep(struct tlv_traffic_sep_policy *tlv); +int wifi_set_opclass_preference(char *radio_name, uint32_t opclass_id, + uint32_t preference, uint32_t *channel_list, int channel_num); #endif