]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - wilink8-wlan/build-utilites.git/blobdiff - patches/hostapd_patches/0030-Mesh-bug-fix-make-sure-when-we-disconnect-we-wait-fo.patch
Creating new folders for hostapd patches and wpa_supplicant configuration.
[wilink8-wlan/build-utilites.git] / patches / hostapd_patches / 0030-Mesh-bug-fix-make-sure-when-we-disconnect-we-wait-fo.patch
diff --git a/patches/hostapd_patches/0030-Mesh-bug-fix-make-sure-when-we-disconnect-we-wait-fo.patch b/patches/hostapd_patches/0030-Mesh-bug-fix-make-sure-when-we-disconnect-we-wait-fo.patch
new file mode 100644 (file)
index 0000000..1307f44
--- /dev/null
@@ -0,0 +1,230 @@
+From e471ede0700591b8b2db978951282e976e7ac38d Mon Sep 17 00:00:00 2001
+From: Chen Loewy <c-loewy@ti.com>
+Date: Thu, 18 Feb 2016 14:35:16 +0200
+Subject: [PATCH 30/47] Mesh: bug fix - make sure when we disconnect we wait
+ for plink_close to be received
+
+When leaving mesh we are not waiting for the other side to respond to our
+close command and tear down the interface.
+This fix waits for 300ms and only then tears down the interface leaving
+enough time for the other side to receive our close action and send us
+a close action back.
+
+note - there is still an issue with mesh_join - when calling mesh join
+we first tear down the last mesh - in that case we won't wait - and this
+bug still occurs - needs to be fixed later on.
+
+Signed-off-by: Chen Loewy <c-loewy@ti.com>
+---
+ src/ap/hostapd.h                |  1 +
+ wpa_supplicant/mesh.c           | 14 +++++++++++++-
+ wpa_supplicant/mesh_mpm.c       | 38 +++++++++++++++++++++++++++++++++-----
+ wpa_supplicant/mesh_mpm.h       |  6 +++++-
+ wpa_supplicant/wpa_supplicant.c | 13 ++++++-------
+ 5 files changed, 58 insertions(+), 14 deletions(-)
+
+diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
+index 518c7f1..084ad3a 100644
+--- a/src/ap/hostapd.h
++++ b/src/ap/hostapd.h
+@@ -433,6 +433,7 @@ struct hostapd_iface {
+ #ifdef CONFIG_MESH
+       struct mesh_conf *mconf;
++      Boolean  mesh_deinit_process;
+ #endif /* CONFIG_MESH */
+       size_t num_bss;
+diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c
+index fb72ed8..8b16ef2 100644
+--- a/wpa_supplicant/mesh.c
++++ b/wpa_supplicant/mesh.c
+@@ -48,7 +48,8 @@ void wpa_supplicant_mesh_iface_deinit(struct wpa_supplicant *wpa_s,
+               return;
+       if (ifmsh->mconf) {
+-              mesh_mpm_deinit(wpa_s, ifmsh);
++              struct hostapd_data *hapd = ifmsh->bss[0];
++              hostapd_free_stas(hapd);
+               if (ifmsh->mconf->rsn_ie) {
+                       ifmsh->mconf->rsn_ie = NULL;
+                       /* We cannot free this struct
+@@ -265,6 +266,7 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
+       if (!ifmsh)
+               return -ENOMEM;
++      ifmsh->mesh_deinit_process = FALSE;
+       ifmsh->drv_flags = wpa_s->drv_flags;
+       ifmsh->num_bss = 1;
+       ifmsh->bss = os_calloc(wpa_s->ifmsh->num_bss,
+@@ -450,6 +452,9 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s,
+               goto out;
+       }
++      if (wpa_s->ifmsh)
++              mesh_mpm_close_links(wpa_s,wpa_s->ifmsh);
++
+       wpa_supplicant_mesh_deinit(wpa_s);
+       wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
+@@ -715,3 +720,10 @@ int wpas_mesh_peer_add(struct wpa_supplicant *wpa_s, const u8 *addr,
+ {
+       return mesh_mpm_connect_peer(wpa_s, addr, duration);
+ }
++
++
++int wpa_supplicant_leave_mesh_initiate(struct wpa_supplicant *wpa_s)
++{
++      wpa_s->ifmsh->mesh_deinit_process = TRUE;
++      mesh_mpm_close_links(wpa_s,wpa_s->ifmsh);
++}
+diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
+index c2c4981..8e1d016 100644
+--- a/wpa_supplicant/mesh_mpm.c
++++ b/wpa_supplicant/mesh_mpm.c
+@@ -463,6 +463,32 @@ static void mesh_mpm_fsm_restart(struct wpa_supplicant *wpa_s,
+ }
++static void mesh_close_links_timer(void *eloop_ctx, void *user_data)
++{
++      struct wpa_supplicant *wpa_s = eloop_ctx;
++      struct hostapd_data *hapd = NULL;
++
++      if (wpa_s->ifmsh)
++              hapd = wpa_s->ifmsh->bss[0];
++
++      /*
++      *in case we timed out and not all mesh links were closed appropriately
++      * we now clean all links
++      */
++
++      if (hapd) {
++              while (hapd->num_plinks > 0) {
++                      wpa_msg(wpa_s, MSG_ERROR,"mesh_close_links_timer, num of plinks: %d",hapd->num_plinks );
++
++                      hapd->num_plinks--;
++                      mesh_mpm_fsm_restart(wpa_s, hapd->sta_list);
++              }
++      }
++
++      if ( (wpa_s->ifmsh) && (wpa_s->ifmsh->mesh_deinit_process) )
++              wpa_supplicant_leave_mesh(wpa_s);
++
++}
+ static void plink_timer(void *eloop_ctx, void *user_data)
+ {
+       struct wpa_supplicant *wpa_s = eloop_ctx;
+@@ -530,7 +556,7 @@ mesh_mpm_plink_open(struct wpa_supplicant *wpa_s, struct sta_info *sta,
+ }
+-static int mesh_mpm_plink_close(struct hostapd_data *hapd, struct sta_info *sta,
++int mesh_mpm_plink_close(struct hostapd_data *hapd, struct sta_info *sta,
+                               void *ctx)
+ {
+       struct wpa_supplicant *wpa_s = ctx;
+@@ -538,6 +564,7 @@ static int mesh_mpm_plink_close(struct hostapd_data *hapd, struct sta_info *sta,
+       if (sta) {
+               wpa_mesh_set_plink_state(wpa_s, sta, PLINK_HOLDING);
++              hapd->num_plinks--;
+               mesh_mpm_send_plink_action(wpa_s, sta, PLINK_CLOSE, reason);
+               wpa_printf(MSG_DEBUG, "MPM closing plink sta=" MACSTR,
+                          MAC2STR(sta->addr));
+@@ -628,16 +655,14 @@ int mesh_mpm_connect_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
+ }
+-void mesh_mpm_deinit(struct wpa_supplicant *wpa_s, struct hostapd_iface *ifmsh)
++void mesh_mpm_close_links(struct wpa_supplicant *wpa_s, struct hostapd_iface *ifmsh)
+ {
+       struct hostapd_data *hapd = ifmsh->bss[0];
+       /* notify peers we're leaving */
+       ap_for_each_sta(hapd, mesh_mpm_plink_close, wpa_s);
+-      hapd->num_plinks = 0;
+-      hostapd_free_stas(hapd);
+-      eloop_cancel_timeout(peer_add_timer, wpa_s, NULL);
++      eloop_register_timeout(0, MESH_CLOSE_LINKS_RESPONSE_TIMER, mesh_close_links_timer, wpa_s, NULL);
+ }
+@@ -807,6 +832,9 @@ void wpa_mesh_new_mesh_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
+       struct ieee80211_mesh_config *mesh_conf_ie =
+               (struct ieee80211_mesh_config *)elems->mesh_config;
++      if (wpa_s->ifmsh->mesh_deinit_process)
++                return;
++
+       /* check if peer accepts new connection. Don't initiate link if peer is full*/
+       if ((ssid && ssid->no_auto_peer &&
+            (is_zero_ether_addr(data->mesh_required_peer) ||
+diff --git a/wpa_supplicant/mesh_mpm.h b/wpa_supplicant/mesh_mpm.h
+index 5fc1e61..26111f2 100644
+--- a/wpa_supplicant/mesh_mpm.h
++++ b/wpa_supplicant/mesh_mpm.h
+@@ -12,7 +12,7 @@
+ /* notify MPM of new mesh peer to be inserted in MPM and driver */
+ void wpa_mesh_new_mesh_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
+                           struct ieee802_11_elems *elems);
+-void mesh_mpm_deinit(struct wpa_supplicant *wpa_s, struct hostapd_iface *ifmsh);
++void mesh_mpm_close_links(struct wpa_supplicant *wpa_s, struct hostapd_iface *ifmsh);
+ void mesh_mpm_auth_peer(struct wpa_supplicant *wpa_s, const u8 *addr);
+ void mesh_mpm_free_sta(struct hostapd_data *hapd, struct sta_info *sta);
+ void wpa_mesh_set_plink_state(struct wpa_supplicant *wpa_s,
+@@ -21,6 +21,8 @@ void wpa_mesh_set_plink_state(struct wpa_supplicant *wpa_s,
+ int mesh_mpm_close_peer(struct wpa_supplicant *wpa_s, const u8 *addr);
+ int mesh_mpm_connect_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
+                         int duration);
++int mesh_mpm_plink_close(struct hostapd_data *hapd, struct sta_info *sta,
++                              void *ctx);
+ #ifdef CONFIG_MESH
+@@ -28,6 +30,8 @@ void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s,
+                       const struct ieee80211_mgmt *mgmt, size_t len);
+ void mesh_mpm_mgmt_rx(struct wpa_supplicant *wpa_s, struct rx_mgmt *rx_mgmt);
++#define MESH_CLOSE_LINKS_RESPONSE_TIMER       300000 // 300 ms - 300,000usec
++
+ #else /* CONFIG_MESH */
+ static inline void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s,
+diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
+index 4a0edc7..63724a6 100644
+--- a/wpa_supplicant/wpa_supplicant.c
++++ b/wpa_supplicant/wpa_supplicant.c
+@@ -3484,11 +3484,12 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
+               struct mesh_conf *mconf;
+               mconf = wpa_s->ifmsh->mconf;
+-              wpa_msg(wpa_s, MSG_INFO, MESH_GROUP_REMOVED "%s",
+-                      wpa_s->ifname);
+               wpas_notify_mesh_group_removed(wpa_s, mconf->meshid,
+                                              mconf->meshid_len, reason_code);
+-              wpa_supplicant_leave_mesh(wpa_s);
++              wpa_msg_ctrl(wpa_s, MSG_INFO, MESH_GROUP_REMOVED "%s",
++                           wpa_s->ifname);
++              wpa_supplicant_leave_mesh_initiate(wpa_s);
++
+       }
+ #endif /* CONFIG_MESH */
+@@ -6050,10 +6051,8 @@ static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
+       }
+ #ifdef CONFIG_MESH
+-      if (wpa_s->ifmsh) {
+-              wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh);
+-              wpa_s->ifmsh = NULL;
+-      }
++      if (wpa_s->ifmsh)
++              wpa_supplicant_leave_mesh(wpa_s);
+ #endif /* CONFIG_MESH */
+       if (wpa_s->conf != NULL) {
+-- 
+1.9.1
+