Browse Source

hostap: Relocate hostapd related source code to new files

Created new files and relocate hostapd support code in glue layer to new
files. The new files will be compiled only if hostapd support is enabled.

Signed-off-by: Hui Bai <hui.bai@nxp.com>
pull/88356/head
Hui Bai 7 months ago committed by Benjamin Cabé
parent
commit
58c932cc46
  1. 5
      modules/hostap/CMakeLists.txt
  2. 1
      modules/hostap/Kconfig
  3. 1032
      modules/hostap/src/hapd_api.c
  4. 91
      modules/hostap/src/hapd_api.h
  5. 122
      modules/hostap/src/hapd_events.c
  6. 24
      modules/hostap/src/hapd_events.h
  7. 572
      modules/hostap/src/hapd_main.c
  8. 21
      modules/hostap/src/hapd_main.h
  9. 1106
      modules/hostap/src/supp_api.c
  10. 77
      modules/hostap/src/supp_api.h
  11. 74
      modules/hostap/src/supp_events.c
  12. 3
      modules/hostap/src/supp_events.h
  13. 577
      modules/hostap/src/supp_main.c
  14. 10
      modules/hostap/src/supp_main.h
  15. 4
      west.yml

5
modules/hostap/CMakeLists.txt

@ -249,6 +249,11 @@ zephyr_library_sources_ifdef(CONFIG_WIFI_NM_HOSTAPD_AP @@ -249,6 +249,11 @@ zephyr_library_sources_ifdef(CONFIG_WIFI_NM_HOSTAPD_AP
${WIFI_NM_HOSTAPD_BASE}/eap_register.c
${WIFI_NM_HOSTAPD_BASE}/hostapd_cli_cmds.c
${WIFI_NM_HOSTAPD_BASE}/hostapd_cli_zephyr.c
# Zephyr specific files (glue code)
src/hapd_main.c
src/hapd_api.c
src/hapd_events.c
)
zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_HOSTAPD_AP

1
modules/hostap/Kconfig

@ -294,6 +294,7 @@ config WIFI_NM_HOSTAPD_AP @@ -294,6 +294,7 @@ config WIFI_NM_HOSTAPD_AP
config WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE
bool "Hostapd crypto enterprise support"
depends on WIFI_NM_HOSTAPD_AP
config EAP_SERVER_TLS
bool "EAP-TLS server support"

1032
modules/hostap/src/hapd_api.c

File diff suppressed because it is too large Load Diff

91
modules/hostap/src/hapd_api.h

@ -0,0 +1,91 @@ @@ -0,0 +1,91 @@
/**
* Copyright 2023-2024 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __HAPD_API_H_
#define __HAPD_API_H_
#ifdef CONFIG_WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE
int hostapd_add_enterprise_creds(const struct device *dev,
struct wifi_enterprise_creds_params *creds);
#endif
/**
* @brief Wi-Fi AP configuration parameter.
*
* @param dev Wi-Fi device
* @param params AP parameters
* @return 0 for OK; -1 for ERROR
*/
int hostapd_ap_config_params(const struct device *dev, struct wifi_ap_config_params *params);
/**
* @brief Set Wi-Fi AP region domain
*
* @param reg_domain region domain parameters
* @return true for OK; false for ERROR
*/
bool hostapd_ap_reg_domain(struct wifi_reg_domain *reg_domain);
#ifdef CONFIG_WIFI_NM_HOSTAPD_WPS
/** Start AP WPS PBC/PIN
*
* @param dev Pointer to the device structure for the driver instance
* @param params wps operarion parameters
*
* @return 0 if ok, < 0 if error
*/
int hostapd_ap_wps_config(const struct device *dev, struct wifi_wps_config_params *params);
#endif
/**
* @brief Get Wi-Fi SAP status
*
* @param dev Wi-Fi device
* @param status SAP status
* @return 0 for OK; -1 for ERROR
*/
int hostapd_ap_status(const struct device *dev, struct wifi_iface_status *status);
/**
* @brief Set Wi-Fi AP configuration
*
* @param dev Wi-Fi interface name to use
* @param params AP configuration parameters to set
* @return 0 for OK; -1 for ERROR
*/
int hostapd_ap_enable(const struct device *dev,
struct wifi_connect_req_params *params);
/**
* @brief Disable Wi-Fi AP
* @param dev Wi-Fi interface name to use
* @return 0 for OK; -1 for ERROR
*/
int hostapd_ap_disable(const struct device *dev);
/**
* @brief Set Wi-Fi AP STA disconnect
* @param dev Wi-Fi interface name to use
* @param mac_addr MAC address of the station to disconnect
* @return 0 for OK; -1 for ERROR
*/
int hostapd_ap_sta_disconnect(const struct device *dev,
const uint8_t *mac_addr);
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP
#ifdef CONFIG_WIFI_NM_HOSTAPD_AP
/**
* @brief Dispatch DPP operations for AP
*
* @param dev Wi-Fi interface name to use
* @param dpp_params DPP action enum and params in string
* @return 0 for OK; -1 for ERROR
*/
int hostapd_dpp_dispatch(const struct device *dev, struct wifi_dpp_params *params);
#endif /* CONFIG_WIFI_NM_HOSTAPD_AP */
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP */
#endif /* __HAPD_API_H_ */

122
modules/hostap/src/hapd_events.c

@ -0,0 +1,122 @@ @@ -0,0 +1,122 @@
/**
* Copyright 2023-2024 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "includes.h"
#include "common.h"
#include "ap/sta_info.h"
#include "ap/ieee802_11.h"
#include "ap/hostapd.h"
#include "wpa_supplicant_i.h"
#include <zephyr/net/wifi_mgmt.h>
#include "hapd_events.h"
#include "supp_events.h"
static enum wifi_link_mode hapd_get_sta_link_mode(struct hostapd_iface *iface,
struct sta_info *sta)
{
if (sta->flags & WLAN_STA_HE) {
return WIFI_6;
} else if (sta->flags & WLAN_STA_VHT) {
return WIFI_5;
} else if (sta->flags & WLAN_STA_HT) {
return WIFI_4;
} else if ((sta->flags & WLAN_STA_NONERP) ||
(iface->current_mode->mode == HOSTAPD_MODE_IEEE80211B)) {
return WIFI_1;
} else if (iface->freq > 4000) {
return WIFI_2;
} else if (iface->freq > 2000) {
return WIFI_3;
} else {
return WIFI_LINK_MODE_UNKNOWN;
}
}
static bool hapd_is_twt_capable(struct hostapd_iface *iface, struct sta_info *sta)
{
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_11AX
return hostapd_get_he_twt_responder(iface->bss[0], IEEE80211_MODE_AP);
#else
return false;
#endif
}
int hostapd_send_wifi_mgmt_ap_status(struct hostapd_iface *iface,
enum net_event_wifi_cmd event,
enum wifi_ap_status ap_status)
{
char *ifname = iface->conf->bss[0]->iface;
int status = ap_status;
return supplicant_send_wifi_mgmt_event(ifname,
event,
(void *)&status,
sizeof(int));
}
int hostapd_send_wifi_mgmt_ap_sta_event(struct hostapd_iface *ap_ctx,
enum net_event_wifi_cmd event,
void *data)
{
struct sta_info *sta = data;
char *ifname = ap_ctx->bss[0]->conf->iface;
struct wifi_ap_sta_info sta_info = { 0 };
if (!ap_ctx || !sta) {
return -EINVAL;
}
memcpy(sta_info.mac, sta->addr, sizeof(sta_info.mac));
if (event == NET_EVENT_WIFI_CMD_AP_STA_CONNECTED) {
sta_info.link_mode = hapd_get_sta_link_mode(ap_ctx, sta);
sta_info.twt_capable = hapd_is_twt_capable(ap_ctx, sta);
}
return supplicant_send_wifi_mgmt_event(ifname,
event,
(void *)&sta_info,
sizeof(sta_info));
}
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP
void hostapd_handle_dpp_event(void *ctx, char *buf, size_t len)
{
struct hostapd_data *hapd = (struct hostapd_data *)ctx;
if (hapd == NULL) {
return;
}
struct hostapd_bss_config *conf = hapd->conf;
if (conf == NULL || !(conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP)) {
return;
}
/* check hostapd */
if (!strncmp(buf, DPP_EVENT_CONNECTOR, sizeof(DPP_EVENT_CONNECTOR) - 1)) {
if (conf->dpp_connector) {
os_free(conf->dpp_connector);
}
conf->dpp_connector = os_strdup(buf + sizeof(DPP_EVENT_CONNECTOR) - 1);
} else if (!strncmp(buf, DPP_EVENT_C_SIGN_KEY, sizeof(DPP_EVENT_C_SIGN_KEY) - 1)) {
if (conf->dpp_csign) {
wpabuf_free(conf->dpp_csign);
}
conf->dpp_csign = wpabuf_parse_bin(buf + sizeof(DPP_EVENT_C_SIGN_KEY) - 1);
} else if (!strncmp(buf, DPP_EVENT_NET_ACCESS_KEY, sizeof(DPP_EVENT_NET_ACCESS_KEY) - 1)) {
if (conf->dpp_netaccesskey) {
wpabuf_free(conf->dpp_netaccesskey);
}
conf->dpp_netaccesskey =
wpabuf_parse_bin(buf + sizeof(DPP_EVENT_NET_ACCESS_KEY) - 1);
}
}
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP */

24
modules/hostap/src/hapd_events.h

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __HAPD_EVENTS_H__
#define __HAPD_EVENTS_H__
#include <zephyr/net/wifi_mgmt.h>
int hostapd_send_wifi_mgmt_ap_status(struct hostapd_iface *iface,
enum net_event_wifi_cmd event,
enum wifi_ap_status ap_status);
int hostapd_send_wifi_mgmt_ap_sta_event(struct hostapd_iface *ap_ctx,
enum net_event_wifi_cmd event,
void *data);
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP
void hostapd_handle_dpp_event(void *ctx, char *buf, size_t len);
#endif
#endif /* __HAPD_EVENTS_H_ */

572
modules/hostap/src/hapd_main.c

@ -0,0 +1,572 @@ @@ -0,0 +1,572 @@
/**
* Copyright 2023-2024 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/net/wifi_mgmt.h>
#include <zephyr/net/wifi_nm.h>
#include "includes.h"
#include "common.h"
#include "eloop.h"
#include "wpa_supplicant_i.h"
#include "hostapd.h"
#include "hostapd_cli_zephyr.h"
#include "eap_register.h"
#include "ap_drv_ops.h"
#include "l2_packet/l2_packet.h"
#include "supp_main.h"
#include "hapd_main.h"
#include "supp_api.h"
#include "hapd_api.h"
#include "hapd_events.h"
static const struct wifi_mgmt_ops mgmt_ap_ops = {
.ap_enable = hostapd_ap_enable,
.ap_disable = hostapd_ap_disable,
.ap_sta_disconnect = hostapd_ap_sta_disconnect,
.iface_status = hostapd_ap_status,
#ifdef CONFIG_WIFI_NM_HOSTAPD_WPS
.wps_config = hostapd_ap_wps_config,
#endif
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP
.dpp_dispatch = hostapd_dpp_dispatch,
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP */
.ap_config_params = hostapd_ap_config_params,
.set_rts_threshold = supplicant_set_rts_threshold,
#ifdef CONFIG_WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE
.enterprise_creds = hostapd_add_enterprise_creds,
#endif
.set_btwt = supplicant_set_btwt,
};
DEFINE_WIFI_NM_INSTANCE(hostapd, &mgmt_ap_ops);
struct hapd_global {
void **drv_priv;
size_t drv_count;
};
static struct hapd_global hglobal;
#ifndef HOSTAPD_CLEANUP_INTERVAL
#define HOSTAPD_CLEANUP_INTERVAL 10
#endif /* HOSTAPD_CLEANUP_INTERVAL */
static int hostapd_periodic_call(struct hostapd_iface *iface, void *ctx)
{
hostapd_periodic_iface(iface);
return 0;
}
/* Periodic cleanup tasks */
static void hostapd_periodic(void *eloop_ctx, void *timeout_ctx)
{
struct hapd_interfaces *interfaces = eloop_ctx;
eloop_register_timeout(HOSTAPD_CLEANUP_INTERVAL, 0,
hostapd_periodic, interfaces, NULL);
hostapd_for_each_interface(interfaces, hostapd_periodic_call, NULL);
}
struct hostapd_iface *zephyr_get_hapd_handle_by_ifname(const char *ifname)
{
struct hapd_interfaces *interfaces = zephyr_get_default_hapd_context();
struct hostapd_data *hapd = NULL;
hapd = hostapd_get_iface(interfaces, ifname);
if (!hapd) {
wpa_printf(MSG_ERROR, "%s: Unable to get hapd handle for %s\n", __func__, ifname);
return NULL;
}
return hapd->iface;
}
static void hostapd_event_eapol_rx_cb(void *ctx, const u8 *src_addr,
const u8 *buf, size_t len)
{
hostapd_event_eapol_rx(ctx, src_addr, buf, len, FRAME_ENCRYPTION_UNKNOWN, -1);
}
struct hostapd_iface *hostapd_get_interface(const char *ifname)
{
struct hapd_interfaces *interfaces = zephyr_get_default_hapd_context();
return interfaces->iface[0];
}
static int hostapd_enable_iface_cb(struct hostapd_iface *hapd_iface)
{
struct hostapd_data *bss;
wpa_printf(MSG_DEBUG, "Enable interface %s", hapd_iface->conf->bss[0]->iface);
bss = hapd_iface->bss[0];
bss->conf->start_disabled = 0;
if (hostapd_config_check(hapd_iface->conf, 1) < 0) {
wpa_printf(MSG_INFO, "Invalid configuration - cannot enable");
return -1;
}
l2_packet_deinit(bss->l2);
bss->l2 = l2_packet_init(bss->conf->iface, bss->conf->bssid, ETH_P_EAPOL,
&hostapd_event_eapol_rx_cb, bss, 0);
if (bss->l2 == NULL) {
wpa_printf(MSG_ERROR, "Failed to initialize l2 for hostapd interface");
return -1;
}
if (hostapd_setup_interface(hapd_iface)) {
wpa_printf(MSG_ERROR, "Failed to initialize hostapd interface");
return -1;
}
return 0;
}
static int hostapd_disable_iface_cb(struct hostapd_iface *hapd_iface)
{
size_t j;
struct hostapd_data *hapd = NULL;
wpa_msg(hapd_iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
hapd_iface->driver_ap_teardown = !!(hapd_iface->drv_flags
& WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
#ifdef NEED_AP_MLME
for (j = 0; j < hapd_iface->num_bss; j++) {
hostapd_cleanup_cs_params(hapd_iface->bss[j]);
}
#endif /* NEED_AP_MLME */
/* Same as hostapd_interface_deinit() without deinitializing control
* interface
*/
for (j = 0; j < hapd_iface->num_bss; j++) {
hapd = hapd_iface->bss[j];
hostapd_bss_deinit_no_free(hapd);
hostapd_free_hapd_data(hapd);
}
hostapd_drv_stop_ap(hapd);
hostapd_cleanup_iface_partial(hapd_iface);
wpa_printf(MSG_DEBUG, "Interface %s disabled", hapd_iface->bss[0]->conf->iface);
hostapd_set_state(hapd_iface, HAPD_IFACE_DISABLED);
hostapd_send_wifi_mgmt_ap_status(hapd_iface,
NET_EVENT_WIFI_CMD_AP_DISABLE_RESULT,
WIFI_STATUS_AP_SUCCESS);
hostapd_config_free(hapd_iface->conf);
hapd_iface->conf = hapd_iface->interfaces->config_read_cb(hapd_iface->config_fname);
for (j = 0; j < hapd_iface->num_bss; j++) {
hapd = hapd_iface->bss[j];
hapd->iconf = hapd_iface->conf;
hapd->conf = hapd_iface->conf->bss[j];
hapd->driver = hapd_iface->conf->driver;
}
return 0;
}
static int hostapd_global_init(struct hapd_interfaces *interfaces, const char *entropy_file)
{
int i;
os_memset(&hglobal, 0, sizeof(struct hapd_global));
if (eap_server_register_methods()) {
wpa_printf(MSG_ERROR, "Failed to register EAP methods");
return -1;
}
interfaces->eloop_initialized = 1;
for (i = 0; wpa_drivers[i]; i++) {
hglobal.drv_count++;
}
if (hglobal.drv_count == 0) {
wpa_printf(MSG_ERROR, "No drivers enabled");
return -1;
}
hglobal.drv_priv = os_calloc(hglobal.drv_count, sizeof(void *));
if (hglobal.drv_priv == NULL) {
return -1;
}
return 0;
}
const char *zephyr_hostap_msg_ifname_cb(void *ctx)
{
if (ctx == NULL) {
return NULL;
}
if ((*((int *)ctx)) == 0) {
struct wpa_supplicant *wpa_s = ctx;
return wpa_s->ifname;
}
struct hostapd_data *hapd = ctx;
if (hapd && hapd->conf) {
return hapd->conf->iface;
}
return NULL;
}
void zephyr_hostap_ctrl_iface_msg_cb(void *ctx, int level, enum wpa_msg_type type,
const char *txt, size_t len)
{
if (ctx == NULL) {
return;
}
if ((*((int *)ctx)) == 0) {
wpa_supplicant_msg_send(ctx, level, type, txt, len);
} else {
hostapd_msg_send(ctx, level, type, txt, len);
}
}
static int hostapd_driver_init(struct hostapd_iface *iface)
{
struct wpa_init_params params;
size_t i;
struct hostapd_data *hapd = iface->bss[0];
struct hostapd_bss_config *conf = hapd->conf;
u8 *b = conf->bssid;
struct wpa_driver_capa capa;
if (hapd->driver == NULL || hapd->driver->hapd_init == NULL) {
wpa_printf(MSG_ERROR, "No hostapd driver wrapper available");
return -1;
}
/* Initialize the driver interface */
if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5])) {
b = NULL;
}
os_memset(&params, 0, sizeof(params));
for (i = 0; wpa_drivers[i]; i++) {
if (wpa_drivers[i] != hapd->driver) {
continue;
}
if (hglobal.drv_priv[i] == NULL && wpa_drivers[i]->global_init) {
hglobal.drv_priv[i] = wpa_drivers[i]->global_init(iface->interfaces);
if (hglobal.drv_priv[i] == NULL) {
wpa_printf(MSG_ERROR, "Failed to initialize driver '%s'",
wpa_drivers[i]->name);
return -1;
}
hglobal.drv_count++;
}
params.global_priv = hglobal.drv_priv[i];
break;
}
params.bssid = b;
params.ifname = hapd->conf->iface;
params.driver_params = hapd->iconf->driver_params;
params.use_pae_group_addr = hapd->conf->use_pae_group_addr;
params.num_bridge = hapd->iface->num_bss;
params.bridge = os_calloc(hapd->iface->num_bss, sizeof(char *));
if (params.bridge == NULL) {
return -1;
}
for (i = 0; i < hapd->iface->num_bss; i++) {
struct hostapd_data *bss = hapd->iface->bss[i];
if (bss->conf->bridge[0]) {
params.bridge[i] = bss->conf->bridge;
}
}
params.own_addr = hapd->own_addr;
hapd->drv_priv = hapd->driver->hapd_init(hapd, &params);
os_free(params.bridge);
if (hapd->drv_priv == NULL) {
wpa_printf(MSG_ERROR, "%s driver initialization failed.",
hapd->driver->name);
hapd->driver = NULL;
return -1;
}
if (hapd->driver->get_capa && hapd->driver->get_capa(hapd->drv_priv, &capa) == 0) {
struct wowlan_triggers *triggs;
iface->drv_flags = capa.flags;
iface->drv_flags2 = capa.flags2;
iface->probe_resp_offloads = capa.probe_resp_offloads;
/*
* Use default extended capa values from per-radio information
*/
iface->extended_capa = capa.extended_capa;
iface->extended_capa_mask = capa.extended_capa_mask;
iface->extended_capa_len = capa.extended_capa_len;
iface->drv_max_acl_mac_addrs = capa.max_acl_mac_addrs;
/*
* Override extended capa with per-interface type (AP), if
* available from the driver.
*/
hostapd_get_ext_capa(iface);
triggs = wpa_get_wowlan_triggers(conf->wowlan_triggers, &capa);
if (triggs && hapd->driver->set_wowlan) {
if (hapd->driver->set_wowlan(hapd->drv_priv, triggs)) {
wpa_printf(MSG_ERROR, "set_wowlan failed");
}
}
os_free(triggs);
}
return 0;
}
struct hostapd_config *hostapd_config_read2(const char *fname)
{
struct hostapd_config *conf;
const struct device *dev;
char ifname[IFNAMSIZ + 1] = {0};
int errors = 0;
size_t i;
int aCWmin = 4, aCWmax = 10;
/* background traffic */
struct hostapd_wmm_ac_params ac_bk = {aCWmin, aCWmax, 9, 0, 0};
/* best effort traffic */
struct hostapd_wmm_ac_params ac_be = {aCWmin, aCWmax - 4, 5, 0, 0};
/* video traffic */
struct hostapd_wmm_ac_params ac_vi = {aCWmin - 1, aCWmin, 3,
3008 / 32, 0};
/* voice traffic */
struct hostapd_wmm_ac_params ac_vo = {aCWmin - 2, aCWmin - 1, 3,
1504 / 32, 0};
dev = net_if_get_device(net_if_get_wifi_sap());
strncpy(ifname, dev->name, IFNAMSIZ);
ifname[IFNAMSIZ] = '\0';
conf = hostapd_config_defaults();
if (conf == NULL) {
return NULL;
}
conf->wmm_ac_params[0] = ac_be;
conf->wmm_ac_params[1] = ac_bk;
conf->wmm_ac_params[2] = ac_vi;
conf->wmm_ac_params[3] = ac_vo;
/* set default driver based on configuration */
conf->driver = wpa_drivers[0];
if (conf->driver == NULL) {
wpa_printf(MSG_ERROR, "No driver wrappers registered!");
hostapd_config_free(conf);
return NULL;
}
conf->last_bss = conf->bss[0];
struct hostapd_bss_config *bss;
bss = conf->last_bss;
bss->start_disabled = 1;
bss->max_num_sta = CONFIG_WIFI_MGMT_AP_MAX_NUM_STA;
bss->dtim_period = 1;
os_strlcpy(conf->bss[0]->iface, ifname, sizeof(conf->bss[0]->iface));
bss->logger_stdout_level = HOSTAPD_LEVEL_INFO;
bss->logger_stdout = 0xffff;
bss->nas_identifier = os_strdup("ap.example.com");
os_memcpy(conf->country, "US ", 3);
conf->hw_mode = HOSTAPD_MODE_IEEE80211G;
bss->wps_state = WPS_STATE_CONFIGURED;
bss->eap_server = 1;
#ifdef CONFIG_WPS
bss->ap_setup_locked = 1;
#endif
conf->channel = 1;
conf->acs = conf->channel == 0;
#ifdef CONFIG_ACS
conf->acs_num_scans = 1;
#endif
conf->ieee80211n = 1;
conf->ieee80211h = 0;
conf->ieee80211d = 1;
conf->acs_exclude_dfs = 1;
conf->ht_capab |= HT_CAP_INFO_SHORT_GI20MHZ;
bss->auth_algs = 1;
bss->okc = 1;
conf->no_pri_sec_switch = 1;
conf->ht_op_mode_fixed = 1;
conf->ieee80211ac = 1;
conf->vht_oper_chwidth = CHANWIDTH_USE_HT;
conf->vht_capab |= VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX;
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_11AX
conf->ieee80211ax = 1;
conf->he_oper_chwidth = CHANWIDTH_USE_HT;
conf->he_phy_capab.he_su_beamformer = 0;
conf->he_phy_capab.he_su_beamformee = 1;
conf->he_phy_capab.he_mu_beamformer = 0;
conf->he_op.he_bss_color = 1;
conf->he_op.he_default_pe_duration = 0;
/* Set default basic MCS/NSS set to single stream MCS 0-7 */
conf->he_op.he_basic_mcs_nss_set = 0xfffc;
#endif
for (i = 0; i < conf->num_bss; i++) {
hostapd_set_security_params(conf->bss[i], 1);
}
if (hostapd_config_check(conf, 1)) {
errors++;
}
#ifndef WPA_IGNORE_CONFIG_ERRORS
if (errors) {
wpa_printf(MSG_ERROR, "%d errors found in configuration file '%s'",
errors, fname);
hostapd_config_free(conf);
conf = NULL;
}
#endif /* WPA_IGNORE_CONFIG_ERRORS */
return conf;
}
static struct hostapd_iface *hostapd_interface_init(struct hapd_interfaces *interfaces,
const char *if_name,
const char *config_fname,
int debug)
{
struct hostapd_iface *iface;
int k;
wpa_printf(MSG_DEBUG, "Configuration file: %s", config_fname);
iface = hostapd_init(interfaces, config_fname);
if (!iface) {
return NULL;
}
if (if_name) {
os_strlcpy(iface->conf->bss[0]->iface, if_name,
sizeof(iface->conf->bss[0]->iface));
}
iface->interfaces = interfaces;
for (k = 0; k < debug; k++) {
if (iface->bss[0]->conf->logger_stdout_level > 0) {
iface->bss[0]->conf->logger_stdout_level--;
}
}
if (iface->conf->bss[0]->iface[0] == '\0' &&
!hostapd_drv_none(iface->bss[0])) {
wpa_printf(MSG_ERROR,
"Interface name not specified in %s, nor by '-i' parameter",
config_fname);
hostapd_interface_deinit_free(iface);
return NULL;
}
iface->bss[0]->is_hostapd = 1;
return iface;
}
void zephyr_hostapd_init(struct hapd_interfaces *interfaces)
{
size_t i;
int ret, debug = 0;
struct net_if *iface;
char ifname[IFNAMSIZ + 1] = { 0 };
const char *entropy_file = NULL;
size_t num_bss_configs = 0;
int start_ifaces_in_sync = 0;
#ifdef CONFIG_DPP
struct dpp_global_config dpp_conf;
#endif /* CONFIG_DPP */
os_memset(interfaces, 0, sizeof(struct hapd_interfaces));
interfaces->reload_config = hostapd_reload_config;
interfaces->config_read_cb = hostapd_config_read2;
interfaces->for_each_interface = hostapd_for_each_interface;
interfaces->driver_init = hostapd_driver_init;
interfaces->global_ctrl_sock = -1;
dl_list_init(&interfaces->global_ctrl_dst);
#ifdef CONFIG_DPP
os_memset(&dpp_conf, 0, sizeof(dpp_conf));
dpp_conf.cb_ctx = interfaces;
interfaces->dpp = dpp_global_init(&dpp_conf);
if (!interfaces->dpp) {
return;
}
#endif /* CONFIG_DPP */
interfaces->count = 1;
if (interfaces->count || num_bss_configs) {
interfaces->iface = os_calloc(interfaces->count + num_bss_configs,
sizeof(struct hostapd_iface *));
if (interfaces->iface == NULL) {
wpa_printf(MSG_ERROR, "malloc failed");
return;
}
}
if (hostapd_global_init(interfaces, entropy_file)) {
wpa_printf(MSG_ERROR, "Failed to initialize global context");
return;
}
eloop_register_timeout(HOSTAPD_CLEANUP_INTERVAL, 0,
hostapd_periodic, interfaces, NULL);
iface = net_if_get_wifi_sap();
ret = net_if_get_name(iface, ifname, sizeof(ifname) - 1);
if (ret < 0) {
wpa_printf(MSG_ERROR, "Cannot get interface %d (%p) name",
net_if_get_by_iface(iface), iface);
goto out;
}
for (i = 0; i < interfaces->count; i++) {
interfaces->iface[i] = hostapd_interface_init(interfaces, ifname,
"hostapd.conf", debug);
if (!interfaces->iface[i]) {
wpa_printf(MSG_ERROR, "Failed to initialize interface");
goto out;
}
if (start_ifaces_in_sync) {
interfaces->iface[i]->need_to_start_in_sync = 0;
}
}
/*
* Enable configured interfaces. Depending on channel configuration,
* this may complete full initialization before returning or use a
* callback mechanism to complete setup in case of operations like HT
* co-ex scans, ACS, or DFS are needed to determine channel parameters.
* In such case, the interface will be enabled from eloop context within
* hostapd_global_run().
*/
interfaces->terminate_on_error = 0;
for (i = 0; i < interfaces->count; i++) {
if (hostapd_driver_init(interfaces->iface[i])) {
goto out;
}
interfaces->iface[i]->enable_iface_cb = hostapd_enable_iface_cb;
interfaces->iface[i]->disable_iface_cb = hostapd_disable_iface_cb;
zephyr_hostapd_ctrl_init((void *)interfaces->iface[i]->bss[0]);
}
out:
return;
}

21
modules/hostap/src/hapd_main.h

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
/**
* Copyright 2023-2024 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __HAPD_MAIN_H_
#define __HAPD_MAIN_H_
#include "common.h"
#include "wpa_debug_zephyr.h"
struct hostapd_iface *zephyr_get_hapd_handle_by_ifname(const char *ifname);
void wpa_supplicant_msg_send(void *ctx, int level, enum wpa_msg_type type, const char *txt,
size_t len);
void hostapd_msg_send(void *ctx, int level, enum wpa_msg_type type, const char *buf, size_t len);
const char *zephyr_hostap_msg_ifname_cb(void *ctx);
void zephyr_hostap_ctrl_iface_msg_cb(void *ctx, int level, enum wpa_msg_type type,
const char *txt, size_t len);
void zephyr_hostapd_init(struct hapd_interfaces *interfaces);
#endif /* __HAPD_MAIN_H_ */

1106
modules/hostap/src/supp_api.c

File diff suppressed because it is too large Load Diff

77
modules/hostap/src/supp_api.h

@ -8,6 +8,7 @@ @@ -8,6 +8,7 @@
#ifndef ZEPHYR_SUPP_MGMT_H
#define ZEPHYR_SUPP_MGMT_H
#include <defs.h>
#include <zephyr/net/wifi_mgmt.h>
#ifndef MAX_SSID_LEN
@ -20,6 +21,17 @@ @@ -20,6 +21,17 @@
#define MAC_STR_LEN 18 /* for ':' or '-' separated MAC address string */
#define CHAN_NUM_LEN 6 /* for space-separated channel numbers string */
enum wifi_frequency_bands wpas_band_to_zephyr(enum wpa_radio_work_band band);
enum wifi_wpa3_enterprise_type wpas_key_mgmt_to_zephyr_wpa3_ent(int key_mgmt);
enum wifi_security_type wpas_key_mgmt_to_zephyr(bool is_hapd, void *config,
int key_mgmt, int proto, int pwe);
const struct wifi_mgmt_ops *const get_wifi_mgmt_api(const struct device *dev);
enum wifi_mfp_options get_mfp(enum mfp_options supp_mfp_option);
/**
* @brief Get version
*
@ -194,6 +206,11 @@ int supplicant_mode(const struct device *dev, struct wifi_mode_info *mode); @@ -194,6 +206,11 @@ int supplicant_mode(const struct device *dev, struct wifi_mode_info *mode);
#if defined CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE || \
defined CONFIG_WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE
int is_eap_valid_security(int security);
int process_cipher_config(struct wifi_connect_req_params *params,
struct wifi_eap_cipher_config *cipher_config);
/** Set Wi-Fi enterprise mode CA/client Cert and key
*
* @param dev Pointer to the device structure for the driver instance
@ -289,50 +306,7 @@ int supplicant_get_wifi_conn_params(const struct device *dev, @@ -289,50 +306,7 @@ int supplicant_get_wifi_conn_params(const struct device *dev,
int supplicant_wps_config(const struct device *dev, struct wifi_wps_config_params *params);
#ifdef CONFIG_AP
#ifdef CONFIG_WIFI_NM_HOSTAPD_AP
/**
* @brief Get Wi-Fi AP Status
*
* @param dev Wi-Fi device
* @param params AP status
* @return 0 for OK; -1 for ERROR
*/
int hapd_state(const struct device *dev, int *state);
/**
* @brief Wi-Fi AP configuration parameter.
*
* @param dev Wi-Fi device
* @param params AP parameters
* @return 0 for OK; -1 for ERROR
*/
int supplicant_ap_config_params(const struct device *dev, struct wifi_ap_config_params *params);
#else
static inline int hapd_state(const struct device *dev, int *state)
{
return -EINVAL;
}
#endif
#ifdef CONFIG_WIFI_NM_HOSTAPD_WPS
/** Start AP WPS PBC/PIN
*
* @param dev Pointer to the device structure for the driver instance
* @param params wps operarion parameters
*
* @return 0 if ok, < 0 if error
*/
int supplicant_ap_wps_config(const struct device *dev, struct wifi_wps_config_params *params);
#endif
/**
* @brief Get Wi-Fi SAP status
*
* @param dev Wi-Fi device
* @param status SAP status
* @return 0 for OK; -1 for ERROR
*/
int supplicant_ap_status(const struct device *dev, struct wifi_iface_status *status);
int set_ap_bandwidth(const struct device *dev, enum wifi_frequency_bandwidths bandwidth);
/**
* @brief Set Wi-Fi AP configuration
@ -363,6 +337,10 @@ int supplicant_ap_sta_disconnect(const struct device *dev, @@ -363,6 +337,10 @@ int supplicant_ap_sta_disconnect(const struct device *dev,
#endif /* CONFIG_AP */
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP
#define SUPPLICANT_DPP_CMD_BUF_SIZE 384
int dpp_params_to_cmd(struct wifi_dpp_params *params, char *cmd, size_t max_len);
/**
* @brief Dispatch DPP operations for STA
*
@ -371,16 +349,5 @@ int supplicant_ap_sta_disconnect(const struct device *dev, @@ -371,16 +349,5 @@ int supplicant_ap_sta_disconnect(const struct device *dev,
* @return 0 for OK; -1 for ERROR
*/
int supplicant_dpp_dispatch(const struct device *dev, struct wifi_dpp_params *params);
#ifdef CONFIG_WIFI_NM_HOSTAPD_AP
/**
* @brief Dispatch DPP operations for AP
*
* @param dev Wi-Fi interface name to use
* @param dpp_params DPP action enum and params in string
* @return 0 for OK; -1 for ERROR
*/
int hapd_dpp_dispatch(const struct device *dev, struct wifi_dpp_params *params);
#endif /* CONFIG_WIFI_NM_HOSTAPD_AP */
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP */
#endif /* ZEPHYR_SUPP_MGMT_H */

74
modules/hostap/src/supp_events.c

@ -252,11 +252,7 @@ int supplicant_send_wifi_mgmt_disc_event(void *ctx, int reason_code) @@ -252,11 +252,7 @@ int supplicant_send_wifi_mgmt_disc_event(void *ctx, int reason_code)
}
#ifdef CONFIG_AP
#ifdef CONFIG_WIFI_NM_HOSTAPD_AP
static enum wifi_link_mode get_sta_link_mode(struct hostapd_iface *iface, struct sta_info *sta)
#else
static enum wifi_link_mode get_sta_link_mode(struct wpa_supplicant *wpa_s, struct sta_info *sta)
#endif
{
if (sta->flags & WLAN_STA_HE) {
return WIFI_6;
@ -264,37 +260,17 @@ static enum wifi_link_mode get_sta_link_mode(struct wpa_supplicant *wpa_s, struc @@ -264,37 +260,17 @@ static enum wifi_link_mode get_sta_link_mode(struct wpa_supplicant *wpa_s, struc
return WIFI_5;
} else if (sta->flags & WLAN_STA_HT) {
return WIFI_4;
#ifndef CONFIG_WIFI_NM_HOSTAPD_AP
} else if (sta->flags & WLAN_STA_NONERP) {
return WIFI_1;
} else if (wpa_s->assoc_freq > 4000) {
return WIFI_2;
} else if (wpa_s->assoc_freq > 2000) {
return WIFI_3;
#else
} else if ((sta->flags & WLAN_STA_NONERP) ||
(iface->current_mode->mode == HOSTAPD_MODE_IEEE80211B)) {
return WIFI_1;
} else if (iface->freq > 4000) {
return WIFI_2;
} else if (iface->freq > 2000) {
return WIFI_3;
#endif
} else {
return WIFI_LINK_MODE_UNKNOWN;
}
}
#ifdef CONFIG_WIFI_NM_HOSTAPD_AP
static bool is_twt_capable(struct hostapd_iface *iface, struct sta_info *sta)
{
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_11AX
return hostapd_get_he_twt_responder(iface->bss[0], IEEE80211_MODE_AP);
#else
return false;
#endif
}
#else
static bool is_twt_capable(struct wpa_supplicant *wpa_s, struct sta_info *sta)
{
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_11AX
@ -303,19 +279,13 @@ static bool is_twt_capable(struct wpa_supplicant *wpa_s, struct sta_info *sta) @@ -303,19 +279,13 @@ static bool is_twt_capable(struct wpa_supplicant *wpa_s, struct sta_info *sta)
return false;
#endif
}
#endif
int supplicant_send_wifi_mgmt_ap_status(void *ctx,
enum net_event_wifi_cmd event,
enum wifi_ap_status ap_status)
{
#ifdef CONFIG_WIFI_NM_HOSTAPD_AP
struct hostapd_iface *iface = ctx;
char *ifname = iface->conf->bss[0]->iface;
#else
struct wpa_supplicant *wpa_s = ctx;
char *ifname = wpa_s->ifname;
#endif
int status = ap_status;
return supplicant_send_wifi_mgmt_event(ifname,
@ -329,13 +299,8 @@ int supplicant_send_wifi_mgmt_ap_sta_event(void *ctx, @@ -329,13 +299,8 @@ int supplicant_send_wifi_mgmt_ap_sta_event(void *ctx,
void *data)
{
struct sta_info *sta = data;
#ifdef CONFIG_WIFI_NM_HOSTAPD_AP
struct hostapd_iface *ap_ctx = ctx;
char *ifname = ap_ctx->bss[0]->conf->iface;
#else
struct wpa_supplicant *ap_ctx = ctx;
char *ifname = ap_ctx->ifname;
#endif
struct wifi_ap_sta_info sta_info = { 0 };
if (!ap_ctx || !sta) {
@ -463,42 +428,3 @@ int supplicant_generate_state_event(const char *ifname, @@ -463,42 +428,3 @@ int supplicant_generate_state_event(const char *ifname,
return 0;
}
#if defined(CONFIG_WIFI_NM_HOSTAPD_AP) && defined(CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP)
void hostapd_handle_dpp_event(void *ctx, char *buf, size_t len)
{
struct hostapd_data *hapd = (struct hostapd_data *)ctx;
if (hapd == NULL) {
return;
}
struct hostapd_bss_config *conf = hapd->conf;
if (conf == NULL || !(conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP)) {
return;
}
/* check hostapd */
if (!strncmp(buf, DPP_EVENT_CONNECTOR, sizeof(DPP_EVENT_CONNECTOR) - 1)) {
if (conf->dpp_connector) {
os_free(conf->dpp_connector);
}
conf->dpp_connector = os_strdup(buf + sizeof(DPP_EVENT_CONNECTOR) - 1);
} else if (!strncmp(buf, DPP_EVENT_C_SIGN_KEY, sizeof(DPP_EVENT_C_SIGN_KEY) - 1)) {
if (conf->dpp_csign) {
wpabuf_free(conf->dpp_csign);
}
conf->dpp_csign = wpabuf_parse_bin(buf + sizeof(DPP_EVENT_C_SIGN_KEY) - 1);
} else if (!strncmp(buf, DPP_EVENT_NET_ACCESS_KEY, sizeof(DPP_EVENT_NET_ACCESS_KEY) - 1)) {
if (conf->dpp_netaccesskey) {
wpabuf_free(conf->dpp_netaccesskey);
}
conf->dpp_netaccesskey =
wpabuf_parse_bin(buf + sizeof(DPP_EVENT_NET_ACCESS_KEY) - 1);
}
}
#endif /* CONFIG_WIFI_NM_HOSTAPD_AP && CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP */

3
modules/hostap/src/supp_events.h

@ -63,9 +63,6 @@ int supplicant_send_wifi_mgmt_ap_sta_event(void *ctx, @@ -63,9 +63,6 @@ int supplicant_send_wifi_mgmt_ap_sta_event(void *ctx,
enum net_event_wifi_cmd event,
void *data);
#endif /* CONFIG_AP */
#if defined(CONFIG_WIFI_NM_HOSTAPD_AP) && defined(CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP)
void hostapd_handle_dpp_event(void *ctx, char *buf, size_t len);
#endif
#define REASON_CODE_LEN 18
#define NM_WIFI_EVENT_STR_LEN 64

577
modules/hostap/src/supp_main.c

@ -46,10 +46,7 @@ static K_THREAD_STACK_DEFINE(iface_wq_stack, CONFIG_WIFI_NM_WPA_SUPPLICANT_WQ_ST @@ -46,10 +46,7 @@ static K_THREAD_STACK_DEFINE(iface_wq_stack, CONFIG_WIFI_NM_WPA_SUPPLICANT_WQ_ST
#include "wpa_cli_zephyr.h"
#ifdef CONFIG_WIFI_NM_HOSTAPD_AP
#include "hostapd.h"
#include "hostapd_cli_zephyr.h"
#include "eap_register.h"
#include "ap_drv_ops.h"
#include "l2_packet/l2_packet.h"
#include "hapd_main.h"
#endif
static const struct wifi_mgmt_ops mgmt_ops = {
@ -100,29 +97,6 @@ static const struct wifi_mgmt_ops mgmt_ops = { @@ -100,29 +97,6 @@ static const struct wifi_mgmt_ops mgmt_ops = {
DEFINE_WIFI_NM_INSTANCE(wifi_supplicant, &mgmt_ops);
#ifdef CONFIG_WIFI_NM_HOSTAPD_AP
static const struct wifi_mgmt_ops mgmt_ap_ops = {
.ap_enable = supplicant_ap_enable,
.ap_disable = supplicant_ap_disable,
.ap_sta_disconnect = supplicant_ap_sta_disconnect,
.iface_status = supplicant_ap_status,
#ifdef CONFIG_WIFI_NM_HOSTAPD_WPS
.wps_config = supplicant_ap_wps_config,
#endif
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP
.dpp_dispatch = hapd_dpp_dispatch,
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP */
.ap_config_params = supplicant_ap_config_params,
.set_rts_threshold = supplicant_set_rts_threshold,
#ifdef CONFIG_WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE
.enterprise_creds = supplicant_add_enterprise_creds,
#endif
.set_btwt = supplicant_set_btwt,
};
DEFINE_WIFI_NM_INSTANCE(hostapd, &mgmt_ap_ops);
#endif
#define WRITE_TIMEOUT 100 /* ms */
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_INF_MON
#define INTERFACE_EVENT_MASK (NET_EVENT_IF_ADMIN_UP | NET_EVENT_IF_ADMIN_DOWN)
@ -141,38 +115,6 @@ struct supplicant_context { @@ -141,38 +115,6 @@ struct supplicant_context {
int (*iface_handler)(struct supplicant_context *ctx, struct net_if *iface);
};
#ifdef CONFIG_WIFI_NM_HOSTAPD_AP
struct hapd_global {
void **drv_priv;
size_t drv_count;
};
static struct hapd_global hglobal;
#ifndef HOSTAPD_CLEANUP_INTERVAL
#define HOSTAPD_CLEANUP_INTERVAL 10
#endif /* HOSTAPD_CLEANUP_INTERVAL */
static void zephyr_hostap_ctrl_iface_msg_cb(void *ctx, int level, enum wpa_msg_type type,
const char *txt, size_t len);
static int hostapd_periodic_call(struct hostapd_iface *iface, void *ctx)
{
hostapd_periodic_iface(iface);
return 0;
}
/* Periodic cleanup tasks */
static void hostapd_periodic(void *eloop_ctx, void *timeout_ctx)
{
struct hapd_interfaces *interfaces = eloop_ctx;
eloop_register_timeout(HOSTAPD_CLEANUP_INTERVAL, 0,
hostapd_periodic, interfaces, NULL);
hostapd_for_each_interface(interfaces, hostapd_periodic_call, NULL);
}
#endif
static struct supplicant_context *get_default_context(void)
{
static struct supplicant_context ctx;
@ -185,6 +127,13 @@ struct wpa_global *zephyr_get_default_supplicant_context(void) @@ -185,6 +127,13 @@ struct wpa_global *zephyr_get_default_supplicant_context(void)
return get_default_context()->supplicant;
}
#ifdef CONFIG_WIFI_NM_HOSTAPD_AP
struct hapd_interfaces *zephyr_get_default_hapd_context(void)
{
return &get_default_context()->hostapd;
}
#endif
struct k_work_q *get_workq(void)
{
return &get_default_context()->iface_wq;
@ -265,22 +214,6 @@ struct wpa_supplicant *zephyr_get_handle_by_ifname(const char *ifname) @@ -265,22 +214,6 @@ struct wpa_supplicant *zephyr_get_handle_by_ifname(const char *ifname)
return wpa_s;
}
#ifdef CONFIG_WIFI_NM_HOSTAPD_AP
struct hostapd_iface *zephyr_get_hapd_handle_by_ifname(const char *ifname)
{
struct hostapd_data *hapd = NULL;
struct supplicant_context *ctx = get_default_context();
hapd = hostapd_get_iface(&ctx->hostapd, ifname);
if (!hapd) {
wpa_printf(MSG_ERROR, "%s: Unable to get hapd handle for %s\n", __func__, ifname);
return NULL;
}
return hapd->iface;
}
#endif
static int get_iface_count(struct supplicant_context *ctx)
{
/* FIXME, should not access ifaces as it is supplicant internal data */
@ -639,498 +572,6 @@ static int register_supplicant_event_socket(struct supplicant_context *ctx) @@ -639,498 +572,6 @@ static int register_supplicant_event_socket(struct supplicant_context *ctx)
return 0;
}
#ifdef CONFIG_WIFI_NM_HOSTAPD_AP
struct hostapd_iface *hostapd_get_interface(const char *ifname)
{
struct supplicant_context *ctx;
ctx = get_default_context();
(void)ifname;
return ctx->hostapd.iface[0];
}
static void hostapd_event_eapol_rx_cb(void *ctx, const u8 *src_addr,
const u8 *buf, size_t len)
{
hostapd_event_eapol_rx(ctx, src_addr, buf, len, FRAME_ENCRYPTION_UNKNOWN, -1);
}
static int hostapd_enable_iface_cb(struct hostapd_iface *hapd_iface)
{
struct hostapd_data *bss;
wpa_printf(MSG_DEBUG, "Enable interface %s", hapd_iface->conf->bss[0]->iface);
bss = hapd_iface->bss[0];
bss->conf->start_disabled = 0;
if (hostapd_config_check(hapd_iface->conf, 1) < 0) {
wpa_printf(MSG_INFO, "Invalid configuration - cannot enable");
return -1;
}
l2_packet_deinit(bss->l2);
bss->l2 = l2_packet_init(bss->conf->iface, bss->conf->bssid, ETH_P_EAPOL,
&hostapd_event_eapol_rx_cb, bss, 0);
if (bss->l2 == NULL) {
wpa_printf(MSG_ERROR, "Failed to initialize l2 for hostapd interface");
return -1;
}
if (hostapd_setup_interface(hapd_iface)) {
wpa_printf(MSG_ERROR, "Failed to initialize hostapd interface");
return -1;
}
return 0;
}
static int hostapd_disable_iface_cb(struct hostapd_iface *hapd_iface)
{
size_t j;
struct hostapd_data *hapd = NULL;
wpa_msg(hapd_iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
hapd_iface->driver_ap_teardown = !!(hapd_iface->drv_flags
& WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
#ifdef NEED_AP_MLME
for (j = 0; j < hapd_iface->num_bss; j++) {
hostapd_cleanup_cs_params(hapd_iface->bss[j]);
}
#endif /* NEED_AP_MLME */
/* Same as hostapd_interface_deinit() without deinitializing control
* interface
*/
for (j = 0; j < hapd_iface->num_bss; j++) {
hapd = hapd_iface->bss[j];
hostapd_bss_deinit_no_free(hapd);
hostapd_free_hapd_data(hapd);
}
hostapd_drv_stop_ap(hapd);
hostapd_cleanup_iface_partial(hapd_iface);
wpa_printf(MSG_DEBUG, "Interface %s disabled", hapd_iface->bss[0]->conf->iface);
hostapd_set_state(hapd_iface, HAPD_IFACE_DISABLED);
supplicant_send_wifi_mgmt_ap_status(hapd_iface,
NET_EVENT_WIFI_CMD_AP_DISABLE_RESULT,
WIFI_STATUS_AP_SUCCESS);
hostapd_config_free(hapd_iface->conf);
hapd_iface->conf = hapd_iface->interfaces->config_read_cb(hapd_iface->config_fname);
for (j = 0; j < hapd_iface->num_bss; j++) {
hapd = hapd_iface->bss[j];
hapd->iconf = hapd_iface->conf;
hapd->conf = hapd_iface->conf->bss[j];
hapd->driver = hapd_iface->conf->driver;
}
return 0;
}
static int hostapd_global_init(struct hapd_interfaces *interfaces, const char *entropy_file)
{
int i;
os_memset(&hglobal, 0, sizeof(struct hapd_global));
if (eap_server_register_methods()) {
wpa_printf(MSG_ERROR, "Failed to register EAP methods");
return -1;
}
interfaces->eloop_initialized = 1;
for (i = 0; wpa_drivers[i]; i++) {
hglobal.drv_count++;
}
if (hglobal.drv_count == 0) {
wpa_printf(MSG_ERROR, "No drivers enabled");
return -1;
}
hglobal.drv_priv = os_calloc(hglobal.drv_count, sizeof(void *));
if (hglobal.drv_priv == NULL) {
return -1;
}
return 0;
}
static int hostapd_driver_init(struct hostapd_iface *iface)
{
struct wpa_init_params params;
size_t i;
struct hostapd_data *hapd = iface->bss[0];
struct hostapd_bss_config *conf = hapd->conf;
u8 *b = conf->bssid;
struct wpa_driver_capa capa;
if (hapd->driver == NULL || hapd->driver->hapd_init == NULL) {
wpa_printf(MSG_ERROR, "No hostapd driver wrapper available");
return -1;
}
/* Initialize the driver interface */
if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5])) {
b = NULL;
}
os_memset(&params, 0, sizeof(params));
for (i = 0; wpa_drivers[i]; i++) {
if (wpa_drivers[i] != hapd->driver)
continue;
if (hglobal.drv_priv[i] == NULL && wpa_drivers[i]->global_init) {
hglobal.drv_priv[i] = wpa_drivers[i]->global_init(iface->interfaces);
if (hglobal.drv_priv[i] == NULL) {
wpa_printf(MSG_ERROR, "Failed to initialize driver '%s'",
wpa_drivers[i]->name);
return -1;
}
hglobal.drv_count++;
}
params.global_priv = hglobal.drv_priv[i];
break;
}
params.bssid = b;
params.ifname = hapd->conf->iface;
params.driver_params = hapd->iconf->driver_params;
params.use_pae_group_addr = hapd->conf->use_pae_group_addr;
params.num_bridge = hapd->iface->num_bss;
params.bridge = os_calloc(hapd->iface->num_bss, sizeof(char *));
if (params.bridge == NULL) {
return -1;
}
for (i = 0; i < hapd->iface->num_bss; i++) {
struct hostapd_data *bss = hapd->iface->bss[i];
if (bss->conf->bridge[0]) {
params.bridge[i] = bss->conf->bridge;
}
}
params.own_addr = hapd->own_addr;
hapd->drv_priv = hapd->driver->hapd_init(hapd, &params);
os_free(params.bridge);
if (hapd->drv_priv == NULL) {
wpa_printf(MSG_ERROR, "%s driver initialization failed.",
hapd->driver->name);
hapd->driver = NULL;
return -1;
}
if (hapd->driver->get_capa && hapd->driver->get_capa(hapd->drv_priv, &capa) == 0) {
struct wowlan_triggers *triggs;
iface->drv_flags = capa.flags;
iface->drv_flags2 = capa.flags2;
iface->probe_resp_offloads = capa.probe_resp_offloads;
/*
* Use default extended capa values from per-radio information
*/
iface->extended_capa = capa.extended_capa;
iface->extended_capa_mask = capa.extended_capa_mask;
iface->extended_capa_len = capa.extended_capa_len;
iface->drv_max_acl_mac_addrs = capa.max_acl_mac_addrs;
/*
* Override extended capa with per-interface type (AP), if
* available from the driver.
*/
hostapd_get_ext_capa(iface);
triggs = wpa_get_wowlan_triggers(conf->wowlan_triggers, &capa);
if (triggs && hapd->driver->set_wowlan) {
if (hapd->driver->set_wowlan(hapd->drv_priv, triggs)) {
wpa_printf(MSG_ERROR, "set_wowlan failed");
}
}
os_free(triggs);
}
return 0;
}
struct hostapd_config *hostapd_config_read2(const char *fname)
{
struct hostapd_config *conf;
const struct device *dev;
char ifname[IFNAMSIZ + 1] = {0};
int errors = 0;
size_t i;
int aCWmin = 4, aCWmax = 10;
/* background traffic */
struct hostapd_wmm_ac_params ac_bk = {aCWmin, aCWmax, 9, 0, 0};
/* best effort traffic */
struct hostapd_wmm_ac_params ac_be = {aCWmin, aCWmax - 4, 5, 0, 0};
/* video traffic */
struct hostapd_wmm_ac_params ac_vi = {aCWmin - 1, aCWmin, 3,
3008 / 32, 0};
/* voice traffic */
struct hostapd_wmm_ac_params ac_vo = {aCWmin - 2, aCWmin - 1, 3,
1504 / 32, 0};
dev = net_if_get_device(net_if_get_wifi_sap());
strncpy(ifname, dev->name, IFNAMSIZ);
ifname[IFNAMSIZ] = '\0';
conf = hostapd_config_defaults();
if (conf == NULL) {
return NULL;
}
conf->wmm_ac_params[0] = ac_be;
conf->wmm_ac_params[1] = ac_bk;
conf->wmm_ac_params[2] = ac_vi;
conf->wmm_ac_params[3] = ac_vo;
/* set default driver based on configuration */
conf->driver = wpa_drivers[0];
if (conf->driver == NULL) {
wpa_printf(MSG_ERROR, "No driver wrappers registered!");
hostapd_config_free(conf);
return NULL;
}
conf->last_bss = conf->bss[0];
struct hostapd_bss_config *bss;
bss = conf->last_bss;
bss->start_disabled = 1;
bss->max_num_sta = CONFIG_WIFI_MGMT_AP_MAX_NUM_STA;
bss->dtim_period = 1;
os_strlcpy(conf->bss[0]->iface, ifname, sizeof(conf->bss[0]->iface));
bss->logger_stdout_level = HOSTAPD_LEVEL_INFO;
bss->logger_stdout = 0xffff;
bss->nas_identifier = os_strdup("ap.example.com");
os_memcpy(conf->country, "US ", 3);
conf->hw_mode = HOSTAPD_MODE_IEEE80211G;
bss->wps_state = WPS_STATE_CONFIGURED;
bss->eap_server = 1;
#ifdef CONFIG_WPS
bss->ap_setup_locked = 1;
#endif
conf->channel = 1;
conf->acs = conf->channel == 0;
#ifdef CONFIG_ACS
conf->acs_num_scans = 1;
#endif
conf->ieee80211n = 1;
conf->ieee80211h = 0;
conf->ieee80211d = 1;
conf->acs_exclude_dfs = 1;
conf->ht_capab |= HT_CAP_INFO_SHORT_GI20MHZ;
bss->auth_algs = 1;
bss->okc = 1;
conf->no_pri_sec_switch = 1;
conf->ht_op_mode_fixed = 1;
conf->ieee80211ac = 1;
conf->vht_oper_chwidth = CHANWIDTH_USE_HT;
conf->vht_capab |= VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX;
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_11AX
conf->ieee80211ax = 1;
conf->he_oper_chwidth = CHANWIDTH_USE_HT;
conf->he_phy_capab.he_su_beamformer = 0;
conf->he_phy_capab.he_su_beamformee = 1;
conf->he_phy_capab.he_mu_beamformer = 0;
conf->he_op.he_bss_color = 1;
conf->he_op.he_default_pe_duration = 0;
/* Set default basic MCS/NSS set to single stream MCS 0-7 */
conf->he_op.he_basic_mcs_nss_set = 0xfffc;
#endif
for (i = 0; i < conf->num_bss; i++) {
hostapd_set_security_params(conf->bss[i], 1);
}
if (hostapd_config_check(conf, 1)) {
errors++;
}
#ifndef WPA_IGNORE_CONFIG_ERRORS
if (errors) {
wpa_printf(MSG_ERROR, "%d errors found in configuration file '%s'",
errors, fname);
hostapd_config_free(conf);
conf = NULL;
}
#endif /* WPA_IGNORE_CONFIG_ERRORS */
return conf;
}
static struct hostapd_iface *hostapd_interface_init(struct hapd_interfaces *interfaces,
const char *if_name,
const char *config_fname,
int debug)
{
struct hostapd_iface *iface;
int k;
wpa_printf(MSG_DEBUG, "Configuration file: %s", config_fname);
iface = hostapd_init(interfaces, config_fname);
if (!iface) {
return NULL;
}
if (if_name) {
os_strlcpy(iface->conf->bss[0]->iface, if_name,
sizeof(iface->conf->bss[0]->iface));
}
iface->interfaces = interfaces;
for (k = 0; k < debug; k++) {
if (iface->bss[0]->conf->logger_stdout_level > 0) {
iface->bss[0]->conf->logger_stdout_level--;
}
}
if (iface->conf->bss[0]->iface[0] == '\0' &&
!hostapd_drv_none(iface->bss[0])) {
wpa_printf(MSG_ERROR,
"Interface name not specified in %s, nor by '-i' parameter",
config_fname);
hostapd_interface_deinit_free(iface);
return NULL;
}
iface->bss[0]->is_hostapd = 1;
return iface;
}
static void zephyr_hostapd_init(struct supplicant_context *ctx)
{
struct hapd_interfaces *interfaces = &ctx->hostapd;
size_t i;
int ret, debug = 0;
struct net_if *iface;
char ifname[IFNAMSIZ + 1] = { 0 };
const char *entropy_file = NULL;
size_t num_bss_configs = 0;
int start_ifaces_in_sync = 0;
#ifdef CONFIG_DPP
struct dpp_global_config dpp_conf;
#endif /* CONFIG_DPP */
os_memset(interfaces, 0, sizeof(struct hapd_interfaces));
interfaces->reload_config = hostapd_reload_config;
interfaces->config_read_cb = hostapd_config_read2;
interfaces->for_each_interface = hostapd_for_each_interface;
interfaces->driver_init = hostapd_driver_init;
interfaces->global_ctrl_sock = -1;
dl_list_init(&interfaces->global_ctrl_dst);
#ifdef CONFIG_DPP
os_memset(&dpp_conf, 0, sizeof(dpp_conf));
dpp_conf.cb_ctx = interfaces;
interfaces->dpp = dpp_global_init(&dpp_conf);
if (!interfaces->dpp) {
return;
}
#endif /* CONFIG_DPP */
interfaces->count = 1;
if (interfaces->count || num_bss_configs) {
interfaces->iface = os_calloc(interfaces->count + num_bss_configs,
sizeof(struct hostapd_iface *));
if (interfaces->iface == NULL) {
wpa_printf(MSG_ERROR, "malloc failed");
return;
}
}
if (hostapd_global_init(interfaces, entropy_file)) {
wpa_printf(MSG_ERROR, "Failed to initialize global context");
return;
}
eloop_register_timeout(HOSTAPD_CLEANUP_INTERVAL, 0,
hostapd_periodic, interfaces, NULL);
iface = net_if_get_wifi_sap();
ret = net_if_get_name(iface, ifname, sizeof(ifname) - 1);
if (ret < 0) {
LOG_ERR("Cannot get interface %d (%p) name", net_if_get_by_iface(iface), iface);
goto out;
}
for (i = 0; i < interfaces->count; i++) {
interfaces->iface[i] = hostapd_interface_init(interfaces, ifname,
"hostapd.conf", debug);
if (!interfaces->iface[i]) {
wpa_printf(MSG_ERROR, "Failed to initialize interface");
goto out;
}
if (start_ifaces_in_sync) {
interfaces->iface[i]->need_to_start_in_sync = 0;
}
}
/*
* Enable configured interfaces. Depending on channel configuration,
* this may complete full initialization before returning or use a
* callback mechanism to complete setup in case of operations like HT
* co-ex scans, ACS, or DFS are needed to determine channel parameters.
* In such case, the interface will be enabled from eloop context within
* hostapd_global_run().
*/
interfaces->terminate_on_error = 0;
for (i = 0; i < interfaces->count; i++) {
if (hostapd_driver_init(interfaces->iface[i])) {
goto out;
}
interfaces->iface[i]->enable_iface_cb = hostapd_enable_iface_cb;
interfaces->iface[i]->disable_iface_cb = hostapd_disable_iface_cb;
zephyr_hostapd_ctrl_init((void *)interfaces->iface[i]->bss[0]);
}
out:
return;
}
static const char *zephyr_hostap_msg_ifname_cb(void *ctx)
{
if (ctx == NULL) {
return NULL;
}
if ((*((int *)ctx)) == 0) {
struct wpa_supplicant *wpa_s = ctx;
return wpa_s->ifname;
}
struct hostapd_data *hapd = ctx;
if (hapd && hapd->conf) {
return hapd->conf->iface;
}
return NULL;
}
static void zephyr_hostap_ctrl_iface_msg_cb(void *ctx, int level, enum wpa_msg_type type,
const char *txt, size_t len)
{
if (ctx == NULL) {
return;
}
if ((*((int *)ctx)) == 0) {
wpa_supplicant_msg_send(ctx, level, type, txt, len);
} else {
hostapd_msg_send(ctx, level, type, txt, len);
}
}
#endif
static void handler(void)
{
struct supplicant_context *ctx;
@ -1186,7 +627,7 @@ static void handler(void) @@ -1186,7 +627,7 @@ static void handler(void)
submit_iface_work(ctx, NULL, setup_interface_monitoring);
#ifdef CONFIG_WIFI_NM_HOSTAPD_AP
zephyr_hostapd_init(ctx);
zephyr_hostapd_init(&ctx->hostapd);
wpa_msg_register_ifname_cb(zephyr_hostap_msg_ifname_cb);
#endif

10
modules/hostap/src/supp_main.h

@ -55,15 +55,11 @@ struct wpa_global *zephyr_get_default_supplicant_context(void); @@ -55,15 +55,11 @@ struct wpa_global *zephyr_get_default_supplicant_context(void);
struct wpa_supplicant *zephyr_get_handle_by_ifname(const char *ifname);
#ifdef CONFIG_WIFI_NM_HOSTAPD_AP
#include "common.h"
#include "wpa_debug_zephyr.h"
struct hostapd_iface *zephyr_get_hapd_handle_by_ifname(const char *ifname);
void wpa_supplicant_msg_send(void *ctx, int level, enum wpa_msg_type type, const char *txt,
size_t len);
void hostapd_msg_send(void *ctx, int level, enum wpa_msg_type type, const char *buf, size_t len);
struct hapd_interfaces *zephyr_get_default_hapd_context(void);
#endif
struct wpa_supplicant *zephyr_get_handle_by_ifname(const char *ifname);
struct wpa_supplicant_event_msg {
#ifdef CONFIG_WIFI_NM_HOSTAPD_AP
int hostapd;

4
west.yml

@ -203,7 +203,7 @@ manifest: @@ -203,7 +203,7 @@ manifest:
groups:
- hal
- name: hal_nxp
revision: 6af2fd7a9b21a567866585384d28963daeb7d350
revision: 4c94d433ba1a7638a0f3a319ab0adb43238f9be3
path: modules/hal/nxp
groups:
- hal
@ -274,7 +274,7 @@ manifest: @@ -274,7 +274,7 @@ manifest:
- hal
- name: hostap
path: modules/lib/hostap
revision: e83c94958cab8e2327c85e484f50cbf570f5ac3f
revision: f72b2d4402cb6e8d29d93e0866bc3e8ec4d7ddbc
- name: liblc3
revision: 48bbd3eacd36e99a57317a0a4867002e0b09e183
path: modules/lib/liblc3

Loading…
Cancel
Save