From: Ben Greear <greearb@xxxxxxxxxxxxxxx> With ability to specify some options. Signed-off-by: Ben Greear <greearb@xxxxxxxxxxxxxxx> --- src/common/ieee802_11_defs.h | 15 ++++++ wpa_supplicant/Makefile | 1 + wpa_supplicant/ctrl_iface.c | 29 ++++++++++ wpa_supplicant/twt.c | 90 +++++++++++++++++++++++++++++++ wpa_supplicant/wpa_cli.c | 10 ++++ wpa_supplicant/wpa_supplicant_i.h | 4 ++ 6 files changed, 149 insertions(+) create mode 100644 wpa_supplicant/twt.c diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index b8dee8dbf..c67c6f46c 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -446,6 +446,7 @@ #define WLAN_EID_WHITE_SPACE_MAP 205 #define WLAN_EID_FTM_PARAMETERS 206 #define WLAN_EID_S1G_BCN_COMPAT 213 +#define WLAN_EID_TWT 216 #define WLAN_EID_S1G_CAPABILITIES 217 #define WLAN_EID_VENDOR_SPECIFIC 221 #define WLAN_EID_S1G_OPERATION 232 @@ -603,6 +604,7 @@ #define WLAN_ACTION_ROBUST_AV_STREAMING 19 #define WLAN_ACTION_UNPROTECTED_DMG 20 #define WLAN_ACTION_VHT 21 +#define WLAN_ACTION_S1G 22 #define WLAN_ACTION_FILS 26 #define WLAN_ACTION_PROTECTED_FTM 34 #define WLAN_ACTION_VENDOR_SPECIFIC_PROTECTED 126 @@ -820,6 +822,19 @@ enum nai_realm_eap_cred_type { NAI_REALM_CRED_TYPE_VENDOR_SPECIFIC = 10 }; +#define S1G_ACT_AID_SWITCH_REQUEST 0 +#define S1G_ACT_AID_SWITCH_RESPONSE 1 +#define S1G_ACT_SYNC_CONTROL 2 +#define S1G_ACT_STA_INFO_ANNOUNCE 3 +#define S1G_ACT_EDCA_PARAM_SET 4 +#define S1G_ACT_EL_OPERATION 5 +#define S1G_ACT_TWT_SETUP 6 +#define S1G_ACT_TWT_TEARDOWN 7 +#define S1G_ACT_SECT_GROUP_ID_LIST 8 +#define S1G_ACT_SECT_ID_FEEDBACK 9 +#define S1G_ACT_RESERVED 10 +#define S1G_ACT_TWT_INFORMATION 11 + /* * IEEE P802.11-REVmc/D5.0 Table 9-81 - Measurement type definitions for * measurement requests diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile index fb665b160..77baa1bb5 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -95,6 +95,7 @@ OBJS += ../src/utils/ip_addr.o OBJS += ../src/utils/crc32.o OBJS += op_classes.o OBJS += rrm.o +OBJS += twt.o OBJS += robust_av.o OBJS_p = wpa_passphrase.o OBJS_p += ../src/utils/common.o diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index d679b56af..1a1c2ca82 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -10108,6 +10108,32 @@ static int wpas_ctrl_iface_send_neighbor_rep(struct wpa_supplicant *wpa_s, return ret; } +static int wpas_ctrl_iface_send_twt_setup(struct wpa_supplicant *wpa_s, + char *cmd) +{ + int ret; + int dtok = 1; + int exponent = 10; + int mantissa = 8192; + int min_twt = 255; + + char* tok_s = os_strstr(cmd, "dialog="); + if (tok_s) + dtok = atoi(tok_s + strlen("dialog=")); + + tok_s = os_strstr(cmd, "exponent="); + if (tok_s) + exponent = atoi(tok_s + strlen("exponent=")); + + tok_s = os_strstr(cmd, "mantissa="); + if (tok_s) + exponent = atoi(tok_s + strlen("mantissa=")); + + ret = wpas_twt_send_setup(wpa_s, dtok, exponent, mantissa, min_twt); + + return ret; +} + static int wpas_ctrl_iface_erp_flush(struct wpa_supplicant *wpa_s) { @@ -11330,6 +11356,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, } else if (os_strncmp(buf, "NEIGHBOR_REP_REQUEST", 20) == 0) { if (wpas_ctrl_iface_send_neighbor_rep(wpa_s, buf + 20)) reply_len = -1; + } 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_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 new file mode 100644 index 000000000..6b62631b7 --- /dev/null +++ b/wpa_supplicant/twt.c @@ -0,0 +1,90 @@ +/* + * wpa_supplicant - TWT + * Copyright (c) 2003-2016, Jouni Malinen <j@xxxxx> + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "includes.h" + +#include "utils/common.h" +#include "utils/eloop.h" +#include "common/ieee802_11_common.h" +#include "wpa_supplicant_i.h" +#include "driver_i.h" +#include "bss.h" +#include "scan.h" +#include "p2p_supplicant.h" + + +/** + * wpas_twt_send_setup - Send TWT setup request to our AP + * @wpa_s: Pointer to wpa_supplicant + * @dtok: Dialog token. + * @exponent: TWT wake-interval exponent + * @mantissa: TWT wake-interval Mantissa + * @min_twt: TWT Minimum TWT Wake Duration. + * Returns: 0 in case of success, negative error code otherwise + * + */ +int wpas_twt_send_setup(struct wpa_supplicant *wpa_s, + int dtok, int exponent, int mantissa, int min_twt) +{ + struct wpabuf *buf; + u16 req_type = 0; + unsigned char targ_wait_time[8] = {0}; + + 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 + dialog token */ + /* 17 = target wait time IE */ + buf = wpabuf_alloc(3 + 17); + + if (buf == NULL) { + wpa_dbg(wpa_s, MSG_DEBUG, + "TWT: Failed to allocate TWT Setup Request"); + return -ENOMEM; + } + + wpa_dbg(wpa_s, MSG_DEBUG, + "TWT: Setup request, dtok: %d exponent: %d mantissa: %d min-twt: %d", + dtok, exponent, mantissa, min_twt); + + wpabuf_put_u8(buf, WLAN_ACTION_S1G); + wpabuf_put_u8(buf, S1G_ACT_TWT_SETUP); + wpabuf_put_u8(buf, dtok); + + wpabuf_put_u8(buf, WLAN_EID_TWT); + wpabuf_put_u8(buf, 15); /* len */ + + wpabuf_put_u8(buf, 0x10); /* control field */ + + req_type |= (0x1); /* This STA is a TWT Requesting STA */ + req_type |= (0x70); /* TWT SP includes trigger frames, TWT Implicit, TWT un-announced */ + req_type |= ((exponent & 0x1f) << 10); + /* high bit is 'protection, leave it false for now */ + wpabuf_put_u8(buf, req_type); + wpabuf_put_u8(buf, req_type >> 8); + /* Not sure exactly how this is used */ + wpabuf_put_data(buf, targ_wait_time, sizeof(targ_wait_time)); + wpabuf_put_u8(buf, min_twt); /* minimum twt wake duration */ + wpabuf_put_u8(buf, mantissa); + wpabuf_put_u8(buf, mantissa >> 8); + wpabuf_put_u8(buf, 0); /* twt channel */ + + 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 Setup 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 b3e256b0f..b84670df9 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -2942,6 +2942,12 @@ static int wpa_cli_cmd_neighbor_rep_request(struct wpa_ctrl *ctrl, int argc, return wpa_cli_cmd(ctrl, "NEIGHBOR_REP_REQUEST", 0, argc, argv); } +static int wpa_cli_cmd_twt_setup(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "TWT_SETUP", 0, argc, argv); +} + static int wpa_cli_cmd_erp_flush(struct wpa_ctrl *ctrl, int argc, char *argv[]) { @@ -3822,6 +3828,10 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = { wpa_cli_cmd_neighbor_rep_request, NULL, cli_cmd_flag_none, "[ssid=<SSID>] [lci] [civic] = Trigger request to AP for neighboring AP report (with optional given SSID in hex or enclosed in double quotes, default: current SSID; with optional LCI and location civic request)" }, + { "twt_setup", + wpa_cli_cmd_twt_setup, NULL, cli_cmd_flag_none, + "[dialog=<token>] [exponent=<exponent>] [mantissa=<mantissa>]" + }, { "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 dfd8c61eb..705352c17 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1557,6 +1557,10 @@ void add_freq(int *freqs, int *num_freqs, int freq); int wpas_get_op_chan_phy(int freq, const u8 *ies, size_t ies_len, u8 *op_class, u8 *chan, u8 *phy_type); + +int wpas_twt_send_setup(struct wpa_supplicant *wpa_s, + int dtok, int exponent, int mantissa, int min_twt); + 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); -- 2.20.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap