Browse Source

IBSS RSN: Clear IBSS RSN peers based on peer lost events

Xi Chen 14 years ago
parent
commit
ea244d2156
4 changed files with 62 additions and 1 deletions
  1. 13 1
      src/drivers/driver.h
  2. 8 0
      wpa_supplicant/events.c
  3. 40 0
      wpa_supplicant/ibss_rsn.c
  4. 1 0
      wpa_supplicant/ibss_rsn.h

+ 13 - 1
src/drivers/driver.h

@@ -2614,7 +2614,12 @@ enum wpa_event_type {
 	EVENT_P2P_PROV_DISC_REQUEST,
 	EVENT_P2P_PROV_DISC_RESPONSE,
 	EVENT_P2P_SD_REQUEST,
-	EVENT_P2P_SD_RESPONSE
+	EVENT_P2P_SD_RESPONSE,
+
+	/**
+	 * EVENT_IBSS_PEER_LOST - IBSS peer not reachable anymore
+	 */
+	EVENT_IBSS_PEER_LOST
 };
 
 
@@ -3145,6 +3150,13 @@ union wpa_event_data {
 		const u8 *tlvs;
 		size_t tlvs_len;
 	} p2p_sd_resp;
+
+	/**
+	 * struct ibss_peer_lost - Data for EVENT_IBSS_PEER_LOST
+	 */
+	struct ibss_peer_lost {
+		u8 peer[ETH_ALEN];
+	} ibss_peer_lost;
 };
 
 /**

+ 8 - 0
wpa_supplicant/events.c

@@ -1570,6 +1570,9 @@ wpa_supplicant_event_interface_status(struct wpa_supplicant *wpa_s,
 		wpa_supplicant_mark_disassoc(wpa_s);
 		l2_packet_deinit(wpa_s->l2);
 		wpa_s->l2 = NULL;
+#ifdef CONFIG_IBSS_RSN
+		ibss_rsn_stop(wpa_s->ibss_rsn, NULL);
+#endif /* CONFIG_IBSS_RSN */
 #ifdef CONFIG_TERMINATE_ONLASTIF
 		/* check if last interface */
 		if (!any_interfaces(wpa_s->global->ifaces))
@@ -2178,6 +2181,11 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
 						  data->low_ack.addr);
 #endif /* CONFIG_AP */
 		break;
+	case EVENT_IBSS_PEER_LOST:
+#ifdef CONFIG_IBSS_RSN
+		ibss_rsn_stop(wpa_s->ibss_rsn, data->ibss_peer_lost.peer);
+#endif /* CONFIG_IBSS_RSN */
+		break;
 	default:
 		wpa_msg(wpa_s, MSG_INFO, "Unknown event %d", event);
 		break;

+ 40 - 0
wpa_supplicant/ibss_rsn.c

@@ -426,6 +426,46 @@ int ibss_rsn_start(struct ibss_rsn *ibss_rsn, const u8 *addr)
 }
 
 
+void ibss_rsn_stop(struct ibss_rsn *ibss_rsn, const u8 *peermac)
+{
+	struct ibss_rsn_peer *peer, *prev;
+
+	if (ibss_rsn == NULL)
+		return;
+
+	if (peermac == NULL) {
+		/* remove all peers */
+		wpa_printf(MSG_DEBUG, "%s: Remove all peers", __func__);
+		peer = ibss_rsn->peers;
+		while (peer) {
+			prev = peer;
+			peer = peer->next;
+			ibss_rsn_free(prev);
+			ibss_rsn->peers = peer;
+		}
+	} else {
+		/* remove specific peer */
+		wpa_printf(MSG_DEBUG, "%s: Remove specific peer " MACSTR,
+			   __func__, MAC2STR(peermac));
+
+		for (prev = NULL, peer = ibss_rsn->peers; peer != NULL;
+		     prev = peer, peer = peer->next) {
+			if (os_memcmp(peermac, peer->addr, ETH_ALEN) == 0) {
+				if (prev == NULL)
+					ibss_rsn->peers = peer->next;
+				else
+					prev->next = peer->next;
+				ibss_rsn_free(peer);
+				wpa_printf(MSG_DEBUG, "%s: Successfully "
+					   "removed a specific peer",
+					   __func__);
+				break;
+			}
+		}
+	}
+}
+
+
 struct ibss_rsn * ibss_rsn_init(struct wpa_supplicant *wpa_s)
 {
 	struct ibss_rsn *ibss_rsn;

+ 1 - 0
wpa_supplicant/ibss_rsn.h

@@ -46,6 +46,7 @@ struct ibss_rsn {
 struct ibss_rsn * ibss_rsn_init(struct wpa_supplicant *wpa_s);
 void ibss_rsn_deinit(struct ibss_rsn *ibss_rsn);
 int ibss_rsn_start(struct ibss_rsn *ibss_rsn, const u8 *addr);
+void ibss_rsn_stop(struct ibss_rsn *ibss_rsn, const u8 *peermac);
 int ibss_rsn_rx_eapol(struct ibss_rsn *ibss_rsn, const u8 *src_addr,
 		      const u8 *buf, size_t len);
 void ibss_rsn_set_psk(struct ibss_rsn *ibss_rsn, const u8 *psk);