[PATCH 1/2] RRM: Move Neighbor Report event notification to RRM

Chung-Hsien Hsu chung-hsien.hsu at infineon.com
Tue May 12 06:25:02 PDT 2026


The Neighbor Report control interface event formatting is currently
implemented in ctrl_iface.c as part of the NEIGHBOR_REP_REQUEST command
callback. Move this formatting into RRM code so that it can be reused by
other Neighbor Report Response processing paths.

This is a refactoring change and is not intended to change the
control-interface event format or ownership rules for the neighbor_rep
buffer.

Signed-off-by: Chung-Hsien Hsu <chung-hsien.hsu at infineon.com>
---
 wpa_supplicant/ctrl_iface.c       |  97 +-------------------------
 wpa_supplicant/rrm.c              | 111 ++++++++++++++++++++++++++++++
 wpa_supplicant/wpa_supplicant_i.h |   2 +
 3 files changed, 114 insertions(+), 96 deletions(-)

diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 1096fa228d06..f1d1f8079b97 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -10868,103 +10868,8 @@ static int wpas_ctrl_vendor_elem_remove(struct wpa_supplicant *wpa_s, char *cmd)
 static void wpas_ctrl_neighbor_rep_cb(void *ctx, struct wpabuf *neighbor_rep)
 {
 	struct wpa_supplicant *wpa_s = ctx;
-	size_t len;
-	const u8 *data;
 
-	/*
-	 * Neighbor Report element (IEEE Std 802.11-2024, 9.4.2.35)
-	 * BSSID[6]
-	 * BSSID Information[4]
-	 * Operating Class[1]
-	 * Channel Number[1]
-	 * PHY Type[1]
-	 * Optional Subelements[variable]
-	 */
-#define NR_IE_MIN_LEN (ETH_ALEN + 4 + 1 + 1 + 1)
-
-	if (!neighbor_rep || wpabuf_len(neighbor_rep) == 0) {
-		wpa_msg_ctrl(wpa_s, MSG_INFO, RRM_EVENT_NEIGHBOR_REP_FAILED);
-		goto out;
-	}
-
-	data = wpabuf_head_u8(neighbor_rep);
-	len = wpabuf_len(neighbor_rep);
-
-	while (len >= 2 + NR_IE_MIN_LEN) {
-		const u8 *nr;
-		char lci[256 * 2 + 1];
-		char civic[256 * 2 + 1];
-		u8 nr_len = data[1];
-		const u8 *pos = data, *end;
-
-		if (pos[0] != WLAN_EID_NEIGHBOR_REPORT ||
-		    nr_len < NR_IE_MIN_LEN) {
-			wpa_dbg(wpa_s, MSG_DEBUG,
-				"CTRL: Invalid Neighbor Report element: id=%u len=%u",
-				data[0], nr_len);
-			goto out;
-		}
-
-		if (2U + nr_len > len) {
-			wpa_dbg(wpa_s, MSG_DEBUG,
-				"CTRL: Invalid Neighbor Report element: id=%u len=%zu nr_len=%u",
-				data[0], len, nr_len);
-			goto out;
-		}
-		pos += 2;
-		end = pos + nr_len;
-
-		nr = pos;
-		pos += NR_IE_MIN_LEN;
-
-		lci[0] = '\0';
-		civic[0] = '\0';
-		while (end - pos > 2) {
-			u8 s_id, s_len;
-
-			s_id = *pos++;
-			s_len = *pos++;
-			if (s_len > end - pos)
-				goto out;
-			if (s_id == WLAN_EID_MEASURE_REPORT && s_len > 3) {
-				/* Measurement Token[1] */
-				/* Measurement Report Mode[1] */
-				/* Measurement Type[1] */
-				/* Measurement Report[variable] */
-				switch (pos[2]) {
-				case MEASURE_TYPE_LCI:
-					if (lci[0])
-						break;
-					wpa_snprintf_hex(lci, sizeof(lci),
-							 pos, s_len);
-					break;
-				case MEASURE_TYPE_LOCATION_CIVIC:
-					if (civic[0])
-						break;
-					wpa_snprintf_hex(civic, sizeof(civic),
-							 pos, s_len);
-					break;
-				}
-			}
-
-			pos += s_len;
-		}
-
-		wpa_msg(wpa_s, MSG_INFO, RRM_EVENT_NEIGHBOR_REP_RXED
-			"bssid=" MACSTR
-			" info=0x%x op_class=%u chan=%u phy_type=%u%s%s%s%s",
-			MAC2STR(nr), WPA_GET_LE32(nr + ETH_ALEN),
-			nr[ETH_ALEN + 4], nr[ETH_ALEN + 5],
-			nr[ETH_ALEN + 6],
-			lci[0] ? " lci=" : "", lci,
-			civic[0] ? " civic=" : "", civic);
-
-		data = end;
-		len -= 2 + nr_len;
-	}
-
-out:
-	wpabuf_free(neighbor_rep);
+	wpas_rrm_notify_neighbor_rep(wpa_s, neighbor_rep);
 }
 
 
diff --git a/wpa_supplicant/rrm.c b/wpa_supplicant/rrm.c
index 2430aeee7bcf..07e952dfe6fc 100644
--- a/wpa_supplicant/rrm.c
+++ b/wpa_supplicant/rrm.c
@@ -11,6 +11,7 @@
 #include "utils/common.h"
 #include "utils/eloop.h"
 #include "common/ieee802_11_common.h"
+#include "common/wpa_ctrl.h"
 #include "wpa_supplicant_i.h"
 #include "driver_i.h"
 #include "bss.h"
@@ -53,6 +54,116 @@ void wpas_rrm_reset(struct wpa_supplicant *wpa_s)
 }
 
 
+/*
+ * wpas_rrm_notify_neighbor_rep - Notify received neighbor report
+ * @wpa_s: Pointer to wpa_supplicant
+ * @neighbor_rep: Pointer to neighbor report element
+ */
+void wpas_rrm_notify_neighbor_rep(struct wpa_supplicant *wpa_s,
+				  struct wpabuf *neighbor_rep)
+{
+	size_t len;
+	const u8 *data;
+
+	/*
+	 * Neighbor Report element (IEEE Std 802.11-2024, 9.4.2.35)
+	 * BSSID[6]
+	 * BSSID Information[4]
+	 * Operating Class[1]
+	 * Channel Number[1]
+	 * PHY Type[1]
+	 * Optional Subelements[variable]
+	 */
+#define NR_IE_MIN_LEN (ETH_ALEN + 4 + 1 + 1 + 1)
+
+	if (!neighbor_rep || wpabuf_len(neighbor_rep) == 0) {
+		wpa_msg_ctrl(wpa_s, MSG_INFO, RRM_EVENT_NEIGHBOR_REP_FAILED);
+		goto out;
+	}
+
+	data = wpabuf_head_u8(neighbor_rep);
+	len = wpabuf_len(neighbor_rep);
+
+	while (len >= 2 + NR_IE_MIN_LEN) {
+		const u8 *nr;
+		char lci[256 * 2 + 1];
+		char civic[256 * 2 + 1];
+		u8 nr_len = data[1];
+		const u8 *pos = data, *end;
+
+		if (pos[0] != WLAN_EID_NEIGHBOR_REPORT ||
+		    nr_len < NR_IE_MIN_LEN) {
+			wpa_dbg(wpa_s, MSG_DEBUG,
+				"RRM: Invalid Neighbor Report element: id=%u len=%u",
+				data[0], nr_len);
+			goto out;
+		}
+
+		if (2U + nr_len > len) {
+			wpa_dbg(wpa_s, MSG_DEBUG,
+				"RRM: Invalid Neighbor Report element: id=%u len=%zu nr_len=%u",
+				data[0], len, nr_len);
+			goto out;
+		}
+
+		pos += 2;
+		end = pos + nr_len;
+		nr = pos;
+		pos += NR_IE_MIN_LEN;
+
+		lci[0] = '\0';
+		civic[0] = '\0';
+		while (end - pos > 2) {
+			u8 s_id, s_len;
+
+			s_id = *pos++;
+			s_len = *pos++;
+
+			if (s_len > end - pos)
+				goto out;
+
+			if (s_id == WLAN_EID_MEASURE_REPORT && s_len > 3) {
+				/* Measurement Token[1] */
+				/* Measurement Report Mode[1] */
+				/* Measurement Type[1] */
+				/* Measurement Report[variable] */
+				switch (pos[2]) {
+				case MEASURE_TYPE_LCI:
+					if (lci[0])
+						break;
+					wpa_snprintf_hex(lci, sizeof(lci),
+							 pos, s_len);
+					break;
+				case MEASURE_TYPE_LOCATION_CIVIC:
+					if (civic[0])
+						break;
+					wpa_snprintf_hex(civic, sizeof(civic),
+							 pos, s_len);
+					break;
+				}
+			}
+
+			pos += s_len;
+		}
+
+		wpa_msg(wpa_s, MSG_INFO, RRM_EVENT_NEIGHBOR_REP_RXED
+			"bssid=" MACSTR
+			" info=0x%x op_class=%u chan=%u phy_type=%u%s%s%s%s",
+			MAC2STR(nr), WPA_GET_LE32(nr + ETH_ALEN),
+			nr[ETH_ALEN + 4], nr[ETH_ALEN + 5],
+			nr[ETH_ALEN + 6],
+			lci[0] ? " lci=" : "", lci,
+			civic[0] ? " civic=" : "", civic);
+
+		data = end;
+		len -= 2 + nr_len;
+	}
+
+out:
+	wpabuf_free(neighbor_rep);
+}
+
+
 /*
  * wpas_rrm_process_neighbor_rep - Handle incoming neighbor report
  * @wpa_s: Pointer to wpa_supplicant
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index d68dd582fb75..6563399928f8 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1896,6 +1896,8 @@ void wpas_rrm_reset(struct wpa_supplicant *wpa_s);
 void wpas_rrm_process_neighbor_rep(struct wpa_supplicant *wpa_s,
 				   const u8 *da, const u8 *sa,
 				   const u8 *report, size_t report_len);
+void wpas_rrm_notify_neighbor_rep(struct wpa_supplicant *wpa_s,
+				  struct wpabuf *neighbor_rep);
 int wpas_rrm_send_neighbor_rep_request(struct wpa_supplicant *wpa_s,
 				       const struct wpa_ssid_value *ssid,
 				       int lci, int civic,
-- 
2.25.1




More information about the Hostap mailing list