blob: 6a9184626db5e5210b24d9502a4b19ff4c2900ca [file] [log] [blame]
/******************************************************************************
*(C) Copyright 2014 Marvell International Ltd.
* All Rights Reserved
******************************************************************************/
/* -------------------------------------------------------------------------------------------------------------------
*
* Filename: mgui_wifi.c
*
* Authors: Tomer Eliyahu
*
* Description: MGUI wifi / battery interface
*
* HISTORY:
*
* Jun 14, 2015 - Initial Version
*
* Notes:
*
******************************************************************************/
/******************************************************************************
* Include files
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include "mgui_utils.h"
#include "mgui_ubus.h"
#include "mgui_icons.h"
#include "mgui_wifi.h"
#include "mgui.h"
/******************************************************************************
* Structures
******************************************************************************/
/******************************************************************************
* Definitions
******************************************************************************/
//#define WIFI_DEBUG
#define WIFI_UBUS_ID "wireless"
#define WIFI_UBUS_REQUEST "wifi_get_detail"
#define STATISTICS_UBUS_ID "statistics"
#define STATISTICS_UBUS_REQUEST "get_wifi_status"
#define ACTIVE_CLIENTS_NUM_REQUEST "get_active_clients_num"
#define to_ubus_subscriber(obj) container_of(obj, struct ubus_subscriber, obj)
#define to_wifi_context(obj) container_of(to_ubus_subscriber(obj), struct mgui_wifi_context, ubus_subscriber)
/******************************************************************************
* Globals
******************************************************************************/
/* wireless get_basic_info */
enum {
ATTR_WIRELESS = 0,
ATTR_AP0,
};
enum {
ATTR_WIFI_IF_2G,
ATTR_DEVICE,
ATTR_SWITCH,
ATTR_CHANNEL,
ATTR_SSID0,
ATTR_SSID,
ATTR_ENCRYPTION,
ATTR_KEY,
};
enum {
ATTR2_WIFI_IF_5G,
ATTR2_DEVICE,
ATTR2_SWITCH,
ATTR2_CHANNEL,
ATTR2_SSID0,
ATTR2_SSID,
ATTR2_ENCRYPTION,
ATTR2_KEY,
};
static const struct blobmsg_policy wifi_info_attr_policy[] = {
[ATTR_WIRELESS] = {.name = "wireless", .type = BLOBMSG_TYPE_TABLE},
[ATTR_AP0] = {.name = "AP0", .type = BLOBMSG_TYPE_TABLE},
};
static const struct blobmsg_policy wifi_2G_attr_policy[] = {
[ATTR_WIFI_IF_2G] = {.name = "wifi_if_24G", .type = BLOBMSG_TYPE_TABLE},
[ATTR_DEVICE] = {.name = "device", .type = BLOBMSG_TYPE_STRING},
[ATTR_SWITCH] = {.name = "switch", .type = BLOBMSG_TYPE_STRING},
[ATTR_CHANNEL] = {.name = "channel", .type = BLOBMSG_TYPE_STRING},
[ATTR_SSID0] = {.name = "ssid0", .type = BLOBMSG_TYPE_TABLE},
[ATTR_SSID] = {.name = "ssid", .type = BLOBMSG_TYPE_STRING},
[ATTR_ENCRYPTION] = {.name = "encryption", .type = BLOBMSG_TYPE_STRING},
[ATTR_KEY] = {.name = "key", .type = BLOBMSG_TYPE_STRING},
};
static const struct blobmsg_policy wifi_5G_attr_policy[] = {
[ATTR2_WIFI_IF_5G] = {.name = "wifi_if_5G", .type = BLOBMSG_TYPE_TABLE},
[ATTR2_DEVICE] = {.name = "device", .type = BLOBMSG_TYPE_STRING},
[ATTR2_SWITCH] = {.name = "switch", .type = BLOBMSG_TYPE_STRING},
[ATTR2_CHANNEL] = {.name = "channel", .type = BLOBMSG_TYPE_STRING},
[ATTR2_SSID0] = {.name = "ssid0", .type = BLOBMSG_TYPE_TABLE},
[ATTR2_SSID] = {.name = "ssid", .type = BLOBMSG_TYPE_STRING},
[ATTR2_ENCRYPTION] = {.name = "encryption", .type = BLOBMSG_TYPE_STRING},
[ATTR2_KEY] = {.name = "key", .type = BLOBMSG_TYPE_STRING},
};
/* statistics get_active_clients_num*/
enum {
ATTR_CLIENTS_INFO,
ATTR_ACTIVE_CLIENTS_NUM,
ATTR_USB_STATE,
};
static const struct blobmsg_policy active_clients_num_attr_policy[] = {
[ATTR_CLIENTS_INFO] = {.name = "clients_info", .type = BLOBMSG_TYPE_TABLE},
[ATTR_ACTIVE_CLIENTS_NUM] = {.name = "active_clients_num", .type = BLOBMSG_TYPE_STRING},
[ATTR_USB_STATE] = {.name = "usb_state", .type = BLOBMSG_TYPE_STRING},
};
/* statistics get_wifi_status */
enum {
ATTR_STATISTICS,
ATTR_WIFI_STATUS,
};
static const struct blobmsg_policy wifi_status_attr_policy[] = {
[ATTR_STATISTICS] = {.name = "statistics", .type = BLOBMSG_TYPE_TABLE},
[ATTR_WIFI_STATUS] = {.name = "wifi_status", .type = BLOBMSG_TYPE_STRING},
};
static struct blob_buf b;
/******************************************************************************
* Code
******************************************************************************/
#ifdef WIFI_DEBUG
static const char *indent_str = "\t\t\t\t\t\t\t\t\t\t\t\t\t";
#define indent_printf(indent, ...) do { \
if (indent > 0) \
fwrite(indent_str, indent, 1, stderr); \
fprintf(stderr, __VA_ARGS__); \
} while(0)
static void dump_attr_data(struct blob_attr *data, int indent, int next_indent);
static void
dump_table(struct blob_attr *head, int len, int indent, bool array)
{
struct blob_attr *attr;
struct blobmsg_hdr *hdr;
indent_printf(indent, "{\n");
__blob_for_each_attr(attr, head, len) {
hdr = blob_data(attr);
if (!array)
indent_printf(indent + 1, "%s : ", hdr->name);
dump_attr_data(attr, 0, indent + 1);
}
indent_printf(indent, "}\n");
}
static void dump_attr_data(struct blob_attr *data, int indent, int next_indent)
{
int type = blobmsg_type(data);
switch(type) {
case BLOBMSG_TYPE_STRING:
indent_printf(indent, "%s\n", blobmsg_get_string(data));
break;
case BLOBMSG_TYPE_INT8:
indent_printf(indent, "%d\n", blobmsg_get_u8(data));
break;
case BLOBMSG_TYPE_INT16:
indent_printf(indent, "%d\n", blobmsg_get_u16(data));
break;
case BLOBMSG_TYPE_INT32:
indent_printf(indent, "%d\n", blobmsg_get_u32(data));
break;
case BLOBMSG_TYPE_INT64:
indent_printf(indent, "%"PRIu64"\n", blobmsg_get_u64(data));
break;
case BLOBMSG_TYPE_TABLE:
case BLOBMSG_TYPE_ARRAY:
if (!indent)
indent_printf(indent, "\n");
dump_table(blobmsg_data(data), blobmsg_data_len(data),
next_indent, type == BLOBMSG_TYPE_ARRAY);
break;
}
}
#endif /* WIFI_DEBUG */
static int wifi_info_parse_blobmsg(struct mgui_wifi_context *ctx, struct blob_attr *msg)
{
struct blob_attr *tb[ARRAY_SIZE(wifi_info_attr_policy)];
struct blob_attr *tb2g[ARRAY_SIZE(wifi_2G_attr_policy)];
struct blob_attr *tb5g[ARRAY_SIZE(wifi_5G_attr_policy)];
int ret;
MASSERT(ctx);
ret = blobmsg_parse(wifi_info_attr_policy, ARRAY_SIZE(wifi_info_attr_policy),
tb, blob_data(msg), blob_len(msg));
if (ret){
MGUI_EMSG("parsing blobmsg failed %d\n", ret);
return -1;
}
if (!tb[ATTR_WIRELESS])
return -1;
ret = blobmsg_parse(wifi_info_attr_policy, ARRAY_SIZE(wifi_info_attr_policy), tb,
blobmsg_data(tb[ATTR_WIRELESS]),
blobmsg_data_len(tb[ATTR_WIRELESS]));
if (ret){
MGUI_EMSG("parsing blobmsg failed %d\n", ret);
return -1;
}
if (!tb[ATTR_AP0])
return -1;
ret = blobmsg_parse(wifi_2G_attr_policy, ARRAY_SIZE(wifi_2G_attr_policy), tb2g,
blobmsg_data(tb[ATTR_AP0]),
blobmsg_data_len(tb[ATTR_AP0]));
if (ret) {
MGUI_EMSG("parsing blobmsg failed %d\n", ret);
return -1;
}
if (!tb2g[ATTR_WIFI_IF_2G]) {
MGUI_EMSG("parsing blobmsg failed %d\n", ret);
return -1;
}
if (tb2g[ATTR_WIFI_IF_2G]) {
ret = blobmsg_parse(wifi_2G_attr_policy,
ARRAY_SIZE(wifi_2G_attr_policy), tb2g,
blobmsg_data(tb2g[ATTR_WIFI_IF_2G]),
blobmsg_data_len(tb2g[ATTR_WIFI_IF_2G]));
ctx->status.on = tb2g[ATTR_SWITCH] ?
strdup(blobmsg_get_string(tb2g[ATTR_SWITCH])) : NULL;
if ((strcmp(ctx->status.on, "on") == 0)) {
ctx->status.device = tb2g[ATTR_DEVICE] ?
strdup(blobmsg_get_string(tb2g[ATTR_DEVICE])) : NULL;
ctx->status.channel = tb2g[ATTR_CHANNEL] ?
strdup(blobmsg_get_string(tb2g[ATTR_CHANNEL])) : NULL;
if (tb2g[ATTR_SSID0]) {
ret = blobmsg_parse(wifi_2G_attr_policy,
ARRAY_SIZE(wifi_2G_attr_policy), tb2g,
blobmsg_data(tb2g[ATTR_SSID0]),
blobmsg_data_len(tb2g[ATTR_SSID0]));
sprintf(ctx->status.ssid, "%s", blobmsg_get_string(tb2g[ATTR_SSID]));
if (ctx->status.num_clients > 0 && ctx->status.usb_status == 1) {
snprintf(ctx->status.ui_ssid, sizeof(ctx->status.ui_ssid), "%s (%d)", ctx->status.ssid, (ctx->status.num_clients - 1));
} else if (ctx->status.num_clients <= 0) {
snprintf(ctx->status.ui_ssid, sizeof(ctx->status.ui_ssid), "%s (%d)", ctx->status.ssid, 0);
} else {
snprintf(ctx->status.ui_ssid, sizeof(ctx->status.ui_ssid), "%s (%d)", ctx->status.ssid, ctx->status.num_clients);
}
ctx->status.key = tb2g[ATTR_KEY] ?
strdup(blobmsg_get_string(tb2g[ATTR_KEY])) : NULL;
ctx->status.encryption = tb2g[ATTR_ENCRYPTION] ?
strdup(blobmsg_get_string(tb2g[ATTR_ENCRYPTION])) : NULL;
}
}
}
if ((strcmp(ctx->status.on, "on") != 0)) {
ret = blobmsg_parse(wifi_5G_attr_policy, ARRAY_SIZE(wifi_5G_attr_policy), tb5g,
blobmsg_data(tb[ATTR_AP0]),
blobmsg_data_len(tb[ATTR_AP0]));
if (ret) {
MGUI_EMSG("parsing blobmsg failed %d\n", ret);
return -1;
}
if (!tb5g[ATTR2_WIFI_IF_5G]) {
MGUI_EMSG("parsing blobmsg failed %d\n", ret);
return -1;
}
if (tb5g[ATTR2_WIFI_IF_5G]) {
ret = blobmsg_parse(wifi_5G_attr_policy,
ARRAY_SIZE(wifi_5G_attr_policy), tb5g,
blobmsg_data(tb5g[ATTR2_WIFI_IF_5G]),
blobmsg_data_len(tb5g[ATTR2_WIFI_IF_5G]));
ctx->status.on = tb5g[ATTR2_SWITCH] ?
strdup(blobmsg_get_string(tb5g[ATTR2_SWITCH])) : NULL;
if ((strcmp(ctx->status.on, "on") == 0)) {
ctx->status.device = tb5g[ATTR2_DEVICE] ?
strdup(blobmsg_get_string(tb5g[ATTR2_DEVICE])) : NULL;
ctx->status.channel = tb5g[ATTR2_CHANNEL] ?
strdup(blobmsg_get_string(tb5g[ATTR2_CHANNEL])) : NULL;
if (tb5g[ATTR2_SSID0]) {
ret = blobmsg_parse(wifi_5G_attr_policy,
ARRAY_SIZE(wifi_5G_attr_policy), tb5g,
blobmsg_data(tb5g[ATTR2_SSID0]),
blobmsg_data_len(tb5g[ATTR2_SSID0]));
sprintf(ctx->status.ssid, "%s", blobmsg_get_string(tb5g[ATTR2_SSID]));
if (ctx->status.num_clients > 0 && ctx->status.usb_status == 1) {
snprintf(ctx->status.ui_ssid, sizeof(ctx->status.ui_ssid), "%s (%d)", ctx->status.ssid, (ctx->status.num_clients - 1));
} else if (ctx->status.num_clients <= 0) {
snprintf(ctx->status.ui_ssid, sizeof(ctx->status.ui_ssid), "%s (%d)", ctx->status.ssid, 0);
} else {
snprintf(ctx->status.ui_ssid, sizeof(ctx->status.ui_ssid), "%s (%d)", ctx->status.ssid, ctx->status.num_clients);
}
ctx->status.key = tb5g[ATTR2_KEY] ?
strdup(blobmsg_get_string(tb5g[ATTR2_KEY])) : NULL;
ctx->status.encryption = tb5g[ATTR2_ENCRYPTION] ?
strdup(blobmsg_get_string(tb5g[ATTR2_ENCRYPTION])) : NULL;
}
} else {
ctx->status.device = NULL;
ctx->status.channel = NULL;
ctx->status.key = NULL;
ctx->status.encryption = NULL;
}
}
}
if (ret){
MGUI_EMSG("parsing blobmsg failed %d\n", ret);
return -1;
}
MGUI_IMSG(" blobmsg device = %s, switch = %s, channel = %s, ssid = %s, num_clients = %d, key = %s, encryption = %s\n",
ctx->status.device,
ctx->status.on,
ctx->status.channel,
ctx->status.ssid,
ctx->status.num_clients,
ctx->status.key,
ctx->status.encryption);
return 0;
}
static int active_clients_num_parse_blobmsg(struct mgui_wifi_context *ctx, struct blob_attr *msg)
{
struct blob_attr *tb[ARRAY_SIZE(active_clients_num_attr_policy)];
int ret;
MASSERT(ctx);
ret = blobmsg_parse(active_clients_num_attr_policy, ARRAY_SIZE(active_clients_num_attr_policy),
tb, blob_data(msg), blob_len(msg));
if (ret){
MGUI_EMSG("parsing clients_num blobmsg failed %d\n", ret);
return -1;
}
if (!tb[ATTR_CLIENTS_INFO])
return -1;
ret = blobmsg_parse(active_clients_num_attr_policy, ARRAY_SIZE(active_clients_num_attr_policy), tb,
blobmsg_data(tb[ATTR_CLIENTS_INFO]),
blobmsg_data_len(tb[ATTR_CLIENTS_INFO]));
if (ret){
MGUI_EMSG("parsing clients_num blobmsg failed %d\n", ret);
return -1;
}
if (!tb[ATTR_ACTIVE_CLIENTS_NUM] || !tb[ATTR_USB_STATE]) {
MGUI_EMSG("parsing clients_num blobmsg failed %d\n", ret);
return -1;
}
ctx->status.num_clients = atoi(blobmsg_get_string(tb[ATTR_ACTIVE_CLIENTS_NUM]));
ctx->status.usb_status = atoi(blobmsg_get_string(tb[ATTR_USB_STATE]));
MGUI_IMSG("parsing clients_num blobmsg num_clients = %d, usb_status = %d\n",
ctx->status.num_clients,
ctx->status.usb_status);
if (ctx->status.num_clients > 0 && ctx->status.usb_status == 1) {
snprintf(ctx->status.ui_ssid, sizeof(ctx->status.ui_ssid), "%s (%d)", ctx->status.ssid, (ctx->status.num_clients - 1));
} else if (ctx->status.num_clients <= 0) {
snprintf(ctx->status.ui_ssid, sizeof(ctx->status.ui_ssid), "%s (%d)", ctx->status.ssid, 0);
} else {
snprintf(ctx->status.ui_ssid, sizeof(ctx->status.ui_ssid), "%s (%d)", ctx->status.ssid, ctx->status.num_clients);
}
MGUI_EMSG("active_clients_num_parse_blobmsg ctx->status.ui_ssid%s \n", ctx->status.ui_ssid);
return 0;
}
static int wifi_status_parse_blobmsg(struct mgui_wifi_context *ctx, struct blob_attr *msg)
{
struct blob_attr *tb[ARRAY_SIZE(wifi_status_attr_policy)];
int ret;
MASSERT(ctx);
ret = blobmsg_parse(wifi_status_attr_policy, ARRAY_SIZE(wifi_status_attr_policy),
tb, blob_data(msg), blob_len(msg));
if (ret){
MGUI_EMSG("parsing blobmsg failed %d\n", ret);
return -1;
}
if (!tb[ATTR_STATISTICS])
return -1;
#ifdef WIFI_DEBUG
fprintf(stderr, "statistics table: ");
dump_table(blobmsg_data(tb[ATTR_WIRELESS]),
blobmsg_data_len(tb[ATTR_WIRELESS]), 0, false);
#endif
ret = blobmsg_parse(wifi_status_attr_policy, ARRAY_SIZE(wifi_status_attr_policy), tb,
blobmsg_data(tb[ATTR_STATISTICS]),
blobmsg_data_len(tb[ATTR_STATISTICS]));
if (ret){
MGUI_EMSG("parsing blobmsg failed %d\n", ret);
return -1;
}
if (!tb[ATTR_WIFI_STATUS]) {
MGUI_EMSG("parsing blobmsg failed %d\n", ret);
return -1;
}
ctx->status.wifi_status = 0;
if (tb[ATTR_WIFI_STATUS]) {
char *str = blobmsg_get_string(tb[ATTR_WIFI_STATUS]);
if (!strcmp(str, "ready"))
ctx->status.wifi_status = 1;
}
return 0;
}
static void wifi_info_data_cb(struct ubus_request *req, int type, struct blob_attr *msg)
{
struct mgui_wifi_context *wifi = (struct mgui_wifi_context *)req->priv;
int ret;
MASSERT(wifi);
MGUI_DMSG("wifi data received\n");
ret = wifi_info_parse_blobmsg(wifi, msg);
if (ret){
MGUI_EMSG("parsing blobmsg failed %d\n", ret);
return;
}
mgui_update_icon(wifi->mgui, MGUI_WIFI_SSID_ICON, (void *)wifi);
}
static void active_clients_num_data_cb(struct ubus_request *req, int type, struct blob_attr *msg)
{
struct mgui_wifi_context *wifi = (struct mgui_wifi_context *)req->priv;
int ret;
MASSERT(wifi);
MGUI_DMSG("wifi data received\n");
ret = active_clients_num_parse_blobmsg(wifi, msg);
if (ret){
MGUI_EMSG("parsing blobmsg failed %d\n", ret);
return;
}
mgui_update_icon(wifi->mgui, MGUI_WIFI_SSID_ICON, (void *)wifi);
}
static void wifi_complete_cb(struct ubus_request *req, int ret)
{
struct mgui_wifi_context *wifi = (struct mgui_wifi_context *)req->priv;
MGUI_DMSG("wifi complete received\n");
/* trigger screen refresh since this is a result of an async request */
mgui_screen_refresh(wifi->mgui);
}
static void active_clients_num_complete_cb(struct ubus_request *req, int ret)
{
struct mgui_wifi_context *wifi = (struct mgui_wifi_context *)req->priv;
MGUI_DMSG("wifi complete received\n");
mgui_screen_refresh(wifi->mgui);
}
static void wifi_status_data_cb(struct ubus_request *req, int type, struct blob_attr *msg)
{
struct mgui_wifi_context *wifi = (struct mgui_wifi_context *)req->priv;
int ret;
MASSERT(wifi);
MGUI_DMSG("wifi data received\n");
ret = wifi_status_parse_blobmsg(wifi, msg);
if (ret){
MGUI_EMSG("parsing blobmsg failed %d\n", ret);
return;
}
mgui_update_icon(wifi->mgui, MGUI_WIFI_ICON, (void *)wifi);
}
static inline int mgui_wifi_info_request(struct mgui_wifi_context *ctx)
{
return mgui_ubus_invoke_async(ctx->mgui->ubus, &b, ctx->wifi_ubus_id,
WIFI_UBUS_REQUEST, wifi_info_data_cb, wifi_complete_cb, ctx);
}
static inline int mgui_active_clients_num_request(struct mgui_wifi_context *ctx)
{
return mgui_ubus_invoke_async(ctx->mgui->ubus, &b, ctx->statistics_ubus_id,
ACTIVE_CLIENTS_NUM_REQUEST, active_clients_num_data_cb, active_clients_num_complete_cb, ctx);
}
static inline int mgui_wifi_status_request(struct mgui_wifi_context *ctx)
{
return mgui_ubus_invoke_async(ctx->mgui->ubus, &b, ctx->statistics_ubus_id,
STATISTICS_UBUS_REQUEST, wifi_status_data_cb, wifi_complete_cb, ctx);
}
enum {
WIFI_CLIENTS_NOTIFY_ID,
WIFI_STATUS_NOTIFY_ID,
};
enum {
REQID,
DATA,
_MAX
};
static int wifi_indication_parse_blobmsg(struct blob_attr *attr, struct blob_attr **tb)
{
struct blob_attr *pos = NULL;
struct blobmsg_hdr *hdr = NULL;
char *policy[] = {"id"};
int rem = 0;
int i = 0;
blob_for_each_attr(pos, attr, rem) {
if (i > _MAX)
return 0;
hdr = blob_data(pos);
if (i == 0) {
if (strcmp(policy[i], (char *)hdr->name) != 0) {
MGUI_EMSG("format is error\n");
return -1;
}
}
tb[i] = pos;
i++;
}
return 0;
}
static int wifi_indication_clients(struct mgui_wifi_context *wifi, struct blob_attr *attr)
{
char *str = blobmsg_get_string(attr);
int num_clients;
MASSERT(wifi);
MGUI_DMSG("clients number changed to %s\n", str);
num_clients = atoi(str);
if (num_clients != wifi->status.num_clients) {
MGUI_IMSG("wifi status changed to %d\n", num_clients);
wifi->status.num_clients = num_clients;
mgui_active_clients_num_request(wifi);
}
return 0;
}
static int wifi_indication_status(struct mgui_wifi_context *wifi, struct blob_attr *attr)
{
char *str = blobmsg_get_string(attr);
int status;
MASSERT(wifi);
MGUI_DMSG("status changed to %s\n", str);
status = !strcmp(str, "ready");
MGUI_EMSG("status=%d\n", status);
if (status != wifi->status.wifi_status) {
MGUI_IMSG("wifi status changed to %s\n", str);
wifi->status.wifi_status = status;
mgui_wifi_info_request(wifi);
mgui_update_icon(wifi->mgui, MGUI_WIFI_ICON, (void *)wifi);
}
return 0;
}
static int wifi_indication_cb(struct ubus_context *ctx,
struct ubus_object *obj,
struct ubus_request_data *req,
const char *method, struct blob_attr *msg)
{
struct mgui_wifi_context *wifi = to_wifi_context(obj);
struct blob_attr *tb[_MAX] = { 0 };
unsigned int id;
struct blob_attr *attr;
int ret = 0;
ret = wifi_indication_parse_blobmsg(msg, tb);
if (ret < 0) {
MGUI_EMSG("parse msg error\n");
return -1;
}
if (!tb[REQID] || !tb[DATA]) {
MGUI_EMSG("Error: id or data not found\n");
return -1;
}
id = blobmsg_get_u32(tb[REQID]);
attr = tb[DATA];
MGUI_IMSG("id is %d, attr = %p\n", id, attr);
if (strcmp(method, "clients_change") == 0) {
ret = wifi_indication_clients(wifi, attr);
} else if (strcmp(method, "wifi_status_change") == 0) {
ret = wifi_indication_status(wifi, attr);
} else {
MGUI_EMSG("id of %d is not supported\n",id);
}
/*
switch (id) {
case WIFI_CLIENTS_NOTIFY_ID:
ret = wifi_indication_clients(wifi, attr);
break;
case WIFI_STATUS_NOTIFY_ID:
ret = wifi_indication_status(wifi, attr);
break;
default:
MGUI_EMSG("id of %d is not supported\n",id);
}
*/
/* refresh screen if required */
if (ret)
mgui_screen_refresh(wifi->mgui);
return 0;
}
/**
* mgui_wifi_exit
* De-initialize wifi interface
*
* @param wifi pointer to previously allocated wifi context
*
* @return 0 for success, error code otherwise
*/
int mgui_wifi_exit(struct mgui_wifi_context *wifi)
{
if(!wifi) {
MGUI_IMSG("wifi module not running\n");
return 0;
}
/*
mgui_ubus_unsubscribe(wifi->mgui->ubus,
&wifi->ubus_subscriber,
wifi->wifi_ubus_id);
*/
mgui_ubus_unsubscribe(wifi->mgui->ubus,
&wifi->ubus_subscriber,
wifi->statistics_ubus_id);
mgui_ubus_unregister_subscriber(wifi->mgui->ubus,
&wifi->ubus_subscriber);
if (wifi->status.channel)
free(wifi->status.channel);
if (wifi->status.device)
free(wifi->status.device);
if (wifi->status.on)
free(wifi->status.on);
if (wifi->status.key)
free(wifi->status.key);
if (wifi->status.encryption)
free(wifi->status.encryption);
free(wifi);
MGUI_IMSG("wifi exit done\n");
return 0;
}
/**
* mgui_wifi_init
* Initialize mgui wifi interface
*
* NOTE - must be called BEFORE uloop_run()!
*
* @param mgui mgui context
*
* @return pointer to mgui_wifi_context
*/
struct mgui_wifi_context *mgui_wifi_init(struct mgui_context *mgui)
{
struct mgui_wifi_context *wifi;
int ret;
MASSERT(mgui);
MASSERT(mgui->ubus);
wifi = malloc(sizeof(struct mgui_wifi_context));
if (!wifi) {
MGUI_EMSG("memory allocation failed\n");
return NULL;
}
memset(wifi, 0, sizeof(*wifi));
wifi->mgui = mgui;
ret = mgui_ubus_lookup_id(wifi->mgui->ubus, WIFI_UBUS_ID,
&wifi->wifi_ubus_id);
if (ret) {
MGUI_EMSG("mubus_lookup_id failed (ret=%d)\n", ret);
goto out_error;
}
ret = mgui_ubus_lookup_id(wifi->mgui->ubus, STATISTICS_UBUS_ID,
&wifi->statistics_ubus_id);
if (ret) {
MGUI_EMSG("mubus_lookup_id failed (ret=%d)\n", ret);
goto out_error;
}
ret = mgui_wifi_status_request(wifi);
if (ret) {
MGUI_EMSG("initial request failed\n");
goto out_error;
}
ret = mgui_active_clients_num_request(wifi);
if (ret) {
MGUI_EMSG("initial request failed\n");
goto out_error;
}
ret = mgui_wifi_info_request(wifi);
if (ret) {
MGUI_EMSG("initial request failed\n");
goto out_error;
}
wifi->ubus_subscriber.cb = wifi_indication_cb;
ret = mgui_ubus_register_subscriber(wifi->mgui->ubus,
&wifi->ubus_subscriber);
if (ret) {
MGUI_EMSG("mubus_register_subscriber failed\n");
goto out_error;
}
/*
ret = mgui_ubus_subscribe(wifi->mgui->ubus,
&wifi->ubus_subscriber,
wifi->wifi_ubus_id);
if (ret) {
MGUI_EMSG("ubus subscribe wireless failed\n");
goto unregister_subscriber;
}
*/
ret = mgui_ubus_subscribe(wifi->mgui->ubus,
&wifi->ubus_subscriber,
wifi->statistics_ubus_id);
if (ret) {
MGUI_EMSG("ubus subscribe statistics failed\n");
goto unregister_subscriber;
}
MGUI_IMSG("wifi init done\n");
return wifi;
/*
unsubscribe_wireless:
mgui_ubus_unsubscribe(wifi->mgui->ubus,
&wifi->ubus_subscriber,
wifi->wifi_ubus_id);
*/
unregister_subscriber:
mgui_ubus_unregister_subscriber(wifi->mgui->ubus,
&wifi->ubus_subscriber);
out_error:
free(wifi);
return NULL;
}