Skip to content

Commit

Permalink
net: l2: wifi: Add support for W-Fi mode setting and selection
Browse files Browse the repository at this point in the history
This change brings in support for setting various Wi-Fi modes and
enables a specific Wi-Fi interface to be also placed into a sniffer
operation via monitor mode and promiscuous mode. A raw TX- packet
Injection mode is also introduced

Signed-off-by: Vivekananda Uppunda <vivekananda.uppunda@nordicsemi.no>
  • Loading branch information
VivekUppunda committed Sep 12, 2023
1 parent 5689916 commit fd0c247
Show file tree
Hide file tree
Showing 4 changed files with 556 additions and 1 deletion.
33 changes: 33 additions & 0 deletions include/zephyr/net/wifi.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ static inline const char *wifi_band_txt(enum wifi_frequency_bands band)
#define WIFI_SAE_PSWD_MAX_LEN 128
#define WIFI_MAC_ADDR_LEN 6

#define WIFI_CHANNEL_MIN 1
#define WIFI_CHANNEL_MAX 233
#define WIFI_CHANNEL_ANY 255

Expand Down Expand Up @@ -355,6 +356,38 @@ static const char * const wifi_ps_mode2str[] = {
};
/** @endcond */

/* Interface index Min and Max values */
#define WIFI_INTERFACE_INDEX_MIN 1
#define WIFI_INTERFACE_INDEX_MAX 255

/** Wifi operational mode */
enum wifi_operational_modes {
/** STA mode setting enable */
WIFI_STA_MODE = BIT(0),
/** Monitor mode setting enable */
WIFI_MONITOR_MODE = BIT(1),
/** TX injection mode setting enable */
WIFI_TX_INJECTION_MODE = BIT(2),
/** Promiscuous mode setting enable */
WIFI_PROMISCUOUS_MODE = BIT(3),
/** AP mode setting enable */
WIFI_AP_MODE = BIT(4),
/** Softap mode setting enable */
WIFI_SOFTAP_MODE = BIT(5),
};

/** Mode filter settings */
enum wifi_filter {
/** Support management, data and control packet sniffing */
WIFI_PACKET_FILTER_ALL = BIT(0),
/** Support only sniffing of management packets */
WIFI_PACKET_FILTER_MGMT = BIT(1),
/** Support only sniffing of data packets */
WIFI_PACKET_FILTER_DATA = BIT(2),
/** Support only sniffing of control packets */
WIFI_PACKET_FILTER_CTRL = BIT(3),
};

/** Wi-Fi Target Wake Time (TWT) operations. */
enum wifi_twt_operation {
/** TWT setup operation */
Expand Down
76 changes: 76 additions & 0 deletions include/zephyr/net/wifi_mgmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ enum net_request_wifi_cmd {
NET_REQUEST_WIFI_CMD_REG_DOMAIN,
/** Set power save timeout */
NET_REQUEST_WIFI_CMD_PS_TIMEOUT,
/** Set or get Mode of operation */
NET_REQUEST_WIFI_CMD_MODE,
/** Set or get packet filter setting for current mode */
NET_REQUEST_WIFI_CMD_PACKET_FILTER,
/** Set or get Wi-Fi channel for Monitor or TX-Injection mode */
NET_REQUEST_WIFI_CMD_CHANNEL,
NET_REQUEST_WIFI_CMD_MAX
};

Expand Down Expand Up @@ -129,6 +135,21 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_REG_DOMAIN);

NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_PS_TIMEOUT);

#define NET_REQUEST_WIFI_MODE \
(_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_MODE)

NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_MODE);

#define NET_REQUEST_WIFI_PACKET_FILTER \
(_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_PACKET_FILTER)

NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_PACKET_FILTER);

#define NET_REQUEST_WIFI_CHANNEL \
(_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_CHANNEL)

NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_CHANNEL);

/** Wi-Fi management events */
enum net_event_wifi_cmd {
/** Scan results available */
Expand Down Expand Up @@ -473,6 +494,37 @@ union wifi_mgmt_events {
struct wifi_twt_params twt_params;
};

/** Wi-Fi mode setup */
struct wifi_mode_info {
/** Mode setting for a specific mode of operation */
uint8_t mode;
/** Interface index */
uint8_t if_index;
/** Get or set operation */
enum wifi_mgmt_op oper;
};

/** Wi-Fi filter setting for monitor, prmoiscuous, TX-injection modes */
struct wifi_filter_info {
/** Filter setting */
uint8_t filter;
/** Interface index */
uint8_t if_index;
/** Filter buffer size */
uint16_t buffer_size;
/** Get or set operation */
enum wifi_mgmt_op oper;
};

/** Wi-Fi channel setting for monitor and TX-injection modes */
struct wifi_channel_info {
/** Channel value to set */
uint16_t channel;
/** Interface index */
uint8_t if_index;
/** Get or set operation */
enum wifi_mgmt_op oper;
};

#include <zephyr/net/net_if.h>

Expand Down Expand Up @@ -594,6 +646,30 @@ struct wifi_mgmt_ops {
* @return 0 if ok, < 0 if error
*/
int (*reg_domain)(const struct device *dev, struct wifi_reg_domain *reg_domain);
/** Set or get packet filter settings for monitor and promiscuous modes
*
* @param dev Pointer to the device structure for the driver instance.
* @param packet filter settings
*
* @return 0 if ok, < 0 if error
*/
int (*filter)(const struct device *dev, struct wifi_filter_info *filter);
/** Set or get mode of operation
*
* @param dev Pointer to the device structure for the driver instance.
* @param mode settings
*
* @return 0 if ok, < 0 if error
*/
int (*mode)(const struct device *dev, struct wifi_mode_info *mode);
/** Set or get current channel of operation
*
* @param dev Pointer to the device structure for the driver instance.
* @param channel settings
*
* @return 0 if ok, < 0 if error
*/
int (*channel)(const struct device *dev, struct wifi_channel_info *channel);
};

/** Wi-Fi management offload API */
Expand Down
60 changes: 60 additions & 0 deletions subsys/net/l2/wifi/wifi_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,66 @@ void wifi_mgmt_raise_twt_sleep_state(struct net_if *iface,
sizeof(twt_sleep_state));
}

static int wifi_mode(uint32_t mgmt_request, struct net_if *iface,
void *data, size_t len)
{
const struct device *dev = net_if_get_device(iface);
const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
struct wifi_mode_info *mode_info = data;

if (dev == NULL) {
return -ENODEV;
}

if (wifi_mgmt_api == NULL || wifi_mgmt_api->mode == NULL) {
return -ENOTSUP;
}

return wifi_mgmt_api->mode(dev, mode_info);
}

NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_MODE, wifi_mode);

static int wifi_packet_filter(uint32_t mgmt_request, struct net_if *iface,
void *data, size_t len)
{
const struct device *dev = net_if_get_device(iface);
const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
struct wifi_filter_info *filter_info = data;

if (dev == NULL) {
return -ENODEV;
}

if (wifi_mgmt_api == NULL || wifi_mgmt_api->filter == NULL) {
return -ENOTSUP;
}

return wifi_mgmt_api->filter(dev, filter_info);
}

NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PACKET_FILTER, wifi_packet_filter);

static int wifi_channel(uint32_t mgmt_request, struct net_if *iface,
void *data, size_t len)
{
const struct device *dev = net_if_get_device(iface);
const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
struct wifi_channel_info *channel_info = data;

if (dev == NULL) {
return -ENODEV;
}

if (wifi_mgmt_api == NULL || wifi_mgmt_api->channel == NULL) {
return -ENOTSUP;
}

return wifi_mgmt_api->channel(dev, channel_info);
}

NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_CHANNEL, wifi_channel);

#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS
void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface,
struct wifi_raw_scan_result *raw_scan_result)
Expand Down

0 comments on commit fd0c247

Please sign in to comment.