[PATCH 05/19] wpa_supplicant: Add LCI and civic to neighbor report request
Ilan Peer
ilan.peer at intel.com
Tue Apr 5 06:07:58 PDT 2016
From: David Spinadel <david.spinadel at intel.com>
Add an option to request LCI and location civic in neighbor report
request, as described in ieee802.11 spec 8.6.7.6.
Signed-off-by: David Spinadel <david.spinadel at intel.com>
---
tests/hwsim/test_wpas_ctrl.py | 4 +--
wpa_supplicant/ctrl_iface.c | 34 ++++++++++++++++------
wpa_supplicant/wpa_cli.c | 5 ++--
wpa_supplicant/wpa_supplicant.c | 60 +++++++++++++++++++++++++++++++++++++--
wpa_supplicant/wpa_supplicant_i.h | 3 +-
5 files changed, 91 insertions(+), 15 deletions(-)
diff --git a/tests/hwsim/test_wpas_ctrl.py b/tests/hwsim/test_wpas_ctrl.py
index 8bbacd2..48421d3 100644
--- a/tests/hwsim/test_wpas_ctrl.py
+++ b/tests/hwsim/test_wpas_ctrl.py
@@ -1278,7 +1278,7 @@ def test_wpas_ctrl_neighbor_rep_req(dev, apdev):
dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
if "FAIL" not in dev[0].request("NEIGHBOR_REP_REQUEST"):
raise Exception("Request succeeded unexpectedly")
- if "FAIL" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=abcdef"):
+ if "FAIL" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"abcdef\""):
raise Exception("Request succeeded unexpectedly")
dev[0].request("DISCONNECT")
@@ -1300,7 +1300,7 @@ def test_wpas_ctrl_neighbor_rep_req(dev, apdev):
raise Exception("RRM report result not indicated")
logger.info("RRM result: " + ev)
- if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=abcdef"):
+ if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"abcdef\""):
raise Exception("Request failed")
ev = dev[0].wait_event([ "RRM-NEIGHBOR-REP-RECEIVED",
"RRM-NEIGHBOR-REP-REQUEST-FAILED" ], timeout=10)
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 8574437..6e91e31 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -8222,19 +8222,37 @@ static void wpas_ctrl_neighbor_rep_cb(void *ctx, struct wpabuf *neighbor_rep)
static int wpas_ctrl_iface_send_neigbor_rep(struct wpa_supplicant *wpa_s,
char *cmd)
{
- struct wpa_ssid ssid;
- struct wpa_ssid *ssid_p = NULL;
- int ret = 0;
+ struct wpa_ssid_value ssid, *ssid_p = NULL;
+ int lci = 0, civic = 0;
+ int ret;
+ char *ssid_s;
- if (os_strncmp(cmd, " ssid=", 6) == 0) {
- ssid.ssid_len = os_strlen(cmd + 6);
- if (ssid.ssid_len > SSID_MAX_LEN)
+ ssid_s = os_strstr(cmd, "ssid=");
+ if (ssid_s) {
+ if (ssid_parse(ssid_s + 5, &ssid)) {
+ wpa_printf(MSG_ERROR,
+ "CTRL: send neighbor rep: bad ssid");
return -1;
- ssid.ssid = (u8 *) (cmd + 6);
+ }
+
ssid_p = &ssid;
+
+ /* Move cmd after the SSID text that may include "lci" or
+ * "civic".
+ */
+ cmd = os_strchr(ssid_s + 6, ssid_s[5] == '"' ? '"' : ' ');
+ if (cmd)
+ cmd++;
+
}
- ret = wpas_rrm_send_neighbor_rep_request(wpa_s, ssid_p,
+ if (cmd && os_strstr(cmd, "lci"))
+ lci = 1;
+
+ if (cmd && os_strstr(cmd, "civic"))
+ civic = 1;
+
+ ret = wpas_rrm_send_neighbor_rep_request(wpa_s, ssid_p, lci, civic,
wpas_ctrl_neighbor_rep_cb,
wpa_s);
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index 36a7a4e..911ee3e 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -3455,8 +3455,9 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = {
},
{ "neighbor_rep_request",
wpa_cli_cmd_neighbor_rep_request, NULL, cli_cmd_flag_none,
- "[ssid=<SSID>] = Trigger request to AP for neighboring AP report "
- "(with optional given SSID, default: current SSID)"
+ "[ssid=<SSID>] [lci] [civic] = Trigger request to AP for neighboring "
+ "AP report (with optional given SSID in hex or enclosesd in double quotes, "
+ "default: current SSID; with optional LCI and location civic request)"
},
{ "erp_flush", wpa_cli_cmd_erp_flush, NULL, cli_cmd_flag_none,
"= flush ERP keys" },
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 51bb245..8b30c98 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -6152,11 +6152,19 @@ void wpas_rrm_process_neighbor_rep(struct wpa_supplicant *wpa_s,
#define ECANCELED -1
#endif
+/* Measure request + location subject + max age subelement */
+#define MEASURE_REQUEST_LCI_LEN (3 + 1 + 4)
+/* Measure request + location civic request */
+#define MEASURE_REQUEST_CIVIC_LEN (3 + 5)
+
+
/**
* wpas_rrm_send_neighbor_rep_request - Request a neighbor report from our AP
* @wpa_s: Pointer to wpa_supplicant
* @ssid: if not null, this is sent in the request. Otherwise, no SSID IE
* is sent in the request.
+ * @lci: if set, neighbor request will include LCI request
+ * @civic: if set, neighbor request will include civic location request
* @cb: Callback function to be called once the requested report arrives, or
* timed out after RRM_NEIGHBOR_REPORT_TIMEOUT seconds.
* In the former case, 'neighbor_rep' is a newly allocated wpabuf, and it's
@@ -6170,7 +6178,8 @@ void wpas_rrm_process_neighbor_rep(struct wpa_supplicant *wpa_s,
* Request must contain a callback function.
*/
int wpas_rrm_send_neighbor_rep_request(struct wpa_supplicant *wpa_s,
- const struct wpa_ssid *ssid,
+ const struct wpa_ssid_value *ssid,
+ int lci, int civic,
void (*cb)(void *ctx,
struct wpabuf *neighbor_rep),
void *cb_ctx)
@@ -6211,7 +6220,9 @@ int wpas_rrm_send_neighbor_rep_request(struct wpa_supplicant *wpa_s,
}
/* 3 = action category + action code + dialog token */
- buf = wpabuf_alloc(3 + (ssid ? 2 + ssid->ssid_len : 0));
+ buf = wpabuf_alloc(3 + (ssid ? 2 + ssid->ssid_len : 0) +
+ (lci ? 2 + MEASURE_REQUEST_LCI_LEN : 0) +
+ (civic ? 2 + MEASURE_REQUEST_CIVIC_LEN : 0));
if (buf == NULL) {
wpa_printf(MSG_DEBUG,
"RRM: Failed to allocate Neighbor Report Request");
@@ -6231,6 +6242,51 @@ int wpas_rrm_send_neighbor_rep_request(struct wpa_supplicant *wpa_s,
wpabuf_put_data(buf, ssid->ssid, ssid->ssid_len);
}
+ if (lci) {
+ wpabuf_put_u8(buf, WLAN_EID_MEASURE_REQUEST);
+ wpabuf_put_u8(buf, MEASURE_REQUEST_LCI_LEN);
+ /* Measurement token; unique among the measurement requests in a
+ * particular frame
+ */
+ wpabuf_put_u8(buf, 1);
+ /* Parallel, enable, request and report bits are 0, duration is
+ * reserved
+ */
+ wpabuf_put_u8(buf, 0);
+ wpabuf_put_u8(buf, MEASURE_TYPE_LCI);
+
+ wpabuf_put_u8(buf, LOCATION_SUBJECT_REMOTE);
+
+ /* Max age subelement is required, otherwise the AP can send
+ * only data that was determined after receiving the request.
+ * Setting it here to unlimited age.
+ */
+ wpabuf_put_u8(buf, LCI_REQ_SUBELEMENT_MAX_AGE);
+ wpabuf_put_u8(buf, 2);
+ wpabuf_put_le16(buf, 0xffff);
+ }
+
+ if (civic) {
+ wpabuf_put_u8(buf, WLAN_EID_MEASURE_REQUEST);
+ wpabuf_put_u8(buf, MEASURE_REQUEST_CIVIC_LEN);
+
+ /* Measurement token; unique among the mesurement requests in a
+ * particular frame
+ */
+ wpabuf_put_u8(buf, 2);
+ /* Parallel, enable, request and report bits are 0, duration is
+ * reserved
+ */
+ wpabuf_put_u8(buf, 0);
+ wpabuf_put_u8(buf, MEASURE_TYPE_LOCATION_CIVIC);
+
+ wpabuf_put_u8(buf, LOCATION_SUBJECT_REMOTE);
+ wpabuf_put_u8(buf, 0); /* Location civic type IETF RFC 4776 */
+ wpabuf_put_u8(buf, 0); /* Location service interval units */
+ /* Location service interval 0 - Only one report is required */
+ wpabuf_put_le16(buf, 0);
+ }
+
wpa_s->rrm.next_neighbor_rep_token++;
if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index e6fc457..211f4d1 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1163,7 +1163,8 @@ void wpas_rrm_reset(struct wpa_supplicant *wpa_s);
void wpas_rrm_process_neighbor_rep(struct wpa_supplicant *wpa_s,
const u8 *report, size_t report_len);
int wpas_rrm_send_neighbor_rep_request(struct wpa_supplicant *wpa_s,
- const struct wpa_ssid *ssid,
+ const struct wpa_ssid_value *ssid,
+ int lci, int civic,
void (*cb)(void *ctx,
struct wpabuf *neighbor_rep),
void *cb_ctx);
--
1.9.1
More information about the Hostap
mailing list