Commit 08313f1a authored by Anjan Chanda's avatar Anjan Chanda
Browse files

create 'ap' or 'backhaul' object based on wifi mode

parent e606469e
......@@ -99,7 +99,7 @@ static int wifimngr_cmd_main(struct ubus_context *ctx)
for (i = 0; i < num_ifs; i++) {
//ret = wifimngr_add_object(wmngr, ctx, ifs[i].iface, interface);
ret = wifimngr_add_interface_object(wmngr, ctx, ifs[i].iface);
ret = wifimngr_add_interface_object(wmngr, ctx, &ifs[i]);
if (ret) {
fprintf(stderr,
"Failed to add 'wifi.ap' ubus object: %s\n",
......
......@@ -36,7 +36,6 @@
#include "version.h"
#define MAX_RADIO 2 // FIXME: get from config
#define MAX_CLIENT 64
#define WL_STA_ANT_MAX 4
#define EXIT_SUCCESS_MANDATORY 1
......@@ -235,6 +234,7 @@ static const char *ubus_objname_to_ifname(struct ubus_object *obj, int radio)
#define ubus_radio_to_ifname(o) ubus_objname_to_ifname(o, 1)
#define ubus_ap_to_ifname(o) ubus_objname_to_ifname(o, 0)
#define ubus_sta_to_ifname(o) ubus_objname_to_ifname(o, 0)
static int uci_get_wifi_devices(char devlist[][16])
{
......@@ -313,6 +313,13 @@ static int uci_get_wifi_interfaces(struct wifimngr_iface ifs[])
memset(ifs[n].device, 0, 16);
strncpy(ifs[n].device, op->v.string, 15);
} else if (!strncmp(x->name, "mode", 4) &&
op->type == UCI_TYPE_STRING) {
if (!strncmp(op->v.string, "ap", 2))
ifs[n].mode = WIFI_AP;
else if (!strncmp(op->v.string, "wet", 3))
ifs[n].mode = WIFI_STA;
}
}
if (++n == WIFI_IF_MAX_NUM)
......@@ -578,7 +585,7 @@ static int wifi_iface_diag_counters(struct ubus_context *ctx,
return 0;
}
static int wl_interface_status(struct ubus_context *ctx, struct ubus_object *obj,
static int wl_ap_status(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
......@@ -667,7 +674,7 @@ static int wl_interface_status(struct ubus_context *ctx, struct ubus_object *obj
return 0;
}
static int wl_interface_stats(struct ubus_context *ctx, struct ubus_object *obj,
static int wl_ap_stats(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
......@@ -2184,6 +2191,89 @@ static int nbr_transition(struct ubus_context *ctx, struct ubus_object *obj,
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)
{
struct blob_attr *tb[__WL_MAX];
const char *ifname;
ifstatus_t ifs = 0;
struct blob_buf bb;
memset(&bb, 0, sizeof(bb));
ifname = ubus_sta_to_ifname(obj);
wifi_get_ifstatus(ifname, &ifs);
//wifi_sta_info(ifname, &sta);
blob_buf_init(&bb, 0);
blobmsg_add_string(&bb, "ifname", ifname);
blobmsg_add_string(&bb, "status", ifstatus_str(ifs));
// TODO: other attrs
ubus_send_reply(ctx, req, bb.head);
blob_buf_free(&bb);
return 0;
}
static int wl_sta_stats(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
const char *ifname;
//struct wifi_sta_stats s;
struct blob_buf bb;
int ret;
ifname = ubus_sta_to_ifname(obj);
//ret = wifi_sta_get_stats(ifname, &s);
//if (ret != 0)
// return UBUS_STATUS_UNKNOWN_ERROR;
memset(&bb, 0, sizeof(bb));
blob_buf_init(&bb, 0);
// TODO
ubus_send_reply(ctx, req, bb.head);
blob_buf_free(&bb);
return 0;
}
/* disconnect from ap policy */
enum {
AP_DISCONNECT_REASON, /* deauth/disassoc reason code */
__AP_DISCONNECT_MAX,
};
static const struct blobmsg_policy ap_disconnect_policy[__AP_DISCONNECT_MAX] = {
[AP_DISCONNECT_REASON] = { .name = "reason", .type = BLOBMSG_TYPE_INT32}
};
static int ap_disconnect(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_DISCONNECT_MAX];
const char *ifname;
unsigned int reason_code = 0;
ifname = ubus_sta_to_ifname(obj);
blobmsg_parse(ap_disconnect_policy, __AP_DISCONNECT_MAX, tb,
blob_data(msg), blob_len(msg));
if (tb[AP_DISCONNECT_REASON])
reason_code = blobmsg_get_u32(tb[AP_DISCONNECT_REASON]);
/* TODO
if (wifi_disconnect_ap(ifname, reason_code) != 0) {
return UBUS_STATUS_UNKNOWN_ERROR;
} */
return UBUS_STATUS_OK;
}
static int wl_status(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
......@@ -2363,119 +2453,6 @@ static int wl_radio_get_param(struct ubus_context *ctx, struct ubus_object *obj,
return UBUS_STATUS_OK;
}
#if 0
struct ubus_method wifi_methods[] = {
UBUS_METHOD_NOARG("status", wl_status),
};
struct ubus_method wifi_radio_methods[] = {
UBUS_METHOD_NOARG("status", wl_radio_status),
UBUS_METHOD("scan", wl_scan, wl_scan_policy),
UBUS_METHOD("scanresults", wl_scanresults, wl_scanres_policy),
UBUS_METHOD("get", wl_radio_get_param, radio_get_param_policy),
UBUS_METHOD("autochannel", wl_autochannel, wl_acs_policy),
};
struct ubus_method wifi_ap_methods[] = {
UBUS_METHOD_NOARG("status", wl_interface_status),
UBUS_METHOD_NOARG("assoclist", wl_assoclist),
UBUS_METHOD("stas", wl_stas, stainfo_policy),
UBUS_METHOD("disconnect_sta", sta_disconnect, sta_disconnect_policy),
UBUS_METHOD("add_neighbor", nbr_add, nbr_add_policy),
UBUS_METHOD("del_neighbor", nbr_del, nbr_del_policy),
UBUS_METHOD("list_neighbor", nbr_list, nbr_list_policy),
UBUS_METHOD("request_neighbor", nbr_request, nbr_req_policy),
UBUS_METHOD("request_transition", nbr_transition, nbr_transition_policy),
};
struct ubus_object_type wifi_objtype =
UBUS_OBJECT_TYPE("wifi", wifi_methods);
struct ubus_object_type wifi_radiotype =
UBUS_OBJECT_TYPE("wifi.radio", wifi_radio_methods);
struct ubus_object_type wifi_iftype =
UBUS_OBJECT_TYPE("wifi.ap", wifi_ap_methods);
int ubus_add_wifi_object(struct wifimngr *w,
struct ubus_context *ctx, char *name)
{
struct ubus_object *wobj;
int ret;
char ifname[32] = {0};
wobj = calloc(1, sizeof(struct ubus_object));
if (!wobj)
return -ENOMEM;
wobj->name = strdup(name);
wobj->type = &wifi_objtype;
wobj->methods = wifi_methods;
wobj->n_methods = ARRAY_SIZE(wifi_methods);
ret = ubus_add_object(ctx, wobj);
if (!ret) {
/* fprintf(stderr, "Added '%s' obj\n", wobj->name); */
w->wifi = wobj;
}
return ret;
}
int ubus_add_radio_object(struct wifimngr *w,
struct ubus_context *ctx, char *name)
{
struct wifi_ubus_object *wobj;
int ret;
char radioname[32] = {0};
wobj = calloc(1, sizeof(struct wifi_ubus_object));
if (!wobj)
return -ENOMEM;
snprintf(radioname, 28, "wifi.radio.%s", name);
wobj->obj.name = strdup(radioname);
wobj->obj.type = &wifi_radiotype;
wobj->obj.methods = wifi_radio_methods;
wobj->obj.n_methods = ARRAY_SIZE(wifi_radio_methods);
ret = ubus_add_object(ctx, &wobj->obj);
if (!ret) {
/* fprintf(stderr, "Added '%s' radio obj\n", wobj->obj.name); */
list_add_tail(&wobj->list, &w->radiolist);
}
return ret;
}
int ubus_add_interface_object(struct wifimngr *w,
struct ubus_context *ctx, char *name)
{
struct wifi_ubus_object *wobj;
int ret;
char ifname[32] = {0};
wobj = calloc(1, sizeof(struct wifi_ubus_object));
if (!wobj)
return -ENOMEM;
snprintf(ifname, 25, "wifi.ap.%s", name);
wobj->obj.name = strdup(ifname);
wobj->obj.type = &wifi_iftype;
wobj->obj.methods = wifi_ap_methods;
wobj->obj.n_methods = ARRAY_SIZE(wifi_ap_methods);
ret = ubus_add_object(ctx, &wobj->obj);
if (!ret) {
/* fprintf(stderr, "Added '%s' iface obj\n", wobj->obj.name); */
list_add_tail(&wobj->list, &w->iflist);
}
return ret;
}
#endif // if 0
#define MAX_WIFI_METHODS 8
int add_wifi_methods(struct ubus_object *wifi_obj)
{
......@@ -2600,74 +2577,101 @@ int wifimngr_add_radio_object(struct wifimngr *w,
return ret;
}
#define MAX_INTERFACE_METHODS 16
static int add_interface_methods(struct ubus_object *interface_obj,
#define MAX_AP_METHODS 16
static int add_ap_methods(struct ubus_object *interface_obj,
const char *ifname)
{
int n_methods = 0;
int i;
struct ubus_method *interface_methods;
struct ubus_method *ap_methods;
interface_methods = calloc(MAX_INTERFACE_METHODS, sizeof(struct ubus_method));
if (!interface_methods)
ap_methods = calloc(MAX_AP_METHODS, sizeof(struct ubus_method));
if (!ap_methods)
return -ENOMEM;
UBUS_METHOD_ADD(interface_methods, n_methods,
UBUS_METHOD_NOARG("status", wl_interface_status));
UBUS_METHOD_ADD(ap_methods, n_methods,
UBUS_METHOD_NOARG("status", wl_ap_status));
UBUS_METHOD_ADD(interface_methods, n_methods,
UBUS_METHOD_NOARG("stats", wl_interface_stats));
UBUS_METHOD_ADD(ap_methods, n_methods,
UBUS_METHOD_NOARG("stats", wl_ap_stats));
UBUS_METHOD_ADD(interface_methods, n_methods,
UBUS_METHOD_ADD(ap_methods, n_methods,
UBUS_METHOD_NOARG("assoclist", wl_assoclist));
UBUS_METHOD_ADD(interface_methods, n_methods,
UBUS_METHOD_ADD(ap_methods, n_methods,
UBUS_METHOD("stas", wl_stas, stainfo_policy));
UBUS_METHOD_ADD(interface_methods, n_methods,
UBUS_METHOD_ADD(ap_methods, n_methods,
UBUS_METHOD("stations", wl_stations, stainfo_policy));
if (libwifi_supports(ifname, "wifi_disconnect_sta")) {
UBUS_METHOD_ADD(interface_methods, n_methods,
UBUS_METHOD_ADD(ap_methods, n_methods,
UBUS_METHOD("disconnect", sta_disconnect, sta_disconnect_policy));
}
if (libwifi_supports(ifname, "wifi_monitor_sta")) {
UBUS_METHOD_ADD(interface_methods, n_methods,
UBUS_METHOD_ADD(ap_methods, n_methods,
UBUS_METHOD("monitor", sta_monitor, sta_monitor_policy));
}
if (libwifi_supports(ifname, "wifi_add_neighbor"))
UBUS_METHOD_ADD(interface_methods, n_methods,
UBUS_METHOD_ADD(ap_methods, n_methods,
UBUS_METHOD("add_neighbor", nbr_add, nbr_add_policy));
if (libwifi_supports(ifname, "wifi_del_neighbor"))
UBUS_METHOD_ADD(interface_methods, n_methods,
UBUS_METHOD_ADD(ap_methods, n_methods,
UBUS_METHOD("del_neighbor", nbr_del, nbr_del_policy));
if (libwifi_supports(ifname, "wifi_get_neighbor_list"))
UBUS_METHOD_ADD(interface_methods, n_methods,
UBUS_METHOD_ADD(ap_methods, n_methods,
UBUS_METHOD("list_neighbor", nbr_list, nbr_list_policy));
if (libwifi_supports(ifname, "wifi_req_beacon_report"))
UBUS_METHOD_ADD(interface_methods, n_methods,
UBUS_METHOD_ADD(ap_methods, n_methods,
UBUS_METHOD("request_neighbor", nbr_request, nbr_req_policy));
if (libwifi_supports(ifname, "wifi_req_bss_transition"))
UBUS_METHOD_ADD(interface_methods, n_methods,
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(interface_methods, n_methods,
UBUS_METHOD_ADD(ap_methods, n_methods,
UBUS_METHOD("vendor_ie_add", vsie_add, vsie_add_policy));
if (libwifi_supports(ifname, "wifi_del_vendor_ie"))
UBUS_METHOD_ADD(interface_methods, n_methods,
UBUS_METHOD_ADD(ap_methods, n_methods,
UBUS_METHOD("vendor_ie_del", vsie_del, vsie_del_policy));
#endif
interface_obj->methods = interface_methods;
interface_obj->methods = ap_methods;
interface_obj->n_methods = n_methods;
}
#define MAX_STA_METHODS 8
static int add_sta_methods(struct ubus_object *interface_obj,
const char *ifname)
{
int n_methods = 0;
int i;
struct ubus_method *sta_methods;
sta_methods = calloc(MAX_STA_METHODS, sizeof(struct ubus_method));
if (!sta_methods)
return -ENOMEM;
UBUS_METHOD_ADD(sta_methods, n_methods,
UBUS_METHOD_NOARG("status", wl_sta_status));
UBUS_METHOD_ADD(sta_methods, n_methods,
UBUS_METHOD_NOARG("stats", wl_sta_stats));
//if (libwifi_supports(ifname, "wifi_disconnect_ap")) {
UBUS_METHOD_ADD(sta_methods, n_methods,
UBUS_METHOD("disconnect", ap_disconnect, ap_disconnect_policy));
//}
interface_obj->methods = sta_methods;
interface_obj->n_methods = n_methods;
}
......@@ -2749,7 +2753,7 @@ int wifimngr_add_interface_subobject(
int wifimngr_add_interface_object(struct wifimngr *w,
struct ubus_context *ctx,
const char *ifname)
struct wifimngr_iface *iface)
{
struct wifi_ubus_object *wobj;
int ret;
......@@ -2759,11 +2763,18 @@ int wifimngr_add_interface_object(struct wifimngr *w,
if (!wobj)
return -ENOMEM;
INIT_LIST_HEAD(&wobj->sobjlist);
snprintf(objname, 25, "wifi.ap.%s", ifname);
wobj->obj.name = strdup(objname);
add_interface_methods(&wobj->obj, ifname);
if (iface->mode == WIFI_AP) {
snprintf(objname, 25, "wifi.ap.%s", iface->iface);
add_ap_methods(&wobj->obj, iface->iface);
} else if (iface->mode == WIFI_STA) {
snprintf(objname, 31, "wifi.backhaul.%s", iface->iface);
add_sta_methods(&wobj->obj, iface->iface);
} else {
/* unhandled wifi mode */
return -EINVAL;
}
wobj->obj.name = strdup(objname);
wobj->obj_type.name = wobj->obj.name;
wobj->obj_type.n_methods = wobj->obj.n_methods;
wobj->obj_type.methods = wobj->obj.methods;
......@@ -2775,6 +2786,8 @@ int wifimngr_add_interface_object(struct wifimngr *w,
#ifdef WIFIMNGR_GRANULAR_OBJECTS
INIT_LIST_HEAD(&wobj->sobjlist);
/* create sub objects per-interface */
wifimngr_add_interface_subobject(wobj, ctx,
ifname,
......
......@@ -37,6 +37,28 @@ struct wifimngr {
struct list_head iflist; /* list of wifi_ubus_objects */
};
#define WIFI_DEV_MAX_NUM 16
#define WIFI_IF_MAX_NUM 16
struct wifimngr_device {
char device[16];
};
enum iface_mode {
WIFI_AP,
WIFI_STA,
};
struct wifimngr_iface {
char iface[16];
char device[16];
int mode;
};
int wifimngr_get_wifi_devices(char devs[][WIFI_DEV_MAX_NUM]);
int wifimngr_get_wifi_interfaces(struct wifimngr_iface ifs[]);
//#define wifimngr_add_object(w, u, n, type) ubus_add_## type ##_object(w, u, n)
#define UBUS_METHOD_ADD(_tab, iter, __m) \
......@@ -60,27 +82,13 @@ extern int wifimngr_add_radio_object(struct wifimngr *w,
extern int wifimngr_add_interface_object(struct wifimngr *w,
struct ubus_context *ctx,
const char *objname);
struct wifimngr_iface *iface);
extern int wifimngr_init(struct wifimngr **w);
extern int wifimngr_exit(struct wifimngr *w);
extern void wifimngr_version(void);
#define WIFI_DEV_MAX_NUM 16
#define WIFI_IF_MAX_NUM 16
struct wifimngr_device {
char device[16];
};
struct wifimngr_iface {
char iface[16];
char device[16];
};
int wifimngr_get_wifi_devices(char devs[][WIFI_DEV_MAX_NUM]);
int wifimngr_get_wifi_interfaces(struct wifimngr_iface ifs[]);
#if 0
extern int ubus_add_wifi_object(struct wifimngr *w,
......
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