diff --git a/src/core/cntlr.c b/src/core/cntlr.c index 5ecdc0e8725dea09f7b0239d9f90bf86653366f7..728f94a81c7dfaf3f58187430ec66f1026578788 100644 --- a/src/core/cntlr.c +++ b/src/core/cntlr.c @@ -2017,8 +2017,8 @@ static void cntlr_signal_periodic_run(struct uloop_timeout *t) if ((diff & CONFIG_DIFF_AGENT_POLICY) && !p->is_policy_diff) continue; - cmdu = cntlr_gen_policy_config_req(c, NULL, p, - num_radio, radio_id, num_bk, bk_id); + cmdu = cntlr_gen_policy_config_req(c, p, num_radio, + radio_id, num_bk, bk_id); if (cmdu) { send_cmdu(c, cmdu); cmdu_free(cmdu); diff --git a/src/core/cntlr_cmdu_generator.c b/src/core/cntlr_cmdu_generator.c index 9254e6792be70f7e613d5940ef29b4911e5e3f15..5ab943eb065972794162f25544da6dd2a6dd37a9 100644 --- a/src/core/cntlr_cmdu_generator.c +++ b/src/core/cntlr_cmdu_generator.c @@ -261,105 +261,75 @@ out: } struct cmdu_buff *cntlr_gen_policy_config_req(struct controller *c, - char *intf_name, struct agent_policy *found, + struct agent_policy *found, int num_radio, uint8_t *radiolist, int num_bss, uint8_t *bsslist) { + int i, ret; + uint16_t mid = 0; + struct cmdu_buff *frm; + + frm = cmdu_alloc_simple(CMDU_POLICY_CONFIG_REQ, &mid); + if (!frm) { + dbg("%s: -ENOMEM\n", __func__); + return NULL; + } + + memcpy(frm->origin, found->agent_id, 6); + + /* Steering Policy TLV */ + ret = cntlr_gen_steering_policy(c, found, frm, + num_radio, radiolist); + if (ret) + goto out; + + /* Metric Reporting Policy TLV */ + ret = cntlr_gen_metric_report_policy(c, found, frm, + num_radio, radiolist); + if (ret) + goto out; + +// #ifdef PROFILE2 + /* Default 802.1Q setting TLV */ + ret = cntlr_gen_8021q_settings(c, frm, found); + if (ret) + goto out; + + /* Traffic Seperation Policy TLV */ +#if 0 + ret = cntlr_gen_traffic_sep_policy(c, frm); + if (ret) + goto out; +#endif + + /* Channel Scan Reporting Policy TLV */ + ret = cntlr_gen_ch_scan_rep_policy(c, found, frm); + if (ret) + goto out; + + /* Unsuccessful Association Policy TLV */ + ret = cntlr_gen_unsuccess_assoc_policy(c, found, frm); + if (ret) + goto out; + + /* Backhaul BSS Configuration TLV */ + for (i = 0; i < num_bss; i++) { + uint8_t bssid[6] = {0}; + + memcpy(bssid, &bsslist[i*6], 6); + ret = cntlr_gen_backhaul_bss_config(c, found, frm, bssid); + if (ret) + goto out; + } +// #endif + + cmdu_put_eom(frm); + + return frm; +out: + cmdu_free(frm); + return NULL; -// struct cmdu_cstruct *cmdu; -// int tlv_index = 0; -// int i; -// /* TLVs */ -// struct tlv_steering_policy *p1; -// struct tlv_metric_report_policy *p2; -// /* Map-2 tlvs */ -//// #ifdef PROFILE2 -// struct tlv_default_8021q_settings *p3; -// struct tlv_traffic_sep_policy *p4; -// struct tlv_ch_scan_rep_policy *p5; -// struct tlv_unsuccess_assoc_policy *p6; -// struct tlv_backhaul_bss_config *p7; -//// #endif -// -// cmdu = (struct cmdu_cstruct *)calloc(1, sizeof(struct cmdu_cstruct)); -// if (!cmdu) { -// trace("failed to malloc cmdu\n"); -// return NULL; -// } -// -// cmdu_defaults(c, cmdu, found->agent_id, intf_name, CMDU_POLICY_CONFIG_REQ); -// -// cmdu->num_tlvs = 2; -//// #ifdef PROFILE2 -// cmdu->num_tlvs += 4 + num_bss; -//// #endif -// -// cmdu->tlvs = (uint8_t **)calloc(cmdu->num_tlvs, sizeof(uint8_t *)); -// if (!cmdu->tlvs) { -// cmdu->num_tlvs = 0; -// goto fail_cmdu; -// } -// -// /* Steering Policy TLV */ -// p1 = cntlr_gen_steering_policy(c, found, cmdu, num_radio, radiolist); -// if (!p1) -// goto fail_cmdu; -// -// cmdu->tlvs[tlv_index++] = (uint8_t *)p1; -// -// /* Metric Reporting Policy TLV */ -// p2 = cntlr_gen_metric_report_policy(c, found, cmdu, num_radio, radiolist); -// if (!p2) -// goto fail_cmdu; -// -// cmdu->tlvs[tlv_index++] = (uint8_t *)p2; -// -//// #ifdef PROFILE2 -// /* Default 802.1Q setting TLV */ -// p3 = cntlr_gen_8021q_settings(c, found); -// if (!p3) -// goto fail_cmdu; -// -// cmdu->tlvs[tlv_index++] = (uint8_t *)p3; -// -// /* Traffic Seperation Policy TLV */ -// p4 = cntlr_gen_traffic_sep_policy(c, cmdu); -// if (!p4) -// goto fail_cmdu; -// -// cmdu->tlvs[tlv_index++] = (uint8_t *)p4; -// -// /* Channel Scan Reporting Policy TLV */ -// p5 = cntlr_gen_ch_scan_rep_policy(c, found, cmdu); -// if (!p5) -// goto fail_cmdu; -// -// cmdu->tlvs[tlv_index++] = (uint8_t *)p5; -// -// /* Unsuccessful Association Policy TLV */ -// p6 = cntlr_gen_unsuccess_assoc_policy(c, found, cmdu); -// if (!p6) -// goto fail_cmdu; -// -// cmdu->tlvs[tlv_index++] = (uint8_t *)p6; -// -// /* Backhaul BSS Configuration TLV */ -// for (i = 0; i < num_bss; i++) { -// uint8_t bssid[6] = {0}; -// -// memcpy(bssid, &bsslist[i*6], 6); -// p7 = cntlr_gen_backhaul_bss_config(c, found, cmdu, bssid); -// if (!p7) -// goto fail_cmdu; -// -// cmdu->tlvs[tlv_index++] = (uint8_t *)p7; -// } -//// #endif -// -// return cmdu; -//fail_cmdu: -// map_free_cmdu(cmdu); -// return NULL; } struct cmdu_buff *cntlr_gen_sta_metric_query(struct controller *c, diff --git a/src/core/cntlr_cmdu_generator.h b/src/core/cntlr_cmdu_generator.h index 0013b7a9cd09ceaf26013ec3f44d585bda3b217c..0cb9f4e76eee5ec71f3bf821ad7e38931093b7e4 100644 --- a/src/core/cntlr_cmdu_generator.h +++ b/src/core/cntlr_cmdu_generator.h @@ -29,7 +29,7 @@ struct cmdu_buff *cntlr_gen_ap_metrics_query(struct controller *c, uint8_t *origin, int num_bss, uint8_t *bsslist, int num_radio, uint8_t *radiolist); struct cmdu_buff *cntlr_gen_policy_config_req(struct controller *c, - char *intf_name, struct agent_policy *found, + struct agent_policy *found, int num_radio, uint8_t *radiolist, int num_bss, uint8_t *bsslist); struct cmdu_buff *cntlr_gen_sta_metric_query(struct controller *c, diff --git a/src/core/cntlr_map_debug.c b/src/core/cntlr_map_debug.c index 6019ed52c835effda9b084a6db0a98865d89bb36..7a743187b6ad659564ffed7f3076254b517b31a4 100644 --- a/src/core/cntlr_map_debug.c +++ b/src/core/cntlr_map_debug.c @@ -1202,64 +1202,55 @@ int debug_assoc_status_notification(void *cntlr, struct cmdu_buff *cmdu) int debug_tunneled_message(void *cntlr, struct cmdu_buff *cmdu) { + struct tlv *tv[3][16] = { 0 }; + struct tlv_policy tunnel_policy[] = { + [0] = { .type = MAP_TLV_SOURCE_INFO, .present = TLV_PRESENT_ONE }, + [1] = { .type = MAP_TLV_TUNNELED_MSG_TYPE, .present = TLV_PRESENT_ONE }, + [2] = { .type = MAP_TLV_TUNNELED, .present = TLV_PRESENT_ONE } + }; + + trace("%s: --->\n", __func__); + trace("parsing tunnel message |" MACFMT "\n", + MAC2STR(cmdu->origin)); + + cmdu_parse_tlvs(cmdu, tv, tunnel_policy, 3); + + if (tv[0][0]) { + struct tlv_source_info *p = + (struct tlv_source_info *) tv[0][0]->data; + + trace("\tmac: " MACFMT "\n", MAC2STR(p->macaddr)); + } + + if (tv[1][0]) { + struct tlv_tunnel_msg_type *p = + (struct tlv_tunnel_msg_type *) tv[1][0]->data; + + trace("\ttunnel_protocol_type: %d\n", p->type); + } + + if (tv[2][0]) { + struct tlv *t = (struct tlv *)tv[2][0]; + char *framestr = NULL; + uint16_t frame_len; + struct tlv_tunneled *p = + (struct tlv_tunneled *) tv[2][0]->data; + + frame_len = BUF_GET_BE16(t->len); + trace("\tlen: %d\n", frame_len); + if (frame_len > 0) { + framestr = calloc((2 * frame_len) + 1, + sizeof(char)); + } + + if (framestr) { + btostr(p->frame, frame_len, framestr); + trace("\tframe_body: %s\n", framestr); + free(framestr); + } + } + return 0; -// int i; -// uint8_t *tlv; -// -// trace("%s: --->\n", __func__); -// trace("parsing tunnel message |" MACFMT "|CMDU: %s\n", -// MAC2STR(cmdu->origin), -// map_stringify_cmdu_type(cmdu->message_type)); -// -// for (i = 0; i < cmdu->num_tlvs; i++) { -// tlv = (uint8_t *)cmdu->tlvs[i]; -// trace("TLV: %s\n", map_stringify_tlv_type(*tlv)); -// switch (*tlv) { -// case MAP_TLV_SOURCE_INFO: -// { -// struct tlv_source_info *p = -// (struct tlv_source_info *)tlv; -// -// trace("\tmac: " MACFMT "\n", MAC2STR(p->mac)); -// break; -// } -// case MAP_TLV_TUNNELED_MSG_TYPE: -// { -// struct tlv_tunnel_msg_type *p = -// (struct tlv_tunnel_msg_type *)tlv; -// -// trace("\ttunnel_protocol_type: %d\n", -// p->tunnel_protocol_type); -// break; -// } -// case MAP_TLV_TUNNELED: -// { -// char *framestr = NULL; -// int frame_len; -// struct tlv_tunneled *p = (struct tlv_tunneled *)tlv; -// -// trace("\ttlv_len: %d\n", p->tlv_len); -// if (p->tlv_len > 0) { -// frame_len = (2 * p->tlv_len) + 1; -// framestr = calloc(frame_len, sizeof(char)); -// } -// -// if (framestr) { -// btostr(p->frame_body, p->tlv_len, framestr); -// trace("\tframe_body: %s\n", framestr); -// free(framestr); -// } -// break; -// } -// default: -// { -// trace("unknown TLV\n"); -// break; -// } -// } -// } -// -// return 0; } int debug_backhaul_sta_caps_report(void *cntlr, struct cmdu_buff *cmdu) diff --git a/src/core/cntlr_tlv_generator.c b/src/core/cntlr_tlv_generator.c index 24c1d5df81f9eaf08a4cf8d164926685ef41bb91..7807561b4cbe44e3fb78821f8f56b208375428ed 100644 --- a/src/core/cntlr_tlv_generator.c +++ b/src/core/cntlr_tlv_generator.c @@ -106,16 +106,16 @@ int cntlr_gen_8021q_settings(struct controller *c, struct cmdu_buff *frm, struct tlv_default_8021q_settings *data; int ret; - t = cmdu_reserve_tlv(frm, 256); + t = cmdu_reserve_tlv(frm, 20); if (!t) return -1; t->type = MAP_TLV_DEFAULT_8021Q_SETTINGS; - t->len = 3; + t->len = sizeof(*data); data = (struct tlv_default_8021q_settings *) t->data; - data->pvid = a->pvid; - data->pcp = a->pcp_default; + BUF_PUT_BE16(data->pvid, a->pvid); + data->pcp = (a->pcp_default << 5) & PCP_MASK; ret = cmdu_put_tlv(frm, t); if (ret) { @@ -124,17 +124,6 @@ int cntlr_gen_8021q_settings(struct controller *c, struct cmdu_buff *frm, } return 0; -// struct tlv_default_8021q_settings *p; -// -// p = (struct tlv_default_8021q_settings *) calloc(1, sizeof(*p)); -// if (!p) -// return NULL; -// -// p->tlv_type = MAP_TLV_DEFAULT_8021Q_SETTINGS; -// p->primary_vid = a->pvid; -// p->pcp = a->pcp_default; -// -// return p; } int cntlr_gen_traffic_sep_policy(struct controller *c, struct cmdu_buff *frm, @@ -378,21 +367,31 @@ int cntlr_gen_map_profile(struct controller *c, struct cmdu_buff *frm, return 0; } -struct tlv_ch_scan_rep_policy *cntlr_gen_ch_scan_rep_policy( - struct controller *c, struct agent_policy *a, - struct cmdu_buff *cmdu) +int cntlr_gen_ch_scan_rep_policy( struct controller *c, + struct agent_policy *a, struct cmdu_buff *frm) { - return NULL; -// struct tlv_ch_scan_rep_policy *p; -// -// p = calloc(1, sizeof(struct tlv_ch_scan_rep_policy)); -// if (!p) -// return NULL; -// -// p->tlv_type = MAP_TLV_CHANNEL_SCAN_REPORTING_POLICY; -// p->ch_scans = a->report_scan; -// -// return p; + int ret; + struct tlv *t; + struct tlv_channel_scan_report_policy *data; + + t = cmdu_reserve_tlv(frm, 20); + if (!t) + return -1; + + t->type = MAP_TLV_CHANNEL_SCAN_REPORTING_POLICY; + t->len = sizeof(*data); + data = (struct tlv_channel_scan_report_policy *) t->data; + + if (a->report_scan) + data->report = REPORT_CHANNEL_SCANS; + + ret = cmdu_put_tlv(frm, t); + if (ret) { + dbg("%s: error: cmdu_put_tlv()\n", __func__); + return -1; + } + + return 0; } int cntlr_gen_al_mac(struct controller *c, struct cmdu_buff *frm, @@ -421,22 +420,33 @@ int cntlr_gen_al_mac(struct controller *c, struct cmdu_buff *frm, return 0; } -struct tlv_unsuccess_assoc_policy *cntlr_gen_unsuccess_assoc_policy( - struct controller *c, struct agent_policy *a, - struct cmdu_buff *cmdu) +int cntlr_gen_unsuccess_assoc_policy(struct controller *c, + struct agent_policy *a, struct cmdu_buff *frm) { - return NULL; -// struct tlv_unsuccess_assoc_policy *p; -// -// p = calloc(1, sizeof(struct tlv_unsuccess_assoc_policy)); -// if (!p) -// return NULL; -// -// p->tlv_type = MAP_TLV_UNSUCCESS_ASSOCIATION_POLICY; -// p->report = a->report_sta_assocfails; -// p->max_reporting_rate = a->report_sta_assocfails_rate; -// -// return p; + int ret; + struct tlv *t; + struct tlv_unsuccess_assoc_policy *data; + + t = cmdu_reserve_tlv(frm, 20); + if (!t) + return -1; + + t->type = MAP_TLV_UNSUCCESS_ASSOCIATION_POLICY; + t->len = sizeof(*data); + data = (struct tlv_unsuccess_assoc_policy *) t->data; + + if (a->report_sta_assocfails) + data->report = UNSUCCESSFUL_ASSOC_REPORT; + + BUF_PUT_BE32(data->max_report_rate, a->report_sta_assocfails_rate); + + ret = cmdu_put_tlv(frm, t); + if (ret) { + dbg("%s: error: cmdu_put_tlv()\n", __func__); + return -1; + } + + return 0; } int cntlr_gen_supported_freq_band(struct controller *c, struct cmdu_buff *frm, @@ -464,133 +474,139 @@ int cntlr_gen_supported_freq_band(struct controller *c, struct cmdu_buff *frm, return 0; } -struct tlv_backhaul_bss_config *cntlr_gen_backhaul_bss_config( - struct controller *c, struct agent_policy *a, - struct cmdu_buff *cmdu, const uint8_t *bssid) +int cntlr_gen_backhaul_bss_config(struct controller *c, + struct agent_policy *a, struct cmdu_buff *frm, + const uint8_t *bssid) { - return NULL; -// struct tlv_backhaul_bss_config *p; -// -// p = calloc(1, sizeof(struct tlv_backhaul_bss_config)); -// if (!p) -// return NULL; -// -// p->tlv_type = MAP_TLV_BACKHAUL_BSS_CONFIG; -// memcpy(p->bssid, bssid, 6); -// p->p1 = a->disallow_bsta_p1; -// p->p2 = a->disallow_bsta_p2; -// -// return p; + int ret; + struct tlv *t; + struct tlv_bbss_config *data; + + t = cmdu_reserve_tlv(frm, 20); + if (!t) + return -1; + + t->type = MAP_TLV_BACKHAUL_BSS_CONFIG; + t->len = sizeof(*data); + data = (struct tlv_bbss_config *) t->data; + + memcpy(data->bssid, bssid, 6); + if (a->disallow_bsta_p1) + data->config |= BBSS_CONFIG_P1_BSTA_DISALLOWED; + + if (a->disallow_bsta_p2) + data->config |= BBSS_CONFIG_P2_BSTA_DISALLOWED; + + ret = cmdu_put_tlv(frm, t); + if (ret) { + dbg("%s: error: cmdu_put_tlv()\n", __func__); + return -1; + } + + return 0; } -struct tlv_steering_policy *cntlr_gen_steering_policy( - struct controller *c, struct agent_policy *a, - struct cmdu_buff *cmdu, int num_radio, uint8_t *radiolist) +int cntlr_gen_steering_policy(struct controller *c, struct agent_policy *a, + struct cmdu_buff *frm, int num_radio, uint8_t *radiolist) { - return NULL; -// int i = 0, index; -// struct tlv_steering_policy *p; -// struct stax *x; -// uint8_t sta_mac[6] = {0}; -// -// p = calloc(1, sizeof(struct tlv_steering_policy)); -// if (!p) -// return NULL; -// -// p->tlv_type = MAP_TLV_STEERING_POLICY; -// -// p->local_disallowed_sta_nr = 0; -// list_for_each_entry(x, &a->steer_exlist, list) { -// p->local_disallowed_sta_nr++; -// index = p->local_disallowed_sta_nr - 1; -// p->local_disallowed_sta_macs = realloc(p->local_disallowed_sta_macs, -// p->local_disallowed_sta_nr * sizeof(*p->local_disallowed_sta_macs)); -// if (!p->local_disallowed_sta_macs) -// goto fail_alloc; -// -// hwaddr_aton(x->macstring, sta_mac); -// memcpy(p->local_disallowed_sta_macs[index].addr, sta_mac, 6); -// } -// -// p->btm_disallowed_sta_nr = 0; -// list_for_each_entry(x, &a->btmsteer_exlist, list) { -// p->btm_disallowed_sta_nr++; -// index = p->btm_disallowed_sta_nr - 1; -// p->btm_disallowed_sta_macs = realloc(p->btm_disallowed_sta_macs, -// p->btm_disallowed_sta_nr * sizeof(*p->btm_disallowed_sta_macs)); -// if (!p->btm_disallowed_sta_macs) -// goto fail_alloc; -// -// hwaddr_aton(x->macstring, sta_mac); -// memcpy(p->btm_disallowed_sta_macs[index].addr, sta_mac, 6); -// } -// -// p->control_policy_radio_nr = num_radio; -// p->control_policy = calloc(p->control_policy_radio_nr, -// sizeof(*p->control_policy)); -// if (!p->control_policy) -// goto fail_alloc; -// -// for (i = 0; i < p->control_policy_radio_nr; i++) { -// memcpy(p->control_policy[i].radio_id, &radiolist[i*6], 6); -// p->control_policy[i].steering_policy = a->policy; -// p->control_policy[i].channel_utilization_thres = -// a->util_threshold; -// p->control_policy[i].rcpi_steering_thres = -// a->rcpi_threshold; -// } -// -// return p; -// -//fail_alloc: -// if (p->local_disallowed_sta_macs) -// free(p->local_disallowed_sta_macs); -// if (p->btm_disallowed_sta_macs) -// free(p->btm_disallowed_sta_macs); -// -// free(p); -// -// return NULL; + int ret, i; + int offset = 0; + struct tlv *t; + struct stax *x; + uint8_t sta_mac[6] = {0}; + uint8_t num_nosteer_index = 0; + uint8_t num_nobtmsteer_index = 0; + uint8_t num_nosteer = 0; + uint8_t num_nobtmsteer = 0; + + t = cmdu_reserve_tlv(frm, 256); + if (!t) + return -1; + + t->type = MAP_TLV_STEERING_POLICY; + + num_nosteer_index = offset++; + list_for_each_entry(x, &a->steer_exlist, list) { + num_nosteer++; + hwaddr_aton(x->macstring, sta_mac); + memcpy(t->data + offset, sta_mac, 6); + offset += 6; + } + t->data[num_nosteer_index] = num_nosteer; + + num_nobtmsteer_index = offset++; + list_for_each_entry(x, &a->btmsteer_exlist, list) { + num_nobtmsteer++; + hwaddr_aton(x->macstring, sta_mac); + memcpy(t->data + offset, sta_mac, 6); + offset += 6; + } + t->data[num_nobtmsteer_index] = num_nobtmsteer; + + t->data[offset++] = num_radio; + for (i = 0; i < num_radio; i++) { + memcpy(t->data + offset, &radiolist[i*6], 6); + offset += 6; + t->data[offset++] = a->policy; + t->data[offset++] = a->util_threshold; + t->data[offset++] = a->rcpi_threshold; + } + + /* update the tlv len */ + t->len = offset; + + ret = cmdu_put_tlv(frm, t); + if (ret) { + dbg("%s: error: cmdu_put_tlv()\n", __func__); + return -1; + } + + return 0; } -struct tlv_metric_report_policy *cntlr_gen_metric_report_policy( - struct controller *c, struct agent_policy *a, - struct cmdu_buff *cmdu, int num_radio, uint8_t *radiolist) +int cntlr_gen_metric_report_policy(struct controller *c, struct agent_policy *a, + struct cmdu_buff *frm, int num_radio, uint8_t *radiolist) { - return NULL; -// int i = 0; -// struct tlv_metric_report_policy *p; -// -// p = calloc(1, sizeof(struct tlv_metric_report_policy)); -// if (!p) -// return NULL; -// -// p->tlv_type = MAP_TLV_METRIC_REPORTING_POLICY; -// p->interval = a->report_metric_periodic; -// p->metric_reporting_policy_radio_nr = num_radio; -// p->metric_reporting_policy = calloc(p->metric_reporting_policy_radio_nr, -// sizeof(*p->metric_reporting_policy)); -// -// if (!p->metric_reporting_policy) { -// free(p); -// return NULL; -// } -// -// for (i = 0; i < p->metric_reporting_policy_radio_nr; i++) { -// memcpy(p->metric_reporting_policy[i].radio_id, &radiolist[i*6], 6); -// p->metric_reporting_policy[i].rcpi_thres = -// a->report_rcpi_threshold; -// p->metric_reporting_policy[i].rcpi_hysteresis_margin = -// a->rcpi_hysteresis_margin; -// p->metric_reporting_policy[i].channel_utilization_thres = -// a->report_util_threshold; -// p->metric_reporting_policy[i].is_assoc_sta_traffic_stats = -// a->include_sta_stats; -// p->metric_reporting_policy[i].is_assoc_sta_link_metrics = -// a->include_sta_metric; -// } -// -// return p; + int ret, i; + struct tlv *t; + int offset = 0; + uint8_t include_flag = 0x00; + + t = cmdu_reserve_tlv(frm, 256); + if (!t) + return -1; + + t->type = MAP_TLV_METRIC_REPORTING_POLICY; + + t->data[offset++] = a->report_metric_periodic; + t->data[offset++] = num_radio; + + for (i = 0; i < num_radio; i++) { + memcpy(t->data + offset, &radiolist[i*6], 6); + offset += 6; + t->data[offset++] = a->report_rcpi_threshold; + t->data[offset++] = a->rcpi_hysteresis_margin; + t->data[offset++] = a->report_util_threshold; + + if (a->include_sta_stats) + include_flag |= INCLUDE_STA_STATS; + + if (a->include_sta_metric) + include_flag |= INCLUDE_STA_LINK_METRICS; + + t->data[offset++] = include_flag; + } + + /* update the tlv length */ + t->len = offset; + + ret = cmdu_put_tlv(frm, t); + if (ret) { + dbg("%s: error: cmdu_put_tlv()\n", __func__); + return -1; + } + + return 0; } struct tlv_supported_role *cntlr_gen_supported_role(struct controller *c, diff --git a/src/core/cntlr_tlv_generator.h b/src/core/cntlr_tlv_generator.h index a8b44b451b6ade984ca9f8f6f8455667b63001e5..4bf519bb7c9cf2b7e762cc289f2d8cf3a644f2da 100644 --- a/src/core/cntlr_tlv_generator.h +++ b/src/core/cntlr_tlv_generator.h @@ -26,20 +26,18 @@ int cntlr_gen_supp_service(struct controller *c, struct cmdu_buff *cmdu, uint8_t service); int cntlr_gen_map_profile(struct controller *c, struct cmdu_buff *frm, uint8_t profile); -struct tlv_steering_policy *cntlr_gen_steering_policy(struct controller *c, - struct agent_policy *a, struct cmdu_buff *cmdu, +int cntlr_gen_steering_policy(struct controller *c, + struct agent_policy *a, struct cmdu_buff *frm, int num_radio, uint8_t *radiolist); -struct tlv_metric_report_policy *cntlr_gen_metric_report_policy(struct controller *c, - struct agent_policy *a, struct cmdu_buff *cmdu, +int cntlr_gen_metric_report_policy(struct controller *c, + struct agent_policy *a, struct cmdu_buff *frm, int num_radio, uint8_t *radiolist); -struct tlv_ch_scan_rep_policy *cntlr_gen_ch_scan_rep_policy(struct controller *c, - struct agent_policy *a, struct cmdu_buff *cmdu); -struct tlv_unsuccess_assoc_policy *cntlr_gen_unsuccess_assoc_policy( - struct controller *c, struct agent_policy *a, - struct cmdu_buff *cmdu); -struct tlv_backhaul_bss_config *cntlr_gen_backhaul_bss_config( - struct controller *c, struct agent_policy *a, - struct cmdu_buff *cmdu, const uint8_t *bssid); +int cntlr_gen_ch_scan_rep_policy(struct controller *c, + struct agent_policy *a, struct cmdu_buff *frm); +int cntlr_gen_unsuccess_assoc_policy(struct controller *c, + struct agent_policy *a, struct cmdu_buff *frm); +int cntlr_gen_backhaul_bss_config(struct controller *c, struct agent_policy *a, + struct cmdu_buff *frm, const uint8_t *bssid); int cntlr_gen_al_mac(struct controller *c, struct cmdu_buff *frm, uint8_t *hwaddr); int cntlr_gen_supported_freq_band(struct controller *c, struct cmdu_buff *frm, diff --git a/src/core/cntlr_ubus.c b/src/core/cntlr_ubus.c index 931dc37b64be85101740ad181d5dc4a6759c293d..6061f358d93f531ac8f1c1f181501071a98e5be5 100644 --- a/src/core/cntlr_ubus.c +++ b/src/core/cntlr_ubus.c @@ -1287,119 +1287,116 @@ static int cntlr_ap_policy_config(struct ubus_context *ctx, struct ubus_object * struct ubus_request_data *req, const char *method, struct blob_attr *msg) { - return 0; -// char agent[18] = {0}; -// char radio[18] = {0}; -// char bss[18] = {0}; -// uint8_t hwaddr[6] = {0}; -// struct cmdu_cstruct *cmdu_data; -// struct agent_policy *a, *found = NULL; -// struct blob_attr *attr = NULL; -// uint8_t *radiolist = NULL; -// uint8_t *bsslist = NULL; -// int rem, num_radio = 0, num_bss = 0; -// struct blob_attr *tb[__AP_POLICY_CONFIG_MAX]; -// struct controller *c = container_of(obj, struct controller, obj); -// -// blobmsg_parse(ap_policy_config_params, __AP_POLICY_CONFIG_MAX, tb, -// blob_data(msg), blob_len(msg)); -// -// if (!tb[AP_POLICY_CONFIG_AGENT] || !tb[AP_POLICY_CONFIG_RADIOS]) { -// fprintf(stderr, "Agent policy config: provide Agent or Radio " \ -// "address in format 11:22:33...\n"); -// return UBUS_STATUS_INVALID_ARGUMENT; -// } -// -// strncpy(agent, blobmsg_data(tb[AP_POLICY_CONFIG_AGENT]), sizeof(agent) - 1); -// if (!hwaddr_aton(agent, hwaddr)) -// return UBUS_STATUS_UNKNOWN_ERROR; -// -// list_for_each_entry(a, &c->cfg.policylist, list) { -// if (!memcmp(hwaddr, a->agent_id, sizeof(hwaddr))) { -// found = a; -// break; -// } -// } -// -// if (!found) -// return UBUS_STATUS_UNKNOWN_ERROR; -// -// /* fetch radio id's */ -// blobmsg_for_each_attr(attr, tb[AP_POLICY_CONFIG_RADIOS], rem) { -// uint8_t bssid[6] = {0}; -// -// if (blobmsg_type(attr) != BLOBMSG_TYPE_STRING) -// continue; -// -// memset(radio, 0, sizeof(radio)); -// strncpy(radio, blobmsg_data(attr), sizeof(radio)-1); -// if (!hwaddr_aton(radio, bssid)) { -// fprintf(stderr, "Agent policy config: provide radio " \ -// "address in format 11:22:33...\n"); -// if (radiolist) -// free(radiolist); -// -// return UBUS_STATUS_UNKNOWN_ERROR; -// } -// -// num_radio++; -// radiolist = (uint8_t *)realloc(radiolist, 6 * num_radio * sizeof(uint8_t)); -// if (!radiolist) -// return UBUS_STATUS_UNKNOWN_ERROR; -// -// memcpy(&radiolist[(num_radio-1)*6], bssid, 6); -// } -// -// if (num_radio == 0) -// return UBUS_STATUS_UNKNOWN_ERROR; -// -// /* fetch BSS list */ -// blobmsg_for_each_attr(attr, tb[AP_POLICY_CONFIG_BSS], rem) { -// uint8_t bssid[6] = {0}; -// -// if (blobmsg_type(attr) != BLOBMSG_TYPE_STRING) -// continue; -// -// memset(bss, 0, sizeof(bss)); -// strncpy(bss, blobmsg_data(attr), sizeof(bss)-1); -// if (!hwaddr_aton(bss, bssid)) { -// fprintf(stderr, "Agent policy config: provide bssid " \ -// "address in format 11:22:33...\n"); -// goto fail_parsing; -// } -// -// num_bss++; -// bsslist = (uint8_t *)realloc(bsslist, 6 * num_bss * sizeof(uint8_t)); -// if (!bsslist) -// goto fail_parsing; -// -// memcpy(&bsslist[(num_bss-1)*6], bssid, 6); -// } -// -// cmdu_data = cntlr_gen_policy_config_req(c, NULL, found, num_radio, -// radiolist, num_bss, bsslist); -// if (!cmdu_data) -// goto fail_parsing; -// -// // TODO: ff:ff:ff:ff:ff:ff = send to all agents -// -// send_cmdu(c, cmdu_data); -// map_free_cmdu(cmdu_data); -// -// if (bsslist) -// free(bsslist); -// -// free(radiolist); -// -// return UBUS_STATUS_OK; -// -//fail_parsing: -// if (bsslist) -// free(bsslist); -// -// free(radiolist); -// -// return UBUS_STATUS_UNKNOWN_ERROR; + char agent[18] = {0}; + char radio[18] = {0}; + char bss[18] = {0}; + uint8_t hwaddr[6] = {0}; + struct cmdu_buff *cmdu; + struct agent_policy *a, *found = NULL; + struct blob_attr *attr = NULL; + uint8_t *radiolist = NULL; + uint8_t *bsslist = NULL; + int rem, num_radio = 0, num_bss = 0; + struct blob_attr *tb[__AP_POLICY_CONFIG_MAX]; + struct controller *c = container_of(obj, struct controller, obj); + + blobmsg_parse(ap_policy_config_params, __AP_POLICY_CONFIG_MAX, tb, + blob_data(msg), blob_len(msg)); + + if (!tb[AP_POLICY_CONFIG_AGENT] || !tb[AP_POLICY_CONFIG_RADIOS]) { + fprintf(stderr, "Agent policy config: provide Agent or Radio " \ + "address in format 11:22:33...\n"); + return UBUS_STATUS_INVALID_ARGUMENT; + } + + strncpy(agent, blobmsg_data(tb[AP_POLICY_CONFIG_AGENT]), sizeof(agent) - 1); + if (!hwaddr_aton(agent, hwaddr)) + return UBUS_STATUS_UNKNOWN_ERROR; + + list_for_each_entry(a, &c->cfg.policylist, list) { + if (!memcmp(hwaddr, a->agent_id, sizeof(hwaddr))) { + found = a; + break; + } + } + + if (!found) + return UBUS_STATUS_UNKNOWN_ERROR; + + /* fetch radio id's */ + blobmsg_for_each_attr(attr, tb[AP_POLICY_CONFIG_RADIOS], rem) { + uint8_t bssid[6] = {0}; + + if (blobmsg_type(attr) != BLOBMSG_TYPE_STRING) + continue; + + memset(radio, 0, sizeof(radio)); + strncpy(radio, blobmsg_data(attr), sizeof(radio)-1); + if (!hwaddr_aton(radio, bssid)) { + fprintf(stderr, "Agent policy config: provide radio " \ + "address in format 11:22:33...\n"); + if (radiolist) + free(radiolist); + + return UBUS_STATUS_UNKNOWN_ERROR; + } + + num_radio++; + radiolist = (uint8_t *)realloc(radiolist, 6 * num_radio * sizeof(uint8_t)); + if (!radiolist) + return UBUS_STATUS_UNKNOWN_ERROR; + + memcpy(&radiolist[(num_radio-1)*6], bssid, 6); + } + + if (num_radio == 0) + return UBUS_STATUS_UNKNOWN_ERROR; + + /* fetch BSS list */ + blobmsg_for_each_attr(attr, tb[AP_POLICY_CONFIG_BSS], rem) { + uint8_t bssid[6] = {0}; + + if (blobmsg_type(attr) != BLOBMSG_TYPE_STRING) + continue; + + memset(bss, 0, sizeof(bss)); + strncpy(bss, blobmsg_data(attr), sizeof(bss)-1); + if (!hwaddr_aton(bss, bssid)) { + fprintf(stderr, "Agent policy config: provide bssid " \ + "address in format 11:22:33...\n"); + goto fail_parsing; + } + + num_bss++; + bsslist = (uint8_t *)realloc(bsslist, 6 * num_bss * sizeof(uint8_t)); + if (!bsslist) + goto fail_parsing; + + memcpy(&bsslist[(num_bss-1)*6], bssid, 6); + } + + cmdu = cntlr_gen_policy_config_req(c, found, num_radio, + radiolist, num_bss, bsslist); + if (!cmdu) + goto fail_parsing; + + send_cmdu(c, cmdu); + cmdu_free(cmdu); + + if (bsslist) + free(bsslist); + + free(radiolist); + + return UBUS_STATUS_OK; + +fail_parsing: + if (bsslist) + free(bsslist); + + free(radiolist); + + return UBUS_STATUS_UNKNOWN_ERROR; } static int cntlr_scan(struct ubus_context *ctx, struct ubus_object *obj,