RRM: Modify the processing of a received neighbor report

Parse a received neighbor report and report for each neighbor report the
data received for it:

RRM-NEIGHBOR-REP-RECEIVED bssid=<BSSID> info=0x<hex> op_class=<class> chan=<chan> [lci=hex] [civic=hex]

Note that this modifies the previous format that originally reported
only the length of the received frame.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
This commit is contained in:
Ilan Peer 2016-04-06 19:42:18 +03:00 committed by Jouni Malinen
parent 00ed0aa2dd
commit cf667c66ac

View file

@ -8236,15 +8236,103 @@ 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) static void wpas_ctrl_neighbor_rep_cb(void *ctx, struct wpabuf *neighbor_rep)
{ {
struct wpa_supplicant *wpa_s = ctx; struct wpa_supplicant *wpa_s = ctx;
size_t len;
const u8 *data;
if (neighbor_rep) { /*
wpa_msg_ctrl(wpa_s, MSG_INFO, RRM_EVENT_NEIGHBOR_REP_RXED * Neighbor Report element (IEEE P802.11-REVmc/D5.0)
"length=%u", * BSSID[6]
(unsigned int) wpabuf_len(neighbor_rep)); * BSSID Information[4]
wpabuf_free(neighbor_rep); * Operating Class[1]
} else { * 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); 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_printf(MSG_DEBUG,
"CTRL: Invalid Neighbor Report element: id=%u len=%u",
data[0], nr_len);
goto out;
}
if (2U + nr_len > len) {
wpa_printf(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);
} }