From: Ben Greear <greearb@xxxxxxxxxxxxxxx> User can supply the 1-byte flags value. Signed-off-by: Ben Greear <greearb@xxxxxxxxxxxxxxx> --- 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 --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, -- 2.20.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap