Commit 0d7a6794 authored by Anjan Chanda's avatar Anjan Chanda

implement add/del vendor ie methods

parent 08313f1a
......@@ -24,6 +24,38 @@ static int hex2byte(const char *hex)
return (a << 4) | b;
}
/* convert hex string to byte array */
unsigned char *strtob(char *str, int len, unsigned char *bytes)
{
size_t i;
for (i = 0; i < len; i++) {
int a;
if ((a = hex2byte(str)) < 0)
return NULL;
str += 2;
bytes[i] = a;
}
return bytes;
}
/* convert byte array to hex string */
char *btostr(unsigned char *bytes, int len, char *str)
{
size_t i;
if (!str)
return NULL;
for (i = 0; i < len; i++)
sprintf(str + strlen(str), "%02x", bytes[i] & 0xff);
return str;
}
/* Convert "00:11:22:33:44:55" --> \x001122334455 */
unsigned char * hwaddr_aton(const char *macstr, unsigned char *mac)
{
......
......@@ -10,6 +10,9 @@ static inline int is_zero_hwaddr(const unsigned char *mac)
return (mac[0] | mac[1] | mac[2] | mac[3] | mac[4] | mac[5]) == 0;
}
unsigned char *strtob(char *str, int len, unsigned char *bytes);
char *btostr(unsigned char *bytes, int len, char *str);
int set_sighandler(int sig, void (*handler)(int));
int unset_sighandler(int sig);
......
......@@ -2135,7 +2135,6 @@ static int nbr_request(struct ubus_context *ctx, struct ubus_object *obj,
return UBUS_STATUS_OK;
}
static int nbr_transition(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
......@@ -2191,6 +2190,137 @@ static int nbr_transition(struct ubus_context *ctx, struct ubus_object *obj,
return UBUS_STATUS_OK;
}
/* vendor_ie add/del policy */
enum {
VSIE_MGMT_STYPE, /* bitmask of (1 << mgmt frame subtype) */
VSIE_OUI,
VSIE_DATA,
__VSIE_MAX,
};
static const struct blobmsg_policy vsie_policy[__VSIE_MAX] = {
[VSIE_MGMT_STYPE] = { .name = "mgmt", .type = BLOBMSG_TYPE_INT32 },
[VSIE_OUI] = { .name = "oui", .type = BLOBMSG_TYPE_STRING},
[VSIE_DATA] = { .name = "data", .type = BLOBMSG_TYPE_STRING},
};
static int vsie_add(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *ureq, const char *method,
struct blob_attr *msg)
{
struct blob_attr *tb[__VSIE_MAX];
struct blob_attr *attr;
const char *ifname;
uint8_t vsie_buf[256] = {0};
struct vendor_iereq *req = (struct vendor_iereq *)vsie_buf;
uint8_t *data = req->ie.data;
char data_str[499] = {0}; /* (256 - 7) * 2 + 1 */
char oui_str[7] = {0}; /* 3 * 2 + 1 */
uint8_t oui[3] = {0};
int data_len = 0;
int data_strlen;
ifname = ubus_ap_to_ifname(obj);
blobmsg_parse(vsie_policy, __VSIE_MAX, tb,
blob_data(msg), blob_len(msg));
if (!(tb[VSIE_OUI]) || !(tb[VSIE_DATA]))
return UBUS_STATUS_INVALID_ARGUMENT;
req->mgmt_subtype = 0;
req->ie.ie_hdr.eid = 0xdd;
req->ie.ie_hdr.len = 0;
if (tb[VSIE_MGMT_STYPE])
req->mgmt_subtype = blobmsg_get_u32(tb[VSIE_MGMT_STYPE]);
if (blobmsg_data_len(tb[VSIE_OUI]) != sizeof(oui_str))
return UBUS_STATUS_INVALID_ARGUMENT;
strncpy(oui_str, blobmsg_data(tb[VSIE_OUI]), 6);
strtob(oui_str, 7, oui);
memcpy(req->ie.oui, oui, 3);
req->ie.ie_hdr.len += 3;
data_strlen = blobmsg_data_len(tb[VSIE_DATA]);
if (data_strlen > sizeof(data_str) - 1)
return UBUS_STATUS_INVALID_ARGUMENT;
strncpy(data_str, blobmsg_data(tb[VSIE_DATA]), data_strlen);
strtob(data_str, data_strlen, &data[2]);
data_len = (data_strlen - 1) / 2;
data[0] = 0xdd;
data[1] = data_len;
req->ie.ie_hdr.len += 2 + data_len;
if (wifi_add_vendor_ie(ifname, req) != 0)
return UBUS_STATUS_UNKNOWN_ERROR;
return UBUS_STATUS_OK;
}
static int vsie_del(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *ureq, const char *method,
struct blob_attr *msg)
{
struct blob_attr *tb[__VSIE_MAX];
struct blob_attr *attr;
const char *ifname;
uint8_t vsie_buf[256] = {0};
struct vendor_iereq *req = (struct vendor_iereq *)vsie_buf;
uint8_t *data = req->ie.data;
char data_str[499] = {0}; /* (256 - 7) * 2 + 1 */
char oui_str[7] = {0}; /* 3 * 2 + 1 */
uint8_t oui[3] = {0};
int data_strlen;
int data_len = 0;
uint32_t mgmt_frames = 0;
ifname = ubus_ap_to_ifname(obj);
blobmsg_parse(vsie_policy, __VSIE_MAX, tb,
blob_data(msg), blob_len(msg));
if (!(tb[VSIE_OUI]))
return UBUS_STATUS_INVALID_ARGUMENT;
req->mgmt_subtype = 0;
req->ie.ie_hdr.eid = 0xdd;
req->ie.ie_hdr.len = 0;
if (tb[VSIE_MGMT_STYPE])
req->mgmt_subtype = blobmsg_get_u32(tb[VSIE_MGMT_STYPE]);
if (blobmsg_data_len(tb[VSIE_OUI]) != sizeof(oui_str))
return UBUS_STATUS_INVALID_ARGUMENT;
strncpy(oui_str, blobmsg_data(tb[VSIE_OUI]), 6);
strtob(oui_str, 7, oui);
memcpy(req->ie.oui, oui, 3);
req->ie.ie_hdr.len += 3;
if (tb[VSIE_DATA]) {
/* match data starting with pattern */
data_strlen = blobmsg_data_len(tb[VSIE_DATA]);
if (data_strlen > sizeof(data_str) - 1)
return UBUS_STATUS_INVALID_ARGUMENT;
strncpy(data_str, blobmsg_data(tb[VSIE_DATA]), data_strlen);
strtob(data_str, data_strlen, &data[2]);
data_len = (data_strlen - 1) / 2;
data[0] = 0xdd;
data[1] = data_len;
req->ie.ie_hdr.len += 2 + data_len;
}
if (wifi_del_vendor_ie(ifname, req) != 0)
return UBUS_STATUS_UNKNOWN_ERROR;
return UBUS_STATUS_OK;
}
static int wl_sta_status(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
......@@ -2634,15 +2764,13 @@ static int add_ap_methods(struct ubus_object *interface_obj,
UBUS_METHOD_ADD(ap_methods, n_methods,
UBUS_METHOD("request_transition", nbr_transition, nbr_transition_policy));
#if 0 // TODO
if (libwifi_supports(ifname, "wifi_add_vendor_ie"))
UBUS_METHOD_ADD(ap_methods, n_methods,
UBUS_METHOD("vendor_ie_add", vsie_add, vsie_add_policy));
UBUS_METHOD("add_vendor_ie", vsie_add, vsie_policy));
if (libwifi_supports(ifname, "wifi_del_vendor_ie"))
UBUS_METHOD_ADD(ap_methods, n_methods,
UBUS_METHOD("vendor_ie_del", vsie_del, vsie_del_policy));
#endif
UBUS_METHOD("del_vendor_ie", vsie_del, vsie_policy));
interface_obj->methods = ap_methods;
interface_obj->n_methods = n_methods;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment