int err = 1;
struct hostapd_hw_modes *cmode = iface->current_mode;
u8 current_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
+ int ieee80211_mode = IEEE80211_MODE_AP;
wpa_printf(MSG_DEBUG, "%s called (CAC active: %s, CSA active: %s)",
__func__, iface->cac_started ? "yes" : "no",
os_memset(&csa_settings, 0, sizeof(csa_settings));
csa_settings.cs_count = 5;
csa_settings.block_tx = 1;
+#ifdef CONFIG_MESH
+ if (iface->mconf)
+ ieee80211_mode = IEEE80211_MODE_MESH;
+#endif /* CONFIG_MESH */
err = hostapd_set_freq_params(&csa_settings.freq_params,
iface->conf->hw_mode,
channel->freq,
oper_centr_freq_seg0_idx,
oper_centr_freq_seg1_idx,
cmode->vht_capab,
- &cmode->he_capab[IEEE80211_MODE_AP]);
+ &cmode->he_capab[ieee80211_mode]);
if (err) {
wpa_printf(MSG_ERROR, "DFS failed to calculate CSA freq params");
#endif /* CONFIG_WEP */
-static void hostapd_free_hapd_data(struct hostapd_data *hapd)
+void hostapd_free_hapd_data(struct hostapd_data *hapd)
{
os_free(hapd->probereq_cb);
hapd->probereq_cb = NULL;
}
-static void hostapd_cleanup_iface_partial(struct hostapd_iface *iface)
+void hostapd_cleanup_iface_partial(struct hostapd_iface *iface)
{
wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
#ifdef NEED_AP_MLME
}
-static void hostapd_bss_deinit_no_free(struct hostapd_data *hapd)
+void hostapd_bss_deinit_no_free(struct hostapd_data *hapd)
{
hostapd_free_stas(hapd);
hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING);
{
size_t j;
+ if (!hapd_iface)
+ return -1;
+
+ if (hapd_iface->enable_iface_cb)
+ return hapd_iface->enable_iface_cb(hapd_iface);
+
if (hapd_iface->bss[0]->drv_priv != NULL) {
wpa_printf(MSG_ERROR, "Interface %s already enabled",
hapd_iface->conf->bss[0]->iface);
if (hapd_iface == NULL)
return -1;
+ if (hapd_iface->disable_iface_cb)
+ return hapd_iface->disable_iface_cb(hapd_iface);
+
if (hapd_iface->bss[0]->drv_priv == NULL) {
wpa_printf(MSG_INFO, "Interface %s already disabled",
hapd_iface->conf->bss[0]->iface);
/* Previous WMM element information */
struct hostapd_wmm_ac_params prev_wmm[WMM_AC_NUM];
+
+ int (*enable_iface_cb)(struct hostapd_iface *iface);
+ int (*disable_iface_cb)(struct hostapd_iface *iface);
};
/* hostapd.c */
int hostapd_enable_iface(struct hostapd_iface *hapd_iface);
int hostapd_reload_iface(struct hostapd_iface *hapd_iface);
int hostapd_disable_iface(struct hostapd_iface *hapd_iface);
+void hostapd_bss_deinit_no_free(struct hostapd_data *hapd);
+void hostapd_free_hapd_data(struct hostapd_data *hapd);
+void hostapd_cleanup_iface_partial(struct hostapd_iface *iface);
int hostapd_add_iface(struct hapd_interfaces *ifaces, char *buf);
int hostapd_remove_iface(struct hapd_interfaces *ifaces, char *buf);
void hostapd_channel_list_updated(struct hostapd_iface *iface, int initiator);
#include "mesh.h"
-static void wpa_supplicant_mesh_deinit(struct wpa_supplicant *wpa_s)
+static void wpa_supplicant_mesh_deinit(struct wpa_supplicant *wpa_s,
+ bool also_clear_hostapd)
{
- wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh, true);
- wpa_s->ifmsh = NULL;
- wpa_s->current_ssid = NULL;
+ wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh,
+ also_clear_hostapd);
+
+ if (also_clear_hostapd) {
+ wpa_s->ifmsh = NULL;
+ wpa_s->current_ssid = NULL;
+ os_free(wpa_s->mesh_params);
+ wpa_s->mesh_params = NULL;
+ }
+
os_free(wpa_s->mesh_rsn);
wpa_s->mesh_rsn = NULL;
- os_free(wpa_s->mesh_params);
- wpa_s->mesh_params = NULL;
+
wpa_supplicant_leave_mesh(wpa_s, false);
}
he_capab)) {
wpa_printf(MSG_ERROR,
"Error updating mesh frequency params");
- wpa_supplicant_mesh_deinit(wpa_s);
+ wpa_supplicant_mesh_deinit(wpa_s, true);
return -1;
}
}
wpas_mesh_init_rsn(wpa_s)) {
wpa_printf(MSG_ERROR,
"mesh: RSN initialization failed - deinit mesh");
- wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh, false);
+ wpa_supplicant_mesh_deinit(wpa_s, false);
return -1;
}
}
+static int wpa_supplicant_mesh_enable_iface_cb(struct hostapd_iface *ifmsh)
+{
+ struct wpa_supplicant *wpa_s = ifmsh->owner;
+ struct hostapd_data *bss;
+
+ ifmsh->mconf = mesh_config_create(wpa_s, wpa_s->current_ssid);
+
+ bss = ifmsh->bss[0];
+ bss->msg_ctx = wpa_s;
+ os_memcpy(bss->own_addr, wpa_s->own_addr, ETH_ALEN);
+ bss->driver = wpa_s->driver;
+ bss->drv_priv = wpa_s->drv_priv;
+ bss->iface = ifmsh;
+ bss->mesh_sta_free_cb = mesh_mpm_free_sta;
+ bss->setup_complete_cb = wpas_mesh_complete_cb;
+ bss->setup_complete_cb_ctx = wpa_s;
+
+ bss->conf->start_disabled = 1;
+ bss->conf->mesh = MESH_ENABLED;
+ bss->conf->ap_max_inactivity = wpa_s->conf->mesh_max_inactivity;
+
+ if (wpa_drv_init_mesh(wpa_s)) {
+ wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh in driver");
+ return -1;
+ }
+
+ if (hostapd_setup_interface(ifmsh)) {
+ wpa_printf(MSG_ERROR,
+ "Failed to initialize hostapd interface for mesh");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int wpa_supplicant_mesh_disable_iface_cb(struct hostapd_iface *ifmsh)
+{
+ struct wpa_supplicant *wpa_s = ifmsh->owner;
+ size_t j;
+
+ wpa_supplicant_mesh_deinit(wpa_s, false);
+
+#ifdef NEED_AP_MLME
+ for (j = 0; j < ifmsh->num_bss; j++)
+ hostapd_cleanup_cs_params(ifmsh->bss[j]);
+#endif /* NEED_AP_MLME */
+
+ /* Same as hostapd_interface_deinit() without deinitializing control
+ * interface */
+ for (j = 0; j < ifmsh->num_bss; j++) {
+ struct hostapd_data *hapd = ifmsh->bss[j];
+
+ hostapd_bss_deinit_no_free(hapd);
+ hostapd_free_hapd_data(hapd);
+ }
+
+ hostapd_cleanup_iface_partial(ifmsh);
+
+ return 0;
+}
+
+
static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid,
struct hostapd_freq_params *freq)
ifmsh->drv_flags = wpa_s->drv_flags;
ifmsh->drv_flags2 = wpa_s->drv_flags2;
ifmsh->num_bss = 1;
+ ifmsh->enable_iface_cb = wpa_supplicant_mesh_enable_iface_cb;
+ ifmsh->disable_iface_cb = wpa_supplicant_mesh_disable_iface_cb;
ifmsh->bss = os_calloc(wpa_s->ifmsh->num_bss,
sizeof(struct hostapd_data *));
if (!ifmsh->bss)
return 0;
out_free:
- wpa_supplicant_mesh_deinit(wpa_s);
+ wpa_supplicant_mesh_deinit(wpa_s, true);
return -ENOMEM;
}
goto out;
}
- wpa_supplicant_mesh_deinit(wpa_s);
+ wpa_supplicant_mesh_deinit(wpa_s, true);
wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
wpa_s->group_cipher = WPA_CIPHER_NONE;
/* Need to send peering close messages first */
if (need_deinit)
- wpa_supplicant_mesh_deinit(wpa_s);
+ wpa_supplicant_mesh_deinit(wpa_s, true);
ret = wpa_drv_leave_mesh(wpa_s);
if (ret)