diff mbox series

[4/5] twt: Support sending teardown action frame.

Message ID 20210306161840.16652-3-greearb@candelatech.com
State Accepted
Headers show
Series [1/5] supplicant: Support disabling HE for stations. | expand

Commit Message

Ben Greear March 6, 2021, 4:18 p.m. UTC
From: Ben Greear <greearb@candelatech.com>

User can supply the 1-byte flags value.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 wpa_supplicant/ctrl_iface.c       | 18 ++++++++++++
 wpa_supplicant/twt.c              | 47 +++++++++++++++++++++++++++++++
 wpa_supplicant/wpa_cli.c          |  9 ++++++
 wpa_supplicant/wpa_supplicant_i.h |  2 ++
 4 files changed, 76 insertions(+)
diff mbox series

Patch

diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 1a1c2ca82..0fb84e435 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -10134,6 +10134,21 @@  static int wpas_ctrl_iface_send_twt_setup(struct wpa_supplicant *wpa_s,
 	return ret;
 }
 
+static int wpas_ctrl_iface_send_twt_teardown(struct wpa_supplicant *wpa_s,
+					     char *cmd)
+{
+	int ret;
+	int flags = 0x1;
+
+	char* tok_s = os_strstr(cmd, "flags=");
+	if (tok_s)
+		flags = atoi(tok_s + strlen("flags="));
+
+	ret = wpas_twt_send_teardown(wpa_s, flags);
+
+	return ret;
+}
+
 
 static int wpas_ctrl_iface_erp_flush(struct wpa_supplicant *wpa_s)
 {
@@ -11359,6 +11374,9 @@  char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
 	} else if (os_strncmp(buf, "TWT_SETUP", 20) == 0) {
 		if (wpas_ctrl_iface_send_twt_setup(wpa_s, buf + 9))
 			reply_len = -1;
+	} else if (os_strncmp(buf, "TWT_TEARDOWN", 20) == 0) {
+		if (wpas_ctrl_iface_send_twt_teardown(wpa_s, buf + 9))
+			reply_len = -1;
 	} else if (os_strcmp(buf, "ERP_FLUSH") == 0) {
 		wpas_ctrl_iface_erp_flush(wpa_s);
 	} else if (os_strncmp(buf, "MAC_RAND_SCAN ", 14) == 0) {
diff --git a/wpa_supplicant/twt.c b/wpa_supplicant/twt.c
index 6b62631b7..39fb5a629 100644
--- a/wpa_supplicant/twt.c
+++ b/wpa_supplicant/twt.c
@@ -88,3 +88,50 @@  int wpas_twt_send_setup(struct wpa_supplicant *wpa_s,
 	wpabuf_free(buf);
 	return 0;
 }
+
+/**
+ * wpas_twt_send_teardown - Send TWT teardown request to our AP
+ * @wpa_s: Pointer to wpa_supplicant
+ * @flags: The byte that goes inside the teardown IE
+ * Returns: 0 in case of success, negative error code otherwise
+ *
+ */
+int wpas_twt_send_teardown(struct wpa_supplicant *wpa_s,
+			   int flags)
+{
+	struct wpabuf *buf;
+
+	if (wpa_s->wpa_state != WPA_COMPLETED || wpa_s->current_ssid == NULL) {
+		wpa_dbg(wpa_s, MSG_DEBUG, "TWT: No connection, no TWT.");
+		return -ENOTCONN;
+	}
+
+	/* 3 = action category + action code + flags */
+	buf = wpabuf_alloc(3);
+
+	if (buf == NULL) {
+		wpa_dbg(wpa_s, MSG_DEBUG,
+			"TWT: Failed to allocate TWT Teardown Request");
+		return -ENOMEM;
+	}
+
+	wpa_dbg(wpa_s, MSG_DEBUG,
+		"TWT: Teardown request, flags: 0x%x",
+		flags);
+
+	wpabuf_put_u8(buf, WLAN_ACTION_S1G);
+	wpabuf_put_u8(buf, S1G_ACT_TWT_TEARDOWN);
+	wpabuf_put_u8(buf, flags);
+
+	if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
+				wpa_s->own_addr, wpa_s->bssid,
+				wpabuf_head(buf), wpabuf_len(buf), 0) < 0) {
+		wpa_dbg(wpa_s, MSG_DEBUG,
+			"TWT: Failed to send TWT Teardown Request");
+		wpabuf_free(buf);
+		return -ECANCELED;
+	}
+
+	wpabuf_free(buf);
+	return 0;
+}
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index b84670df9..ba57d7d91 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -2948,6 +2948,11 @@  static int wpa_cli_cmd_twt_setup(struct wpa_ctrl *ctrl, int argc,
 	return wpa_cli_cmd(ctrl, "TWT_SETUP", 0, argc, argv);
 }
 
+static int wpa_cli_cmd_twt_teardown(struct wpa_ctrl *ctrl, int argc,
+				    char *argv[])
+{
+	return wpa_cli_cmd(ctrl, "TWT_TEARDOWN", 0, argc, argv);
+}
 
 static int wpa_cli_cmd_erp_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
 {
@@ -3832,6 +3837,10 @@  static const struct wpa_cli_cmd wpa_cli_commands[] = {
 	  wpa_cli_cmd_twt_setup, NULL, cli_cmd_flag_none,
 	  "[dialog=<token>] [exponent=<exponent>] [mantissa=<mantissa>]"
 	},
+	{ "twt_teardown",
+	  wpa_cli_cmd_twt_teardown, NULL, cli_cmd_flag_none,
+	  "[flags=<value>]"
+	},
 	{ "erp_flush", wpa_cli_cmd_erp_flush, NULL, cli_cmd_flag_none,
 	  "= flush ERP keys" },
 	{ "mac_rand_scan",
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 705352c17..0271c5e24 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1560,6 +1560,8 @@  int wpas_get_op_chan_phy(int freq, const u8 *ies, size_t ies_len,
 
 int wpas_twt_send_setup(struct wpa_supplicant *wpa_s,
 			int dtok, int exponent, int mantissa, int min_twt);
+int wpas_twt_send_teardown(struct wpa_supplicant *wpa_s,
+			   int flags);
 
 void wpas_rrm_reset(struct wpa_supplicant *wpa_s);
 void wpas_rrm_process_neighbor_rep(struct wpa_supplicant *wpa_s,