[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