net/mgmt/wifi: Add dedicated net mgmt hooks for WiFi offload devices

Exposing connect, disconnect and scan for now.

In case the iface is an instance of a WiFi offload device, the way it
manages scanning, connecting and disconnecting will be specific to that
device (not the mgmt interface obviously). In such case the device will
have to export relevantly a dedicated bunch of function to serve the
mgmt interface in a generic way.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
Tomasz Bursztyka 2017-12-04 13:17:42 +01:00 committed by Anas Nashif
commit eab3f168fd
5 changed files with 171 additions and 1 deletions

View file

@ -36,4 +36,11 @@ config WIFI_INIT_PRIORITY
Note that the priority needs to be lower than the net stack
so that it can start before the networking sub-system.
config WIFI_OFFLOAD
bool "Support offloaded WiFi device drivers"
default n
select NET_OFFLOAD
help
Enable support for Full-MAC WiFi devices.
endif # WIFI

View file

@ -12,6 +12,11 @@
#ifndef __WIFI_H__
#define __WIFI_H__
enum wifi_security_type {
WIFI_SECURITY_TYPE_NONE = 0,
WIFI_SECURITY_TYPE_PSK,
};
#define WIFI_SSID_MAX_LEN 32
#define WIFI_PSK_MAX_LEN 64
@ -19,4 +24,3 @@
#define WIFI_CHANNEL_ANY 255
#endif /* __WIFI_H__ */

View file

@ -13,6 +13,7 @@
#define __WIFI_MGMT_H__
#include <net/net_mgmt.h>
#include <net/wifi.h>
/* Management part definitions */
@ -46,6 +47,7 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_DISCONNECT);
enum net_event_wifi_cmd {
NET_EVENT_WIFI_CMD_SCAN_RESULT = 1,
NET_EVENT_WIFI_CMD_SCAN_DONE,
NET_EVENT_WIFI_CMD_CONNECT_RESULT,
NET_EVENT_WIFI_CMD_DISCONNECT_RESULT,
};
@ -53,10 +55,72 @@ enum net_event_wifi_cmd {
#define NET_EVENT_WIFI_SCAN_RESULT \
(_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_SCAN_RESULT)
#define NET_EVENT_WIFI_SCAN_DONE \
(_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_SCAN_DONE)
#define NET_EVENT_WIFI_CONNECT_RESULT \
(_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_CONNECT_RESULT)
#define NET_EVENT_WIFI_DISCONNECT_RESULT \
(_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_DISCONNECT_RESULT)
/* Each result is provided to the net_mgmt_event_callback
* via its info attribute (see net_mgmt.h)
*/
struct wifi_scan_result {
u8_t ssid[WIFI_SSID_MAX_LEN];
u8_t ssid_length;
u8_t channel;
enum wifi_security_type security;
s8_t rssi;
};
struct wifi_connect_req_params {
u8_t *ssid;
u8_t ssid_length; /* Max 32 */
u8_t *psk;
u8_t psk_length; /* Min 8 - Max 64 */
u8_t channel;
enum wifi_security_type security;
};
struct wifi_status {
int status;
};
#ifdef CONFIG_WIFI_OFFLOAD
#include <net/net_if.h>
typedef void (*scan_result_cb_t)(struct net_if *iface, int status,
struct wifi_scan_result *entry);
struct net_wifi_mgmt_offload {
/**
* Mandatory to get in first position.
* A network device should indeed provide a pointer on such
* net_if_api structure. So we make current structure pointer
* that can be casted to a net_if_api structure pointer.
*/
struct net_if_api iface_api;
/* cb parameter is the cb that should be called for each
* result by the driver. The wifi mgmt part will take care of
* raising the necessary event etc...
*/
int (*scan)(struct device *dev, scan_result_cb_t cb);
int (*connect)(struct device *dev,
struct wifi_connect_req_params *params);
int (*disconnect)(struct device *dev);
};
void wifi_mgmt_raise_connect_result_event(struct net_if *iface, int status);
void wifi_mgmt_raise_disconnect_result_event(struct net_if *iface, int status);
#endif /* CONFIG_WIFI_OFFLOAD */
#endif /* __WIFI_MGMT_H__ */

View file

@ -18,15 +18,72 @@
static int wifi_connect(u32_t mgmt_request, struct net_if *iface,
void *data, size_t len)
{
struct wifi_connect_req_params *params =
(struct wifi_connect_req_params *)data;
SYS_LOG_DBG("%s %u %u %u %s %u",
params->ssid, params->ssid_length,
params->channel, params->security,
params->psk, params->psk_length);
if ((params->security > WIFI_SECURITY_TYPE_PSK) ||
(params->ssid_length > WIFI_SSID_MAX_LEN) ||
(params->ssid_length == 0) ||
((params->security == WIFI_SECURITY_TYPE_PSK) &&
((params->psk_length < 8) || (params->psk_length > 64) ||
(params->psk_length == 0))) ||
((params->channel != WIFI_CHANNEL_ANY) &&
(params->channel > WIFI_CHANNEL_MAX)) ||
!params->ssid || !params->psk) {
return -EINVAL;
}
if (net_if_is_ip_offloaded(iface)) {
struct device *dev = net_if_get_device(iface);
struct net_wifi_mgmt_offload *off_api =
(struct net_wifi_mgmt_offload *) dev->driver_api;
return off_api->connect(dev, params);
}
return -ENETDOWN;
}
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_CONNECT, wifi_connect);
static void _scan_result_cb(struct net_if *iface, int status,
struct wifi_scan_result *entry)
{
if (!iface) {
return;
}
if (!entry) {
struct wifi_status scan_status = {
.status = status,
};
net_mgmt_event_notify_with_info(NET_EVENT_WIFI_SCAN_DONE,
iface, &scan_status,
sizeof(struct wifi_status));
return;
}
net_mgmt_event_notify_with_info(NET_EVENT_WIFI_SCAN_RESULT, iface,
entry, sizeof(struct wifi_scan_result));
}
static int wifi_scan(u32_t mgmt_request, struct net_if *iface,
void *data, size_t len)
{
if (net_if_is_ip_offloaded(iface)) {
struct device *dev = net_if_get_device(iface);
struct net_wifi_mgmt_offload *off_api =
(struct net_wifi_mgmt_offload *) dev->driver_api;
return off_api->scan(dev, _scan_result_cb);
}
return -ENETDOWN;
}
@ -36,7 +93,37 @@ NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_SCAN, wifi_scan);
static int wifi_disconnect(u32_t mgmt_request, struct net_if *iface,
void *data, size_t len)
{
if (net_if_is_ip_offloaded(iface)) {
struct device *dev = net_if_get_device(iface);
struct net_wifi_mgmt_offload *off_api =
(struct net_wifi_mgmt_offload *) dev->driver_api;
return off_api->disconnect(dev);
}
return -ENETDOWN;
}
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_DISCONNECT, wifi_disconnect);
void wifi_mgmt_raise_connect_result_event(struct net_if *iface, int status)
{
struct wifi_status cnx_status = {
.status = status,
};
net_mgmt_event_notify_with_info(NET_EVENT_WIFI_CONNECT_RESULT,
iface, &cnx_status,
sizeof(struct wifi_status));
}
void wifi_mgmt_raise_disconnect_result_event(struct net_if *iface, int status)
{
struct wifi_status cnx_status = {
.status = status,
};
net_mgmt_event_notify_with_info(NET_EVENT_WIFI_DISCONNECT_RESULT,
iface, &cnx_status,
sizeof(struct wifi_status));
}

View file

@ -24,8 +24,16 @@
* NOTE: Update comments here and calculate which struct occupies max size.
*/
#ifdef CONFIG_NET_L2_WIFI_MGMT
#include <net/wifi_mgmt.h>
#define NET_EVENT_INFO_MAX_SIZE sizeof(struct wifi_scan_result)
#else
#define NET_EVENT_INFO_MAX_SIZE sizeof(struct net_event_ipv6_route)
#endif /* CONFIG_NET_L2_WIFI_MGMT */
#endif /* CONFIG_NET_MGMT_EVENT_INFO */
#include "connection.h"