Skip to content
Snippets Groups Projects
Commit ffef7303 authored by Nevadita's avatar Nevadita Committed by Jakob Olsson
Browse files

map-controller: Adding changes for section 8.2 channel selection

parent dccf9561
Branches
No related tags found
1 merge request!4map-controller: Adding changes for section 8.2 channel selection
Pipeline #7860 failed
...@@ -411,12 +411,78 @@ int debug_channel_pref_report(void *cntlr, struct cmdu_cstruct *cmdu) ...@@ -411,12 +411,78 @@ int debug_channel_pref_report(void *cntlr, struct cmdu_cstruct *cmdu)
int debug_channel_sel_response(void *cntlr, struct cmdu_cstruct *cmdu) int debug_channel_sel_response(void *cntlr, struct cmdu_cstruct *cmdu)
{ {
trace("%s: --->\n", __func__); trace("%s: --->\n", __func__);
trace("parsing channel selection response of |%s:" MACFMT "|\n",
cmdu->intf_name,
MAC2STR(cmdu->origin));
int i;
uint8_t *tlv = NULL;
for (i = 0; i < cmdu->num_tlvs; i++) {
tlv = (uint8_t *) cmdu->tlvs[i];
trace("CMDU type: %s\n", map_stringify_tlv_type(*tlv));
switch (*tlv) {
case MAP_TLV_CHANNEL_SELECTION_RESPONSE:
{
struct tlv_ch_selection_resp *p =
(struct tlv_ch_selection_resp *)tlv;
trace("\tradio_id: " MACFMT "\n",
MAC2STR(p->radio_id));
trace("\tresponse_code: %d\n",
p->response_code);
break;
}
default:
fprintf(stdout, "unknown TLV in CMDU:|%s|",
map_stringify_cmdu_type(cmdu->message_type));
break;
}
trace("\n");
}
return 0; return 0;
} }
int debug_oper_channel_report(void *cntlr, struct cmdu_cstruct *cmdu) int debug_oper_channel_report(void *cntlr, struct cmdu_cstruct *cmdu)
{ {
trace("%s: --->\n", __func__); trace("%s: --->\n", __func__);
trace("parsing operating channel report of |%s:" MACFMT "|\n",
cmdu->intf_name,
MAC2STR(cmdu->origin));
int i, j;
uint8_t *tlv = NULL;
for (i = 0; i < cmdu->num_tlvs; i++) {
tlv = (uint8_t *) cmdu->tlvs[i];
trace("CMDU type: %s\n", map_stringify_tlv_type(*tlv));
switch (*tlv) {
case MAP_TLV_OPERATING_CHANNEL_REPORT:
{
struct tlv_oper_ch_report *p =
(struct tlv_oper_ch_report *)tlv;
trace("\tradio_id: " MACFMT "\n",
MAC2STR(p->radio_id));
trace("\tch_preference_op_class_nr: %d\n",
p->op_ch_op_class_nr);
for (j = 0; j < p->op_ch_op_class_nr; j++) {
trace("\t\top_class: %d\n",
p->op_ch_op_class[j].op_class);
trace("\t\top_channel: %d\n",
p->op_ch_op_class[j].channel);
}
trace("\tcurr_tx_power: %d\n",
p->curr_tx_power);
break;
}
default:
fprintf(stdout, "unknown TLV in CMDU:|%s|",
map_stringify_cmdu_type(cmdu->message_type));
break;
}
trace("\n");
}
return 0; return 0;
} }
......
...@@ -71,6 +71,25 @@ static const struct blobmsg_policy channel_pref_policy_params[__CHANNEL_PREF_POL ...@@ -71,6 +71,25 @@ static const struct blobmsg_policy channel_pref_policy_params[__CHANNEL_PREF_POL
[CHANNEL_PREF_POLICY_AGENT] = { .name = "agent", .type = BLOBMSG_TYPE_STRING } [CHANNEL_PREF_POLICY_AGENT] = { .name = "agent", .type = BLOBMSG_TYPE_STRING }
}; };
enum {
CHANNEL_SEL_POLICY_AGENT,
CHANNEL_SEL_POLICY_RADIO_ID,
CHANNEL_SEL_POLICY_CLASS_ID,
CHANNEL_SEL_POLICY_CHANNEL,
CHANNEL_SEL_POLICY_PREF,
CHANNEL_SEL_POLICY_TRANSMIT_POWER,
__CHANNEL_SEL_POLICY_MAX,
};
static const struct blobmsg_policy channel_select_policy_params[__CHANNEL_SEL_POLICY_MAX] = {
[CHANNEL_SEL_POLICY_AGENT] = { .name = "agent", .type = BLOBMSG_TYPE_STRING },
[CHANNEL_SEL_POLICY_RADIO_ID] = { .name = "radio_id", .type = BLOBMSG_TYPE_STRING },
[CHANNEL_SEL_POLICY_CLASS_ID] = { .name = "class_id", .type = BLOBMSG_TYPE_INT32 },
[CHANNEL_SEL_POLICY_CHANNEL] = { .name = "channel", .type = BLOBMSG_TYPE_ARRAY },
[CHANNEL_SEL_POLICY_PREF] = { .name = "preference", .type = BLOBMSG_TYPE_INT32 },
[CHANNEL_SEL_POLICY_TRANSMIT_POWER] = { .name = "transmit_power", .type = BLOBMSG_TYPE_INT32 }
};
enum { enum {
CFG_POLICY_AGENT, CFG_POLICY_AGENT,
CFG_POLICY_RADIO, CFG_POLICY_RADIO,
...@@ -411,6 +430,151 @@ static int cntlr_channel_pref(struct ubus_context *ctx, struct ubus_object *obj, ...@@ -411,6 +430,151 @@ static int cntlr_channel_pref(struct ubus_context *ctx, struct ubus_object *obj,
return 0; return 0;
} }
static int cntlr_channel_select(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
struct blob_attr *tb[__CHANNEL_SEL_POLICY_MAX];
struct controller *c = container_of(obj, struct controller, obj);
struct tlv_channel_pref *p = NULL;
struct tlv_tx_power_limit *p1 = NULL;
uint32_t count = 0, tlv_index = 0, k = 0, j = 0;
char agent[18] = {0};
char radio_id[18] = {0};
uint32_t radio_present = 0;
uint32_t class_id = -1;
uint32_t channel_nr = 0, pref = -1, transmit_power = -1;
uint32_t channel[20];
struct cmdu_cstruct *cmdu_data;
struct blob_attr *cur;
int rem, l = 0;
cmdu_data = (struct cmdu_cstruct *)calloc(1,
sizeof(struct cmdu_cstruct));
if (!cmdu_data) {
fprintf(stderr, "failed to malloc cmdu\n");
return UBUS_STATUS_UNKNOWN_ERROR;
}
blobmsg_parse(channel_select_policy_params, __CHANNEL_SEL_POLICY_MAX,
tb, blob_data(msg), blob_len(msg));
if (tb[CHANNEL_SEL_POLICY_AGENT]) {
strncpy(agent, blobmsg_data(tb[CHANNEL_SEL_POLICY_AGENT]),
sizeof(agent) - 1);
if (!hwaddr_aton(agent, cmdu_data->origin))
goto fail_cmdu;
}
// TODO: ff:ff:ff:ff:ff:ff = send to all agents
if (tb[CHANNEL_SEL_POLICY_RADIO_ID]) {
strncpy(radio_id, blobmsg_data(tb[CHANNEL_SEL_POLICY_RADIO_ID]),
sizeof(radio_id) - 1);
radio_present = 1;
}
if (tb[CHANNEL_SEL_POLICY_CLASS_ID])
class_id = (int) blobmsg_get_u32(tb[CHANNEL_SEL_POLICY_CLASS_ID]);
if (tb[CHANNEL_SEL_POLICY_CHANNEL]) {
channel_nr = blobmsg_check_array(tb[CHANNEL_SEL_POLICY_CHANNEL],
BLOBMSG_TYPE_INT32);
l = 0;
blobmsg_for_each_attr(cur, tb[CHANNEL_SEL_POLICY_CHANNEL], rem)
channel[l++] = blobmsg_get_u32(cur);
}
if (tb[CHANNEL_SEL_POLICY_PREF])
pref = (int) blobmsg_get_u32(tb[CHANNEL_SEL_POLICY_PREF]);
if (tb[CHANNEL_SEL_POLICY_TRANSMIT_POWER])
transmit_power = (int) blobmsg_get_u32
(tb[CHANNEL_SEL_POLICY_TRANSMIT_POWER]);
cmdu_data->message_type = CMDU_CHANNEL_SELECTION_REQ;
if (radio_present == 1 && class_id != -1 && pref != -1) {
p = calloc(1, sizeof(struct tlv_channel_pref));
if (!p) {
fprintf(stderr, "failed to malloc cmdu\n");
goto fail_cmdu;
}
p->tlv_type = MAP_TLV_CHANNEL_PREFERENCE;
hwaddr_aton(radio_id, p->radio_id);
p->ch_preference_op_class_nr = 1;
if (p->ch_preference_op_class_nr > 0)
p->op_class = calloc(p->ch_preference_op_class_nr,
sizeof(*p->op_class));
if (!p->op_class) {
fprintf(stderr, "|%s:%d| out of memory!\n", __func__, __LINE__);
p->ch_preference_op_class_nr = 0;
goto fail_p;
}
for (j = 0; j < p->ch_preference_op_class_nr; j++) {
p->op_class[j].op_class = (uint8_t)class_id;
p->op_class[j].channel_list = NULL;
if (channel_nr != 0)
p->op_class[j].channel_nr = channel_nr;
if (p->op_class[j].channel_nr > 0) {
p->op_class[j].channel_list =
calloc(p->op_class[j].channel_nr,
sizeof(uint8_t));
if (!p->op_class[j].channel_list) {
fprintf(stderr, "|%s:%d| out of memory!\n",
__func__, __LINE__);
p->op_class[j].channel_nr = 0;
goto fail_p;
}
for (k = 0; k < p->op_class[j].channel_nr; k++)
p->op_class[j].channel_list[k] = (uint8_t) channel[k];
}
p->op_class[j].preference = (uint8_t) pref;
p->op_class[j].preference_reason = 0x00;
}
count++;
}
if (radio_present == 1 && transmit_power != -1) {
p1 = calloc(1, sizeof(struct tlv_tx_power_limit));
if (!p1) {
fprintf(stderr, "failed to malloc cmdu\n");
goto fail_p;
}
p1->tlv_type = MAP_TLV_TRANSMIT_POWER_LIMIT;
hwaddr_aton(radio_id, p1->radio_id);
p1->tx_power_limit = (uint8_t)transmit_power;
count++;
}
cmdu_data->num_tlvs = count;
if (count)
cmdu_data->tlvs = (uint8_t **)calloc(cmdu_data->num_tlvs,
sizeof(uint8_t *));
if (cmdu_data->tlvs && p != NULL)
cmdu_data->tlvs[tlv_index++] = (uint8_t *)p;
if (cmdu_data->tlvs && p1 != NULL)
cmdu_data->tlvs[tlv_index++] = (uint8_t *)p1;
send_cmdu(c, cmdu_data);
map_free_cmdu(cmdu_data);
return 0;
fail_p:
map_free_tlv_cstruct((uint8_t *) p);
fail_cmdu:
map_free_cmdu(cmdu_data);
return UBUS_STATUS_UNKNOWN_ERROR;
}
static int cntlr_sta_caps(struct ubus_context *ctx, struct ubus_object *obj, static int cntlr_sta_caps(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct ubus_request_data *req, const char *method,
...@@ -980,14 +1144,15 @@ int cntlr_publish_object(struct controller *c, const char *objname) ...@@ -980,14 +1144,15 @@ int cntlr_publish_object(struct controller *c, const char *objname)
struct ubus_object *obj; struct ubus_object *obj;
struct ubus_object_type *obj_type; struct ubus_object_type *obj_type;
struct ubus_method *obj_methods; struct ubus_method *obj_methods;
struct ubus_method m[6] = { struct ubus_method m[7] = {
UBUS_METHOD_NOARG("status", cntlr_status), UBUS_METHOD_NOARG("status", cntlr_status),
UBUS_METHOD("ap_caps", cntlr_ap_caps, ap_caps_policy_params), UBUS_METHOD("ap_caps", cntlr_ap_caps, ap_caps_policy_params),
UBUS_METHOD("sta_caps", cntlr_sta_caps, sta_caps_policy_params), UBUS_METHOD("sta_caps", cntlr_sta_caps, sta_caps_policy_params),
UBUS_METHOD("channels", cntlr_channel_pref, UBUS_METHOD("channels", cntlr_channel_pref,
channel_pref_policy_params), channel_pref_policy_params),
UBUS_METHOD("bk_steer", cntlr_bk_steer, bk_steer_policy_params), UBUS_METHOD("bk_steer", cntlr_bk_steer, bk_steer_policy_params),
UBUS_METHOD("agent_policy", cntlr_ap_policy_config, ap_policy_config_params) UBUS_METHOD("agent_policy", cntlr_ap_policy_config, ap_policy_config_params),
UBUS_METHOD("channel", cntlr_channel_select, channel_select_policy_params)
/* /*
UBUS_METHOD("teardown_ap", cntlr_teardown_ap, UBUS_METHOD("teardown_ap", cntlr_teardown_ap,
config_policy_params), config_policy_params),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment