@@ -10116,6 +10116,15 @@ static int wpas_ctrl_iface_send_twt_setup(struct wpa_supplicant *wpa_s,
int exponent = 10;
int mantissa = 8192;
int min_twt = 255;
+ unsigned long long twt = 0;
+ int requestor = 1;
+ int setup_cmd = 0;
+ int trigger = 1;
+ int implicit = 1;
+ int flow_type = 1;
+ int flow_id = 0;
+ int protection = 0;
+ int twt_channel = 0;
char* tok_s = os_strstr(cmd, "dialog=");
if (tok_s)
@@ -10129,7 +10138,45 @@ static int wpas_ctrl_iface_send_twt_setup(struct wpa_supplicant *wpa_s,
if (tok_s)
exponent = atoi(tok_s + strlen("mantissa="));
- ret = wpas_twt_send_setup(wpa_s, dtok, exponent, mantissa, min_twt);
+ tok_s = os_strstr(cmd, "setup_cmd=");
+ if (tok_s)
+ setup_cmd = atoi(tok_s + strlen("setup_cmd="));
+
+ tok_s = os_strstr(cmd, "twt=");
+ if (tok_s)
+ sscanf(tok_s + strlen("twt="), "%llu", &twt);
+
+ tok_s = os_strstr(cmd, "requestor=");
+ if (tok_s)
+ requestor = atoi(tok_s + strlen("requestor="));
+
+ tok_s = os_strstr(cmd, "trigger=");
+ if (tok_s)
+ trigger = atoi(tok_s + strlen("trigger="));
+
+ tok_s = os_strstr(cmd, "implicit=");
+ if (tok_s)
+ implicit = atoi(tok_s + strlen("implicit="));
+
+ tok_s = os_strstr(cmd, "flow_type=");
+ if (tok_s)
+ flow_type = atoi(tok_s + strlen("flow_type="));
+
+ tok_s = os_strstr(cmd, "flow_id=");
+ if (tok_s)
+ flow_id = atoi(tok_s + strlen("flow_id="));
+
+ tok_s = os_strstr(cmd, "protection=");
+ if (tok_s)
+ protection = atoi(tok_s + strlen("protection="));
+
+ tok_s = os_strstr(cmd, "twt_channel=");
+ if (tok_s)
+ twt_channel = atoi(tok_s + strlen("twt_channel="));
+
+ ret = wpas_twt_send_setup(wpa_s, dtok, exponent, mantissa, min_twt, setup_cmd,
+ twt, requestor, trigger, implicit, flow_type, flow_id,
+ protection, twt_channel);
return ret;
}
@@ -25,15 +25,18 @@
* @exponent: TWT wake-interval exponent
* @mantissa: TWT wake-interval Mantissa
* @min_twt: TWT Minimum TWT Wake Duration.
+ * @setup_cmd: 0 == request, 1 == suggest, etc. table 9-297
* 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)
+ int dtok, int exponent, int mantissa, int min_twt, int setup_cmd,
+ u64 twt, int requestor, int trigger, int implicit, int flow_type, int flow_id,
+ int protection, int twt_channel)
{
struct wpabuf *buf;
u16 req_type = 0;
- unsigned char targ_wait_time[8] = {0};
+ int i;
if (wpa_s->wpa_state != WPA_COMPLETED || wpa_s->current_ssid == NULL) {
wpa_dbg(wpa_s, MSG_DEBUG, "TWT: No connection, no TWT.");
@@ -43,7 +46,7 @@ int wpas_twt_send_setup(struct wpa_supplicant *wpa_s,
/* 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");
@@ -63,18 +66,25 @@ int wpas_twt_send_setup(struct wpa_supplicant *wpa_s,
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 |= (requestor & 0x1); /* This STA is a TWT Requesting STA */
+ req_type |= (setup_cmd & 0x7) << 1;
+ req_type |= (trigger & 0x1) << 4;
+ req_type |= (implicit & 0x1) << 5;
+ req_type |= (flow_type & 0x1) << 6;
+ req_type |= (flow_id & 0x7) << 7;
req_type |= ((exponent & 0x1f) << 10);
- /* high bit is 'protection, leave it false for now */
+ req_type |= (protection & 0x1) << 15;
+
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));
+
+ for (i = 0; i<8; i++) {
+ wpabuf_put_u8(buf, twt >> i);
+ }
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 */
+ wpabuf_put_u8(buf, twt_channel); /* twt channel */
if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
wpa_s->own_addr, wpa_s->bssid,
@@ -3835,7 +3835,7 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = {
},
{ "twt_setup",
wpa_cli_cmd_twt_setup, NULL, cli_cmd_flag_none,
- "[dialog=<token>] [exponent=<exponent>] [mantissa=<mantissa>]"
+ "[dialog=<token>] [exponent=<exponent>] [mantissa=<mantissa>] [setup_cmd=<setup-cmd>] [twt=<u64>] [requestor=0|1] [trigger=0|1] [implicit=0|1] [flow_type=0|1] [flow_id=<3-bit-id>] [protection=0|1] [twt_channel=<twt chanel id>]"
},
{ "twt_teardown",
wpa_cli_cmd_twt_teardown, NULL, cli_cmd_flag_none,
@@ -1559,7 +1559,9 @@ 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);
+ int dtok, int exponent, int mantissa, int min_twt, int setup_cmd,
+ u64 twt, int requestor, int trigger, int implicit, int flow_type, int flow_id,
+ int protection, int channel);
int wpas_twt_send_teardown(struct wpa_supplicant *wpa_s,
int flags);