[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