Skip to content
Snippets Groups Projects
Commit 1c54af85 authored by Jakob Olsson's avatar Jakob Olsson
Browse files

add ap capability handling and request

parent 30917325
No related branches found
No related tags found
No related merge requests found
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <libubox/utils.h> #include <libubox/utils.h>
#include <libubus.h> #include <libubus.h>
#include <easy/easy.h>
#include "map_module.h" #include "map_module.h"
#include "utils.h" #include "utils.h"
...@@ -88,8 +89,88 @@ int handle_1905_ack(void *cntlr, struct cmdu_cstruct *cmdu) ...@@ -88,8 +89,88 @@ int handle_1905_ack(void *cntlr, struct cmdu_cstruct *cmdu)
return 0; return 0;
} }
static bool ap_caps_info_from_tlv(struct controller *c,
struct cmdu_cstruct *cmdu_data)
{
int i, j, k;
int radio_index, bss_index;
uint8_t *tlv = NULL;
for (i = 0; i < cmdu_data->num_tlvs; i++) {
tlv = cmdu_data->tlvs[i];
trace("CMDU type: %s\n", map_stringify_tlv_type(*tlv));
switch (*tlv) {
case MAP_TLV_AP_CAPABILITY:
{
struct tlv_ap_cap *p = (struct tlv_ap_cap *)tlv;
trace("\top_ch_metric_reporting: %d\n", p->op_ch_metric_reporting);
trace("\tnon_op_ch_metric_reporting: %d\n", p->non_op_ch_metric_reporting);
trace("\tagent_init_rcpi_steering: %d\n", p->agent_init_rcpi_steering);
break;
}
case MAP_TLV_AP_RADIO_BASIC_CAPABILITIES:
{
struct tlv_ap_radio_basic_cap *p = (struct tlv_ap_radio_basic_cap *)tlv;
trace("\tradio_id: " MACFMT "\n", MAC2STR(p->radio_id));
trace("\tmax_bss_nr: %d\n", p->max_bss_nr);
trace("\toperating_classes_nr: %d\n", p->operating_classes_nr);
for (j = 0; j < p->operating_classes_nr; j++) {
trace("\t\top_class: %d\n", p->operating_class[j].op_class);
trace("\t\tmax_tx_power: %d\n", p->operating_class[j].max_tx_power);
trace("\t\tnon_op_ch_nr: %d\n", p->operating_class[j].non_op_ch_nr);
for (k = 0; k < p->operating_class[j].non_op_ch_nr; k++)
trace("\t\t\tchannel: %d\n", p->operating_class[j].channel[k]);
}
break;
}
case MAP_TLV_AP_HT_CAPABILITIES:
{
struct tlv_ap_ht_cap *p = (struct tlv_ap_ht_cap *)tlv;
trace("\tradio_id: " MACFMT "\n", MAC2STR(p->radio_id));
trace("\tmax_tx_streams_supported: %02x\n", p->max_tx_streams_supported);
trace("\tmax_rx_streams_supported: %02x\n", p->max_rx_streams_supported);
trace("\tgi_20_support: %s\n", (p->gi_20_support ? "true" : "false"));
trace("\tgi_40_support: %s\n", (p->gi_40_support ? "true" : "false"));
trace("\tht_40_support: %s\n", (p->ht_40_support ? "true" : "false"));
break;
}
case MAP_TLV_AP_VHT_CAPABILITIES:
{
struct tlv_ap_vht_cap *p = (struct tlv_ap_vht_cap *)tlv;
trace("\tradio_id: " MACFMT "\n", MAC2STR(p->radio_id));
trace("\tvht_tx_mcs_supported: %04x\n", p->vht_tx_mcs_supported);
trace("\tvht_rx_mcs_supported: %04x\n", p->vht_rx_mcs_supported);
trace("\tmax_tx_streams_supported: %02x\n", p->max_tx_streams_supported);
trace("\tmax_rx_streams_supported: %02x\n", p->max_rx_streams_supported);
trace("\tgi_80_support: %s\n", (p->gi_80_support ? "true" : "false"));
trace("\tgi_160_support: %s\n", (p->gi_160_support ? "true" : "false"));
trace("\tvht160_support: %s\n", (p->vht_160_support ? "true" : "false"));
trace("\tsu_beamformer_capable: %s\n", (p->su_beamformer_capable ? "true" : "false"));
trace("\tmu_beamformer_capable: %s\n", (p->mu_beamformer_capable ? "true" : "false"));
break;
}
default:
fprintf(stdout, "unknown TLV in CMDU:|%s|", map_stringify_cmdu_type(cmdu_data->message_type));
break;
}
trace("\n");
}
return 0;
}
int handle_ap_caps_report(void *cntlr, struct cmdu_cstruct *cmdu) int handle_ap_caps_report(void *cntlr, struct cmdu_cstruct *cmdu)
{ {
trace("%s: --->\n", __func__);
trace("parsing AP capabilities of |%s:" MACFMT "|\n", cmdu->intf_name, MAC2STR(cmdu->origin));
ap_caps_info_from_tlv(cntlr, cmdu);
return 0; return 0;
} }
...@@ -115,6 +196,7 @@ int handle_oper_channel_report(void *cntlr, struct cmdu_cstruct *cmdu) ...@@ -115,6 +196,7 @@ int handle_oper_channel_report(void *cntlr, struct cmdu_cstruct *cmdu)
int handle_sta_caps_report(void *cntlr, struct cmdu_cstruct *cmdu) int handle_sta_caps_report(void *cntlr, struct cmdu_cstruct *cmdu)
{ {
trace("received sta caps report!\n");
return 0; return 0;
} }
......
...@@ -31,6 +31,150 @@ ...@@ -31,6 +31,150 @@
#include "map_module.h" #include "map_module.h"
#include <map1905/map2.h>
#include <map1905/maputils.h>
enum {
AP_POLICY_AGENT,
//AP_POLICY_BSSID,
__AP_POLICY_MAX,
};
static const struct blobmsg_policy ap_caps_policy_params[__AP_POLICY_MAX] = {
[AP_POLICY_AGENT] = { .name = "agent", .type = BLOBMSG_TYPE_STRING }, // agent = ieee1905 AL macaddress of an agent, agent = "ff:ff:ff:ff:ff:ff" means all agents
//[AP_POLICY_BSSID] = { .name = "bssid", .type = BLOBMSG_TYPE_STRING }
};
static void send_cmdu_cb(struct ubus_request *req,
int type, struct blob_attr *msg)
{
struct json_object *jobj = NULL;
struct json_object *tmp;
uint16_t *mid;
char *str;
if (!msg || !req->priv) {
fprintf(stderr, "%s:Message recieved is NULL\n", __func__);
return;
}
mid = (uint16_t *)req->priv;
str = (char *)blobmsg_format_json_indent(msg, true, -1);
if (str) {
jobj = json_tokener_parse(str);
free(str);
}
if (jobj == NULL)
return;
if (json_object_object_get_ex(jobj, "mid", &tmp)) {
*mid = json_object_get_int(tmp);
fprintf(stdout, "%s:%d map-mid:%d\n", __func__, __LINE__, *mid);
}
json_object_put(jobj);
}
static int send_cmdu(struct controller *c,
struct cmdu_cstruct *cmdu_data)
{
char *tlv_data = NULL;
uint16_t tlv_data_len = 1;
uint16_t tlv_str_len = 0;
int copy_index;
struct blob_buf b = { 0 };
char dst_addr[18] = { 0 };
char tlv_str[512] = { 0 };
uint8_t is_store_mid = 1;
uint8_t *ss = NULL;
uint16_t msgid = 0;
uint16_t len;
int ret = 0;
size_t i;
uint32_t id;
struct ieee1905_cmdu_msg *cmsg = NULL;
fprintf(stdout, "|%s:%d| Entry \n", __func__, __LINE__);
memset(&b, 0, sizeof(struct blob_buf));
blob_buf_init(&b, 0);
blobmsg_add_u32(&b, "type", cmdu_data->message_type);
blobmsg_add_string(&b, "egress", cmdu_data->intf_name);
blobmsg_add_u32(&b, "mid", cmdu_data->message_id);
hwaddr_ntoa(cmdu_data->origin, dst_addr);
blobmsg_add_string(&b, "dst_macaddr", dst_addr);
fprintf(stdout, "|%s:%d|cmdu:%s|dst:%s|\n", __func__, __LINE__,
map_stringify_cmdu_type(cmdu_data->message_type), dst_addr);
if (cmdu_data->num_tlvs > 0) {
for (i = 0; i < cmdu_data->num_tlvs; i++) {
len = 0;
ss = map_put_tlv_cstruct(cmdu_data->tlvs[i], &len);
if (ss) {
btostr(ss, len, tlv_str);
tlv_str_len = 2 * len;
tlv_data_len += tlv_str_len;
tlv_data = realloc(tlv_data, tlv_data_len * sizeof(char));
if (!tlv_data) {
fprintf(stderr, "%s:%d out of memory.!\n", __func__, __LINE__);
free(ss);
goto out;
}
copy_index = tlv_data_len - tlv_str_len - 1;
memcpy(tlv_data + copy_index, tlv_str, tlv_str_len);
memset(tlv_str, 0, sizeof(tlv_str));
free(ss);
}
}
tlv_data[tlv_data_len - 1] = '\0';
blobmsg_add_string(&b, "data", tlv_data);
if (tlv_data)
free(tlv_data);
}
if (ubus_lookup_id(c->ubus_ctx, "map.1905", &id)) {
fprintf(stderr, "[%s:%d] not present", __func__, __LINE__);
goto out;
}
ret = ubus_invoke(c->ubus_ctx, id, "send",
b.head, send_cmdu_cb,
(void *)&msgid,
1000);
if (ret) {
fprintf(stderr, "[%s:%d] ubus call failed for |map.1905 send|",
__func__, __LINE__);
goto out;
}
//TODO: improve /////////////////////////
// if (is_store_mid) {
// cmsg = &priv->cmsg;
// for (i = 0; i < MAX_CMDU_MSG; i++) {
// if (cmsg->msg_id[i] == -1) {
// cmsg->msg_id[i] = msgid;
// cmsg->msg_ts[i] = time(NULL);
// break;
// }
// }
// }
/////////////////////////////////////////
out:
blob_buf_free(&b);
return ret;
}
static int cntlr_status(struct ubus_context *ctx, struct ubus_object *obj, static int cntlr_status(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method, struct ubus_request_data *req, const char *method,
...@@ -118,13 +262,80 @@ static int cntlr_status(struct ubus_context *ctx, struct ubus_object *obj, ...@@ -118,13 +262,80 @@ static int cntlr_status(struct ubus_context *ctx, struct ubus_object *obj,
return UBUS_STATUS_OK; return UBUS_STATUS_OK;
} }
static int cntlr_req_cap(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
struct cmdu_cstruct *cmdu_data;
uint32_t total_bss = 0;
uint32_t k = 0;
uint32_t i, j;
cmdu_data = (struct cmdu_cstruct *)calloc(1, sizeof(struct cmdu_cstruct));
if (!cmdu_data) {
fprintf(stderr, "failed to malloc cmdu\n");
return -1;
}
cmdu_data->message_type = CMDU_CLIENT_CAPABILITY_QUERY;
cmdu_data->message_id = 1;
fprintf(stderr, "map.1905 egress interface:|%s|\n", cmdu_data->intf_name);
send_cmdu(NULL, cmdu_data);
return 0;
}
static int cntlr_ap_caps(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
struct blob_attr *tb[__AP_POLICY_MAX];
struct controller *c = container_of(obj, struct controller, obj);
char mac[18] = {0};
struct cmdu_cstruct *cmdu_data;
uint32_t total_bss = 0;
uint32_t k = 0;
uint32_t i, j;
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(ap_caps_policy_params, __AP_POLICY_MAX, tb, blob_data(msg), blob_len(msg));
if (tb[AP_POLICY_AGENT]) {
strncpy(mac, blobmsg_data(tb[AP_POLICY_AGENT]), sizeof(mac) - 1);
printf("mac = %s\n", mac);
if (!hwaddr_aton(mac, cmdu_data->origin))
return UBUS_STATUS_UNKNOWN_ERROR;
}
// TODO: ff:ff:ff:ff:ff:ff = send to all agents
cmdu_data->message_type = CMDU_AP_CAPABILITY_QUERY;
cmdu_data->message_id = 1;
cmdu_data->num_tlvs = 0;
send_cmdu(c, cmdu_data);
return 0;
}
int cntlr_publish_object(struct controller *c, const char *objname) 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[2] = { struct ubus_method m[3] = {
UBUS_METHOD_NOARG("status", cntlr_status), UBUS_METHOD_NOARG("status", cntlr_status),
UBUS_METHOD_NOARG("req_cap", cntlr_req_cap),
UBUS_METHOD("ap_caps", cntlr_ap_caps, ap_caps_policy_params),
}; };
int num_methods = ARRAY_SIZE(m); int num_methods = ARRAY_SIZE(m);
int ret; int ret;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment