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,