diff --git a/src/core/cntlr.c b/src/core/cntlr.c
index 2cbc887f7073201e10f0814fa95621c6300671b5..772e7739ac3a8a4a37ca289322cce8c4546c2e3e 100644
--- a/src/core/cntlr.c
+++ b/src/core/cntlr.c
@@ -1780,25 +1780,26 @@ static void cntlr_ubusx_event_handler(struct ubus_context *ctx,
static void cntlr_ieee1905_cmdu_event_handler(void *cntlr,
struct blob_attr *msg)
{
- static const struct blobmsg_policy cmdu_attrs[5] = {
+ static const struct blobmsg_policy cmdu_attrs[6] = {
[0] = { .name = "type", .type = BLOBMSG_TYPE_INT16 },
[1] = { .name = "mid", .type = BLOBMSG_TYPE_INT16 },
[2] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING },
[3] = { .name = "source", .type = BLOBMSG_TYPE_STRING },
- [4] = { .name = "cmdu", .type = BLOBMSG_TYPE_STRING },
+ [4] = { .name = "origin", .type = BLOBMSG_TYPE_STRING },
+ [5] = { .name = "cmdu", .type = BLOBMSG_TYPE_STRING },
};
struct controller *c = (struct controller *)cntlr;
char in_ifname[16] = {0};
- struct blob_attr *tb[5];
- char src[18] = { 0 };
+ struct blob_attr *tb[6];
+ char src[18] = { 0 }, src_origin[18] = { 0 };
uint8_t *tlv = NULL;
char *tlvstr = NULL;
uint16_t type;
- uint8_t srcmac[6];
+ uint8_t srcmac[6], origin[6];
uint16_t mid = 0;
int len = 0;
- blobmsg_parse(cmdu_attrs, 5, tb, blob_data(msg), blob_len(msg));
+ blobmsg_parse(cmdu_attrs, 6, tb, blob_data(msg), blob_len(msg));
if (!tb[0] || !tb[1])
return;
@@ -1822,14 +1823,20 @@ static void cntlr_ieee1905_cmdu_event_handler(void *cntlr,
}
if (tb[4]) {
- len = blobmsg_data_len(tb[4]) - 16;
+ strncpy(src_origin, blobmsg_data(tb[4]), 17);
+ hwaddr_aton(src_origin, origin);
+ }
+
+
+ if (tb[5]) {
+ len = blobmsg_data_len(tb[5]) - 16;
tlvstr = calloc(1, len + 1);
if (!tlvstr)
return;
- strncpy(tlvstr, (blobmsg_data(tb[4]) + 16), len);
+ strncpy(tlvstr, (blobmsg_data(tb[5]) + 16), len);
len = (len - 1) / 2;
tlv = calloc(1, len);
if (!tlv) {
@@ -1841,7 +1848,7 @@ static void cntlr_ieee1905_cmdu_event_handler(void *cntlr,
free(tlvstr);
}
- cntlr_handle_map_event(c, type, mid, in_ifname, srcmac, tlv, len);
+ cntlr_handle_map_event(c, type, mid, in_ifname, srcmac, origin, tlv, len);
if (tlv)
free(tlv);
@@ -2208,7 +2215,8 @@ static void mapclient_subscribe_for_cmdus(struct controller *c)
CMDU_TYPE_VENDOR_SPECIFIC,
CMDU_TYPE_AP_AUTOCONFIGURATION_SEARCH,
CMDU_TYPE_AP_AUTOCONFIGURATION_RESPONSE,
- CMDU_TYPE_AP_AUTOCONFIGURATION_WSC);
+ CMDU_TYPE_AP_AUTOCONFIGURATION_WSC,
+ -1);
trace("<----------------------------------- %s\n", __func__);
diff --git a/src/core/cntlr_cmdu_generator.c b/src/core/cntlr_cmdu_generator.c
index db4441a878fdb85a4fdbc055a373d12f5fb50bbf..4f4d5a6f1a13c13020ce8d7a3f8b9f988fc24183 100644
--- a/src/core/cntlr_cmdu_generator.c
+++ b/src/core/cntlr_cmdu_generator.c
@@ -175,41 +175,28 @@ struct cmdu_buff *cntlr_gen_client_capability_query(struct controller *c,
}
struct cmdu_buff *cntlr_gen_backhaul_steer_request(struct controller *c,
- uint8_t *origin, char *intf_name, uint8_t *bssid,
- uint8_t *bkhaul, uint8_t op_class, uint8_t channel)
+ uint8_t *origin, uint8_t *macaddr, uint8_t *target_bssid,
+ uint8_t op_class, uint8_t channel)
{
- return NULL;
-// struct tlv_backhaul_steer_req *p;
-// struct cmdu_cstruct *cmdu;
-//
-// cmdu = (struct cmdu_cstruct *)calloc(1,
-// sizeof(struct cmdu_cstruct));
-// if (!cmdu) {
-// trace("failed to malloc cmdu\n");
-// return NULL;
-// }
-//
-// cmdu_defaults(c, cmdu, origin, intf_name, CMDU_BACKHAUL_STEER_REQUEST);
-//
-// p = cntlr_gen_backhaul_steer_req(c, bkhaul, bssid, op_class, channel);
-// if (!p)
-// goto fail_cmdu;
-//
-// cmdu->num_tlvs = 1;
-// cmdu->tlvs = (uint8_t **)calloc(cmdu->num_tlvs,
-// sizeof(uint8_t *));
-//
-// if (!cmdu->tlvs)
-// goto fail_p;
-//
-// cmdu->tlvs[0] = (uint8_t *)p;
-//
-// return cmdu;
-//fail_p:
-// map_free_tlv_cstruct((uint8_t *) p);
-//fail_cmdu:
-// map_free_cmdu(cmdu);
-// return NULL;
+ int ret;
+ struct cmdu_buff *resp;
+
+ resp = cmdu_alloc_frame(1500);
+ if (!resp) {
+ trace("%s: -ENOMEM\n", __func__);
+ return -1;
+ }
+
+ cmdu_set_type(resp, CMDU_BACKHAUL_STEER_REQUEST);
+
+ ret = cntlr_gen_backhaul_steer_req(c, resp, macaddr, target_bssid, op_class,
+ channel);
+ if (ret)
+ return -1;
+
+ memcpy(resp->origin, origin, 6);
+ cmdu_put_eom(resp);
+ return 0;
}
struct cmdu_buff *cntlr_gen_ap_metrics_query(struct controller *c,
@@ -587,7 +574,7 @@ out:
}
struct cmdu_buff *cntlr_gen_ap_autoconfig_wsc(struct controller *c,
- struct agent_policy *a, struct cmdu_buff *rec_cmdu,
+ struct agent_policy *a, struct cmdu_buff *rx_cmdu,
struct tlv *basic_cap, struct tlv *wsc,
uint16_t mid)
{
@@ -659,7 +646,7 @@ struct cmdu_buff *cntlr_gen_ap_autoconfig_wsc(struct controller *c,
continue;
}
- memcpy(resp->origin, rec_cmdu->origin, 6);
+ memcpy(resp->origin, rx_cmdu->origin, 6);
cmdu_put_eom(resp);
return resp;
out:
diff --git a/src/core/cntlr_cmdu_generator.h b/src/core/cntlr_cmdu_generator.h
index 9a5f4f8ddf51be20d57a89b5094baa15b5409023..ada19b79a154600ee0f8fa1add538dcb96e682a6 100644
--- a/src/core/cntlr_cmdu_generator.h
+++ b/src/core/cntlr_cmdu_generator.h
@@ -17,7 +17,7 @@ struct cmdu_buff *cntlr_gen_ap_capability_query(struct controller *c,
struct cmdu_buff *cntlr_gen_client_capability_query(struct controller *c,
uint8_t *origin, char *intf_name, uint8_t *sta, uint8_t *bssid);
struct cmdu_buff *cntlr_gen_backhaul_steer_request(struct controller *c,
- uint8_t *origin, char *intf_name, uint8_t *bssid,
+ uint8_t *origin, uint8_t *bssid,
uint8_t *bkhaul, uint8_t op_class, uint8_t channel);
struct cmdu_buff *cntlr_gen_ap_metrics_query(struct controller *c,
uint8_t *origin, char *intf_name, int num_bss,
diff --git a/src/core/cntlr_map.c b/src/core/cntlr_map.c
index 9125f87ff1e67c236edfcdfda7e8d27d68df44ef..07475bf176df1b9e1c88dd14ed09335380754c0d 100644
--- a/src/core/cntlr_map.c
+++ b/src/core/cntlr_map.c
@@ -154,8 +154,8 @@ uint16_t send_cmdu(struct controller *a, struct cmdu_buff *cmdu)
free(tlv_str);
}
- if (ubus_lookup_id(a->ubus_ctx, "i1905.al.eth1", &id)) {
- trace("[%s:%d] not present i1905.al.eth1", __func__, __LINE__);
+ if (ubus_lookup_id(a->ubus_ctx, "i1905", &id)) {
+ trace("[%s:%d] not present i1905", __func__, __LINE__);
goto out;
}
@@ -164,7 +164,7 @@ uint16_t send_cmdu(struct controller *a, struct cmdu_buff *cmdu)
&msgid,
1000);
if (ret) {
- trace("[%s:%d] ubus call failed for |i1905.al.eth1 send|",
+ trace("[%s:%d] ubus call failed for |i1905 send|",
__func__, __LINE__);
goto out;
}
@@ -276,6 +276,7 @@ int handle_ap_autoconfig_search(void *cntlr, struct cmdu_buff *rec_cmdu)
return -1;
+ memcpy(cmdu->origin, aladdr_origin, 6);
ret = send_cmdu(c, cmdu);
cmdu_free(cmdu);
@@ -328,7 +329,7 @@ int handle_ap_autoconfig_response(void *cntlr, struct cmdu_buff *cmdu)
// return 0;
}
-int handle_ap_autoconfig_wsc(void *cntlr, struct cmdu_buff *rec_cmdu)
+int handle_ap_autoconfig_wsc(void *cntlr, struct cmdu_buff *rx_cmdu)
{
trace("%s: --->\n", __func__);
struct controller *c = (struct controller *) cntlr;
@@ -340,22 +341,17 @@ int handle_ap_autoconfig_wsc(void *cntlr, struct cmdu_buff *rec_cmdu)
[3] = { .type = TLV_TYPE_WSC, .present = TLV_PRESENT_ONE }
};
struct cmdu_buff *cmdu;
- uint8_t aladdr_origin[6] = {0};
struct tlv *tv[4][16] = {0};
bool agent_found;
int ret = 0;
- ret = cmdu_parse_tlvs(rec_cmdu, tv, a_policy, 4);
+ ret = cmdu_parse_tlvs(rx_cmdu, tv, a_policy, 4);
if (!tv[0][0] || !tv[1][0] || !tv[2][0] || !tv[3][0])
return -1;
- /* TODO: workaround to local address */
- if (hwaddr_is_zero(rec_cmdu->origin))
- memcpy(rec_cmdu->origin, c->almac, 6);
-
list_for_each_entry(a, &c->cfg.policylist, list) {
- if (!memcmp(rec_cmdu->origin, a->agent_id, 6)) {
+ if (!memcmp(rx_cmdu->dev_macaddr, a->agent_id, 6)) {
agent_found = true;
break;
}
@@ -364,8 +360,8 @@ int handle_ap_autoconfig_wsc(void *cntlr, struct cmdu_buff *rec_cmdu)
return -1;
trace("%s: prepare autoconfig wsc response\n", __func__);
- cmdu = cntlr_gen_ap_autoconfig_wsc(cntlr, a, rec_cmdu, tv[1][0], tv[3][0],
- cmdu_get_mid(rec_cmdu));
+ cmdu = cntlr_gen_ap_autoconfig_wsc(cntlr, a, rx_cmdu, tv[1][0], tv[3][0],
+ cmdu_get_mid(rx_cmdu));
if (!cmdu)
return -1;
@@ -641,7 +637,7 @@ bool is_cmdu_for_us(void *module, uint16_t type)
}
int cntlr_handle_map_event(void *module, uint16_t cmdutype, uint16_t mid,
- char *rxif, uint8_t *src, uint8_t *tlvs, int len)
+ char *rxif, uint8_t *src, uint8_t *origin, uint8_t *tlvs, int len)
{
struct controller *c = (struct controller *)module;
const struct map_cmdu_calltable_t *f;
@@ -664,7 +660,7 @@ int cntlr_handle_map_event(void *module, uint16_t cmdutype, uint16_t mid,
dbg("%s: cmdu_alloc_custom() failed!\n", __func__);
return -1;
}
-
+ memcpy(cmdu->origin, origin, 6);
dbg("%s: cmdu_alloc_custom() succeeded! cmdu->cdata->hdr.mid %u\n", __func__, cmdu_get_mid(cmdu));
if (f[idx].handle)
diff --git a/src/core/cntlr_map.h b/src/core/cntlr_map.h
index 8ef9c247eeaf0e8c3f32b210b73128fed0d80cbe..94d775b94354594f1b093ea27598b21f1442369a 100644
--- a/src/core/cntlr_map.h
+++ b/src/core/cntlr_map.h
@@ -6,12 +6,10 @@
extern bool is_cmdu_for_us(void *module, uint16_t type);
extern int cntlr_handle_map_event(void *module, uint16_t cmdutype, uint16_t mid,
- char *rxif, uint8_t *src, uint8_t *tlvs,
+ char *rxif, uint8_t *src, uint8_t *origin, uint8_t *tlvs,
int len);
void send_cmdu_cb(struct ubus_request *req, int type, struct blob_attr *msg);
uint16_t send_cmdu(struct controller *a, struct cmdu_buff *cmdu);
-int cntlr_handle_map_event(void *module, uint16_t cmdutype, uint16_t mid,
- char *rxif, uint8_t *src, uint8_t *tlvs, int len);
#endif /* CNTLR_MAP_H */
diff --git a/src/core/cntlr_tlv_generator.c b/src/core/cntlr_tlv_generator.c
index 2c23dd4870bede9d084cd68f7f9cde6b6a774132..a5de78374b7364b9470a58e1634f4e480e1f7f59 100644
--- a/src/core/cntlr_tlv_generator.c
+++ b/src/core/cntlr_tlv_generator.c
@@ -633,24 +633,33 @@ struct tlv_client_info *cntlr_gen_client_info(struct controller *c,
// return p;
}
-struct tlv_backhaul_steer_req *cntlr_gen_backhaul_steer_req(struct controller *c,
- uint8_t *bssid, uint8_t *bkhaul, uint8_t op_class,
+int cntlr_gen_backhaul_steer_req(struct controller *c, struct cmdu_buff *frm,
+ uint8_t *target_bssid, uint8_t *macaddr, uint8_t op_class,
uint8_t channel)
{
- return NULL;
-// struct tlv_backhaul_steer_req *p;
-//
-// p = calloc(1, sizeof(struct tlv_backhaul_steer_req));
-// if (!p)
-// return NULL;
-//
-// p->tlv_type = MAP_TLV_BACKHAUL_STEERING_REQUEST;
-// memcpy(p->bssid, bssid, 6);
-// memcpy(p->addr, bkhaul, 6);
-//
-// p->channel = channel;
-// p->op_class = op_class;
-// return p;
+ struct tlv *t;
+ struct tlv_backhaul_steer_request *data;
+ int ret;
+
+ t = cmdu_reserve_tlv(frm, 256);
+ if (!t)
+ return -1;
+
+ t->type = MAP_TLV_BACKHAUL_STEERING_REQUEST;
+ t->len = 14;
+ data = (struct tlv_backhaul_steer_request *) t->data;
+ memcpy(data->target_bssid, target_bssid, 6);
+ memcpy(data->macaddr, macaddr, 6);
+ data->target_opclass = op_class;
+ data->target_channel = channel;
+
+ ret = cmdu_put_tlv(frm, t);
+ if (ret) {
+ dbg("%s: error: cmdu_put_tlv()\n", __func__);
+ return -1;
+ }
+
+ return 0;
}
struct tlv_steer_request *cntlr_gen_client_steering_req(
diff --git a/src/core/cntlr_tlv_generator.h b/src/core/cntlr_tlv_generator.h
index cca6f7a9cd248930b0db708593cfb20d58757b28..3b11b5240f382f4cb2cae08b9584f5a1c74e628f 100644
--- a/src/core/cntlr_tlv_generator.h
+++ b/src/core/cntlr_tlv_generator.h
@@ -46,8 +46,8 @@ struct tlv_supported_role *cntlr_gen_supported_role(struct controller *c,
uint8_t role);
struct tlv_client_info *cntlr_gen_client_info(struct controller *c,
uint8_t *sta, uint8_t *bssid);
-struct tlv_backhaul_steer_req *cntlr_gen_backhaul_steer_req(struct controller *c,
- uint8_t *bssid, uint8_t *bkhaul, uint8_t op_class,
+int cntlr_gen_backhaul_steer_req(struct controller *c, struct cmdu_buff *frm,
+ uint8_t *target_bssid, uint8_t *macaddr, uint8_t op_class,
uint8_t channel);
struct tlv_steer_request *cntlr_gen_client_steering_req(
char *bss_id, uint32_t steer_timeout,
diff --git a/src/core/cntlr_ubus.c b/src/core/cntlr_ubus.c
index a0e0b559748684a799633e4a641f08ab68ba553e..b85477cb4406f374afa877e3381fc0f2cddb6da4 100644
--- a/src/core/cntlr_ubus.c
+++ b/src/core/cntlr_ubus.c
@@ -1219,58 +1219,53 @@ static int cntlr_bk_steer(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
+ struct blob_attr *tb[__BK_STEER_POLICY_MAX];
+ struct controller *c = container_of(obj, struct controller, obj);
+ char agent_str[18] = {0}, bssid_str[18] = {0}, bkhaul_str[18] = {0};
+ uint8_t agent[6] = {0}, bssid[6] = {0}, bkhaul[6] = {0};
+ struct cmdu_cstruct *cmdu;
+ uint8_t op_class = 0, channel = 0;
+
+ blobmsg_parse(bk_steer_policy_params, __BK_STEER_POLICY_MAX, tb,
+ blob_data(msg), blob_len(msg));
+
+ if (!tb[BK_STEER_POLICY_BSSID] || !tb[BK_STEER_POLICY_STA_MAC]) {
+ fprintf(stderr, "BSSID and MAC required\n");
+ return UBUS_STATUS_INVALID_ARGUMENT;
+ }
+
+ strncpy(bssid_str, blobmsg_data(tb[BK_STEER_POLICY_BSSID]),
+ sizeof(bssid_str) - 1);
+ strncpy(bkhaul_str, blobmsg_data(tb[BK_STEER_POLICY_STA_MAC]),
+ sizeof(bkhaul_str) - 1);
+
+ if (!hwaddr_aton(bssid_str, bssid) || !hwaddr_aton(bkhaul_str, bkhaul)) {
+ fprintf(stderr, "MAC must be in format 11:22:33...\n");
+ return UBUS_STATUS_INVALID_ARGUMENT;
+ }
+
+
+ if (tb[BK_STEER_POLICY_AGENT]) {
+ strncpy(agent_str, blobmsg_data(tb[BK_STEER_POLICY_AGENT]),
+ sizeof(agent_str) - 1);
+ if (!hwaddr_aton(agent_str, agent))
+ return UBUS_STATUS_INVALID_ARGUMENT;
+ }
+
+ if (tb[BK_STEER_POLICY_CHANNEL])
+ channel = blobmsg_get_u8(tb[BK_STEER_POLICY_CHANNEL]);
+ if (tb[BK_STEER_POLICY_OP_CLASS])
+ op_class = blobmsg_get_u8(tb[BK_STEER_POLICY_OP_CLASS]);
+
+ cmdu = cntlr_gen_backhaul_steer_request(c, agent, bssid, bkhaul,
+ op_class, channel);
+ if (!cmdu)
+ return UBUS_STATUS_UNKNOWN_ERROR;
+
+ send_cmdu(c, cmdu);
+ cmdu_free(cmdu);
+
return 0;
-// struct blob_attr *tb[__BK_STEER_POLICY_MAX];
-// struct controller *c = container_of(obj, struct controller, obj);
-// char agent_str[18] = {0}, bssid_str[18] = {0}, bkhaul_str[18] = {0};
-// uint8_t agent[6] = {0}, bssid[6] = {0}, bkhaul[6] = {0};
-// struct cmdu_cstruct *cmdu;
-// uint8_t op_class, channel;
-//
-// blobmsg_parse(bk_steer_policy_params, __BK_STEER_POLICY_MAX, tb,
-// blob_data(msg), blob_len(msg));
-//
-// if (!tb[BK_STEER_POLICY_BSSID] || !tb[BK_STEER_POLICY_CHANNEL] ||
-// !tb[BK_STEER_POLICY_OP_CLASS] ||
-// !tb[BK_STEER_POLICY_STA_MAC]) {
-// fprintf(stderr, "BSSID, channel and op class required!\n");
-// return UBUS_STATUS_INVALID_ARGUMENT;
-// }
-//
-// strncpy(bssid_str, blobmsg_data(tb[BK_STEER_POLICY_BSSID]),
-// sizeof(bssid_str) - 1);
-// strncpy(bkhaul_str, blobmsg_data(tb[BK_STEER_POLICY_STA_MAC]),
-// sizeof(bkhaul_str) - 1);
-//
-// if (!hwaddr_aton(bssid_str, bssid)) {
-// fprintf(stderr, "BSSID must be in format 11:22:33...\n");
-// return UBUS_STATUS_INVALID_ARGUMENT;
-// }
-//
-// if (!hwaddr_aton(bkhaul_str, bkhaul)) {
-// fprintf(stderr, "Backhaul must be in format 11:22:33...\n");
-// return UBUS_STATUS_INVALID_ARGUMENT;
-// }
-//
-// if (tb[AP_POLICY_AGENT]) {
-// strncpy(agent_str, blobmsg_data(tb[AP_POLICY_AGENT]),
-// sizeof(agent_str) - 1);
-// if (!hwaddr_aton(agent_str, agent))
-// return UBUS_STATUS_INVALID_ARGUMENT;
-// }
-//
-// channel = blobmsg_get_u8(tb[BK_STEER_POLICY_CHANNEL]);
-// op_class = blobmsg_get_u8(tb[BK_STEER_POLICY_OP_CLASS]);
-//
-// cmdu = cntlr_gen_backhaul_steer_request(c, agent, NULL, bssid, bkhaul,
-// op_class, channel);
-// if (!cmdu)
-// return UBUS_STATUS_UNKNOWN_ERROR;
-//
-// send_cmdu(c, cmdu);
-// map_free_cmdu(cmdu);
-//
-// return 0;
}
static int cntlr_ap_policy_config(struct ubus_context *ctx, struct ubus_object *obj,