1 /* 2 * wpa_supplicant - TWT 3 * Copyright (c) 2003-2016, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include "includes.h" 10 11 #include "utils/common.h" 12 #include "wpa_supplicant_i.h" 13 #include "driver_i.h" 14 15 16 #ifdef CONFIG_TESTING_OPTIONS 17 18 /** 19 * wpas_twt_send_setup - Send TWT Setup frame (Request) to our AP 20 * @wpa_s: Pointer to wpa_supplicant 21 * @dtok: Dialog token 22 * @exponent: Wake-interval exponent 23 * @mantissa: Wake-interval mantissa 24 * @min_twt: Minimum TWT wake duration in units of 256 usec 25 * @setup_cmd: 0 == request, 1 == suggest, etc. Table 9-297 26 * Returns: 0 in case of success, negative error code otherwise 27 * 28 */ 29 int wpas_twt_send_setup(struct wpa_supplicant *wpa_s, u8 dtok, int exponent, 30 int mantissa, u8 min_twt, int setup_cmd, u64 twt, 31 bool requestor, bool trigger, bool implicit, 32 bool flow_type, u8 flow_id, bool protection, 33 u8 twt_channel, u8 control) 34 { 35 struct wpabuf *buf; 36 u16 req_type = 0; 37 int ret = 0; 38 39 if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid) { 40 wpa_printf(MSG_DEBUG, 41 "TWT: No connection - cannot send TWT Setup frame"); 42 return -ENOTCONN; 43 } 44 45 /* 3 = Action category + Action code + Dialog token */ 46 /* 17 = TWT element */ 47 buf = wpabuf_alloc(3 + 17); 48 if (!buf) { 49 wpa_printf(MSG_DEBUG, 50 "TWT: Failed to allocate TWT Setup frame (Request)"); 51 return -ENOMEM; 52 } 53 54 wpa_printf(MSG_DEBUG, 55 "TWT: Setup request, dtok: %d exponent: %d mantissa: %d min-twt: %d", 56 dtok, exponent, mantissa, min_twt); 57 58 wpabuf_put_u8(buf, WLAN_ACTION_S1G); 59 wpabuf_put_u8(buf, S1G_ACT_TWT_SETUP); 60 wpabuf_put_u8(buf, dtok); 61 62 wpabuf_put_u8(buf, WLAN_EID_TWT); 63 wpabuf_put_u8(buf, 15); /* len */ 64 65 wpabuf_put_u8(buf, control); 66 67 if (requestor) 68 req_type |= BIT(0); /* This STA is a TWT Requesting STA */ 69 /* TWT Setup Command field */ 70 req_type |= (setup_cmd & 0x7) << 1; 71 if (trigger) 72 req_type |= BIT(4); /* TWT SP includes trigger frames */ 73 if (implicit) 74 req_type |= BIT(5); /* Implicit TWT */ 75 if (flow_type) 76 req_type |= BIT(6); /* Flow Type: Unannounced TWT */ 77 req_type |= (flow_id & 0x7) << 7; 78 req_type |= (exponent & 0x1f) << 10; /* TWT Wake Interval Exponent */ 79 if (protection) 80 req_type |= BIT(15); 81 wpabuf_put_le16(buf, req_type); 82 wpabuf_put_le64(buf, twt); 83 wpabuf_put_u8(buf, min_twt); /* Nominal Minimum TWT Wake Duration */ 84 wpabuf_put_le16(buf, mantissa); /* TWT Wake Interval Mantissa */ 85 wpabuf_put_u8(buf, twt_channel); /* TWT Channel */ 86 87 if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid, 88 wpa_s->own_addr, wpa_s->bssid, 89 wpabuf_head(buf), wpabuf_len(buf), 0) < 0) { 90 wpa_printf(MSG_DEBUG, "TWT: Failed to send TWT Setup Request"); 91 ret = -ECANCELED; 92 } 93 94 wpabuf_free(buf); 95 return ret; 96 } 97 98 99 /** 100 * wpas_twt_send_teardown - Send TWT teardown request to our AP 101 * @wpa_s: Pointer to wpa_supplicant 102 * @flags: The byte that goes inside the TWT Teardown element 103 * Returns: 0 in case of success, negative error code otherwise 104 * 105 */ 106 int wpas_twt_send_teardown(struct wpa_supplicant *wpa_s, u8 flags) 107 { 108 struct wpabuf *buf; 109 int ret = 0; 110 111 if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid) { 112 wpa_printf(MSG_DEBUG, 113 "TWT: No connection - cannot send TWT Teardown frame"); 114 return -ENOTCONN; 115 } 116 117 /* 3 = Action category + Action code + flags */ 118 buf = wpabuf_alloc(3); 119 if (!buf) { 120 wpa_printf(MSG_DEBUG, 121 "TWT: Failed to allocate TWT Teardown frame"); 122 return -ENOMEM; 123 } 124 125 wpa_printf(MSG_DEBUG, "TWT: Teardown request, flags: 0x%x", flags); 126 127 wpabuf_put_u8(buf, WLAN_ACTION_S1G); 128 wpabuf_put_u8(buf, S1G_ACT_TWT_TEARDOWN); 129 wpabuf_put_u8(buf, flags); 130 131 if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid, 132 wpa_s->own_addr, wpa_s->bssid, 133 wpabuf_head(buf), wpabuf_len(buf), 0) < 0) { 134 wpa_printf(MSG_DEBUG, "TWT: Failed to send TWT Teardown frame"); 135 ret = -ECANCELED; 136 } 137 138 wpabuf_free(buf); 139 return ret; 140 } 141 142 #endif /* CONFIG_TESTING_OPTIONS */ 143