net: wifi: split wifi interface into STA and uAP

Split wifi interface into station mode and soft-AP mode, as there may be
station and soft-AP two interfaces that work concurrently.

Signed-off-by: Maochen Wang <maochen.wang@nxp.com>
This commit is contained in:
Maochen Wang 2024-05-22 12:11:09 +08:00 committed by Alberto Escolar
parent 7f0f0a4f97
commit 762169034b
6 changed files with 157 additions and 11 deletions

View file

@ -3063,6 +3063,20 @@ bool net_if_is_wifi(struct net_if *iface);
*/
struct net_if *net_if_get_first_wifi(void);
/**
* @brief Get Wi-Fi network station interface.
*
* @return Pointer to network interface, NULL if not found.
*/
struct net_if *net_if_get_wifi_sta(void);
/**
* @brief Get first Wi-Fi network Soft-AP interface.
*
* @return Pointer to network interface, NULL if not found.
*/
struct net_if *net_if_get_wifi_sap(void);
/**
* @brief Get network interface name.
*

View file

@ -30,6 +30,24 @@
extern "C" {
#endif
/** Types of Wi-Fi interface */
enum wifi_nm_iface_type {
/** IEEE 802.11 Wi-Fi Station */
WIFI_TYPE_STA = 0,
/** IEEE 802.11 Wi-Fi Soft AP */
WIFI_TYPE_SAP,
};
/**
* @brief WiFi Network Managed interfaces
*/
struct wifi_nm_mgd_iface {
/** Wi-Fi interface type */
unsigned char type;
/** Managed net interfaces */
struct net_if *iface;
};
/**
* @brief WiFi Network manager instance
*/
@ -39,7 +57,7 @@ struct wifi_nm_instance {
/** Wi-Fi Management operations */
const struct wifi_mgmt_ops *ops;
/** List of Managed interfaces */
struct net_if *mgd_ifaces[CONFIG_WIFI_NM_MAX_MANAGED_INTERFACES];
struct wifi_nm_mgd_iface mgd_ifaces[CONFIG_WIFI_NM_MAX_MANAGED_INTERFACES];
};
/** @cond INTERNAL_HIDDEN */
@ -50,7 +68,7 @@ struct wifi_nm_instance {
static STRUCT_SECTION_ITERABLE(wifi_nm_instance, WIFI_NM_NAME(_name)) = { \
.name = STRINGIFY(_name), \
.ops = _ops, \
.mgd_ifaces = { NULL }, \
.mgd_ifaces = {}, \
}
/** @endcond */
@ -71,6 +89,14 @@ struct wifi_nm_instance *wifi_nm_get_instance(const char *name);
*/
struct wifi_nm_instance *wifi_nm_get_instance_iface(struct net_if *iface);
/**
* @brief Get a Wi-Fi type for a given interface
*
* @param iface Interface
*
*/
unsigned char wifi_nm_get_type_iface(struct net_if *iface);
/**
* @brief Register a managed interface
*
@ -84,6 +110,21 @@ struct wifi_nm_instance *wifi_nm_get_instance_iface(struct net_if *iface);
*/
int wifi_nm_register_mgd_iface(struct wifi_nm_instance *nm, struct net_if *iface);
/**
* @brief Register a managed interface
*
* @param nm Pointer to Network manager instance
* @param type Wi-Fi type
* @param iface Managed interface
*
* @retval 0 If successful.
* @retval -EINVAL If invalid parameters were passed.
* @retval -ENOTSUP If the interface is not a Wi-Fi interface.
* @retval -ENOMEM If the maximum number of managed interfaces has been reached.
*/
int wifi_nm_register_mgd_type_iface(struct wifi_nm_instance *nm,
enum wifi_nm_iface_type type, struct net_if *iface);
/**
* @brief Unregister managed interface
*

View file

@ -412,6 +412,10 @@ static void iface_cb(struct net_if *iface, void *user_data)
return;
}
if (wifi_nm_get_type_iface(iface) != (1 << WIFI_TYPE_STA)) {
return;
}
if (!net_if_is_up(iface)) {
return;
}

View file

@ -23,6 +23,9 @@ LOG_MODULE_REGISTER(net_if, CONFIG_NET_IF_LOG_LEVEL);
#include <zephyr/net/net_if.h>
#include <zephyr/net/net_mgmt.h>
#include <zephyr/net/ethernet.h>
#ifdef CONFIG_WIFI_NM
#include <zephyr/net/wifi_nm.h>
#endif
#include <zephyr/net/offloaded_netdev.h>
#include <zephyr/net/virtual.h>
#include <zephyr/net/socket.h>
@ -5681,6 +5684,40 @@ struct net_if *net_if_get_first_wifi(void)
return NULL;
}
struct net_if *net_if_get_wifi_sta(void)
{
struct ethernet_context *eth_ctx = NULL;
STRUCT_SECTION_FOREACH(net_if, iface) {
eth_ctx = net_if_l2_data(iface);
if (net_if_is_wifi(iface)
#ifdef CONFIG_WIFI_NM
&& (wifi_nm_get_type_iface(iface) == (1 << WIFI_TYPE_STA))
#endif
) {
return iface;
}
}
return NULL;
}
struct net_if *net_if_get_wifi_sap(void)
{
struct ethernet_context *eth_ctx = NULL;
STRUCT_SECTION_FOREACH(net_if, iface) {
eth_ctx = net_if_l2_data(iface);
if (net_if_is_wifi(iface)
#ifdef CONFIG_WIFI_NM
&& (wifi_nm_get_type_iface(iface) == (1 << WIFI_TYPE_SAP))
#endif
) {
return iface;
}
}
return NULL;
}
int net_if_get_name(struct net_if *iface, char *buf, int len)
{
#if defined(CONFIG_NET_INTERFACE_NAME)

View file

@ -33,7 +33,7 @@ struct wifi_nm_instance *wifi_nm_get_instance_iface(struct net_if *iface)
k_mutex_lock(&wifi_nm_lock, K_FOREVER);
STRUCT_SECTION_FOREACH(wifi_nm_instance, nm) {
for (int i = 0; i < CONFIG_WIFI_NM_MAX_MANAGED_INTERFACES; i++) {
if (nm->mgd_ifaces[i] == iface) {
if (nm->mgd_ifaces[i].iface == iface) {
k_mutex_unlock(&wifi_nm_lock);
return nm;
}
@ -44,6 +44,26 @@ struct wifi_nm_instance *wifi_nm_get_instance_iface(struct net_if *iface)
return NULL;
}
unsigned char wifi_nm_get_type_iface(struct net_if *iface)
{
if (!iface || !net_if_is_wifi(iface)) {
return 0;
}
k_mutex_lock(&wifi_nm_lock, K_FOREVER);
STRUCT_SECTION_FOREACH(wifi_nm_instance, nm) {
for (int i = 0; i < CONFIG_WIFI_NM_MAX_MANAGED_INTERFACES; i++) {
if (nm->mgd_ifaces[i].iface == iface) {
k_mutex_unlock(&wifi_nm_lock);
return nm->mgd_ifaces[i].type;
}
}
}
k_mutex_unlock(&wifi_nm_lock);
return 0;
}
int wifi_nm_register_mgd_iface(struct wifi_nm_instance *nm, struct net_if *iface)
{
if (!nm || !iface) {
@ -56,8 +76,38 @@ int wifi_nm_register_mgd_iface(struct wifi_nm_instance *nm, struct net_if *iface
k_mutex_lock(&wifi_nm_lock, K_FOREVER);
for (int i = 0; i < CONFIG_WIFI_NM_MAX_MANAGED_INTERFACES; i++) {
if (!nm->mgd_ifaces[i]) {
nm->mgd_ifaces[i] = iface;
if (nm->mgd_ifaces[i].iface == iface) {
k_mutex_unlock(&wifi_nm_lock);
return 0;
}
if (!nm->mgd_ifaces[i].iface) {
nm->mgd_ifaces[i].iface = iface;
k_mutex_unlock(&wifi_nm_lock);
return 0;
}
}
k_mutex_unlock(&wifi_nm_lock);
return -ENOMEM;
}
int wifi_nm_register_mgd_type_iface(struct wifi_nm_instance *nm,
enum wifi_nm_iface_type type, struct net_if *iface)
{
if (!nm || !iface) {
return -EINVAL;
}
if (!net_if_is_wifi(iface)) {
return -ENOTSUP;
}
k_mutex_lock(&wifi_nm_lock, K_FOREVER);
for (int i = 0; i < CONFIG_WIFI_NM_MAX_MANAGED_INTERFACES; i++) {
if (!nm->mgd_ifaces[i].iface) {
nm->mgd_ifaces[i].iface = iface;
nm->mgd_ifaces[i].type = (1 << type);
k_mutex_unlock(&wifi_nm_lock);
return 0;
}
@ -75,8 +125,8 @@ int wifi_nm_unregister_mgd_iface(struct wifi_nm_instance *nm, struct net_if *ifa
k_mutex_lock(&wifi_nm_lock, K_FOREVER);
for (int i = 0; i < CONFIG_WIFI_NM_MAX_MANAGED_INTERFACES; i++) {
if (nm->mgd_ifaces[i] == iface) {
nm->mgd_ifaces[i] = NULL;
if (nm->mgd_ifaces[i].iface == iface) {
nm->mgd_ifaces[i].iface = NULL;
k_mutex_unlock(&wifi_nm_lock);
return 0;
}

View file

@ -607,7 +607,7 @@ static int __wifi_args_to_params(const struct shell *sh, size_t argc, char *argv
static int cmd_wifi_connect(const struct shell *sh, size_t argc,
char *argv[])
{
struct net_if *iface = net_if_get_first_wifi();
struct net_if *iface = net_if_get_wifi_sta();
struct wifi_connect_req_params cnx_params = { 0 };
int ret;
@ -634,7 +634,7 @@ static int cmd_wifi_connect(const struct shell *sh, size_t argc,
static int cmd_wifi_disconnect(const struct shell *sh, size_t argc,
char *argv[])
{
struct net_if *iface = net_if_get_first_wifi();
struct net_if *iface = net_if_get_wifi_sta();
int status;
context.disconnecting = true;
@ -1263,7 +1263,7 @@ static int cmd_wifi_twt_teardown_all(const struct shell *sh, size_t argc,
static int cmd_wifi_ap_enable(const struct shell *sh, size_t argc,
char *argv[])
{
struct net_if *iface = net_if_get_first_wifi();
struct net_if *iface = net_if_get_wifi_sap();
static struct wifi_connect_req_params cnx_params;
int ret;
@ -1290,7 +1290,7 @@ static int cmd_wifi_ap_enable(const struct shell *sh, size_t argc,
static int cmd_wifi_ap_disable(const struct shell *sh, size_t argc,
char *argv[])
{
struct net_if *iface = net_if_get_first_wifi();
struct net_if *iface = net_if_get_wifi_sap();
int ret;
ret = net_mgmt(NET_REQUEST_WIFI_AP_DISABLE, iface, NULL, 0);