cozybit/wpa_supplicant — pull request #5 by chunyeow (2013-08-10 00:29:58+00:00)
Title: Add support of sending PLINK_CLOSE frame before leaving mesh

```
From f1fb92e4503cb7f91cccac06e32915a2818c6f88 Mon Sep 17 00:00:00 2001
From: Chun-Yeow Yeoh
Date: Fri, 9 Aug 2013 17:14:37 -0700
Subject: [PATCH] mesh: send plink close to all mesh STAs while leaving mesh

Sending plink close frame to all mesh STAs while leaving mesh.
We need to do this after only we have joined the mesh network. So,
introduce a flag to indicate that we have successfully joining
the mesh network before doing so.

Signed-off-by: Chun-Yeow Yeoh
---
wpa_supplicant/mesh.c | 12 ++++++++++++
wpa_supplicant/mesh.h | 2 ++
wpa_supplicant/mesh_mpm.c | 13 +++++++++++++
wpa_supplicant/wpa_supplicant_i.h | 1 +
4 files changed, 28 insertions(+)

diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c
index 8f7865e..d72207f 100644
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
@@ -177,6 +177,8 @@ wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
goto out_free;
}

+	wpa_s->join_mesh = 0;
+
return 0;
out_free:
wpa_supplicant_mesh_deinit(wpa_s);
@@ -251,6 +253,9 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s,
ret = wpa_drv_join_mesh(wpa_s, ¶ms);
if (ret)
wpa_msg(wpa_s, MSG_ERROR, "mesh join error=%d", ret);
+	else
+	/* Set this after joining the mesh */
+	wpa_s->join_mesh = 1;

/* hostapd sets the interface down until we associate */
wpa_drv_set_operstate(wpa_s, 1);
@@ -262,6 +267,13 @@ out:
void wpa_supplicant_leave_mesh(struct wpa_supplicant *wpa_s)
{
int ret = 0;
+	struct hostapd_data *bss;
+
+	/* Send all the peering close frame to all mesh STAs before leaving */
+	if (wpa_s->join_mesh) {
+	bss = wpa_s->ifmsh->bss[0];
+	ap_for_each_sta(bss, mesh_deactivate_sta, wpa_s);
+	}

wpa_msg(wpa_s, MSG_INFO, "leaving mesh");
ret = wpa_drv_leave_mesh(wpa_s);
diff --git a/wpa_supplicant/mesh.h b/wpa_supplicant/mesh.h
index 1b2895b..b12367e 100644
--- a/wpa_supplicant/mesh.h
+++ b/wpa_supplicant/mesh.h
@@ -32,4 +32,6 @@ void wpa_supplicant_leave_mesh(struct wpa_supplicant *wpa_s);
void wpa_mesh_notify_peer(struct wpa_supplicant *wpa_s, const u8 *addr,
const u8 *ies, int ie_len);
void wpa_supplicant_mesh_iface_deinit(struct hostapd_iface *ifmsh);
+int mesh_deactivate_sta(struct hostapd_data *hapd,
+	struct sta_info *sta, void *ctx);
#endif /* MESH_H */
diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
index 5df0a57..04a9377 100644
--- a/wpa_supplicant/mesh_mpm.c
+++ b/wpa_supplicant/mesh_mpm.c
@@ -801,3 +801,16 @@ void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s,
}
mesh_mpm_fsm(wpa_s, sta, event);
}
+
+int mesh_deactivate_sta(struct hostapd_data *hapd,
+	struct sta_info *sta, void *ctx)
+{
+	if (sta->plink_state == PLINK_ESTAB) {
+	mesh_mpm_send_plink_action(ctx, sta, PLINK_CLOSE, 0);
+	wpa_printf(MSG_DEBUG, "Mesh MPM: send plink close to " MACSTR,
+	MAC2STR(sta->addr));
+	return 1;
+	}
+
+	return 0;
+}
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 403c33e..10e8e99 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -532,6 +532,7 @@ struct wpa_supplicant {
#ifdef CONFIG_MESH
struct hostapd_iface *ifmsh;
struct mesh_rsn *mesh_rsn;
+	char join_mesh; /* use to indicate whether we have join the mesh */
#endif /* CONFIG_MESH */

unsigned int off_channel_freq;
--
1.7.9.5

```