blob: 9fe21eb83bdcd44f22ced5fd4a8c025b4b3e2b80 [file] [log] [blame]
Mark De Ruyter1a7ae572018-03-02 15:35:36 -08001#!/usr/bin/env python3
Ang Li73697b32015-12-03 00:41:53 +00002#
tturney1bdf77d2015-12-28 17:46:13 -08003# Copyright 2016 Google, Inc.
Ang Li73697b32015-12-03 00:41:53 +00004#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
Ang Li5bd83f32016-05-23 14:39:38 -070017import logging
Girish Moturucf4dccd2018-08-27 12:22:00 -070018import os
James Mattis5a5dd492020-05-14 13:09:43 -070019import re
xianyuanjia0431ba32018-12-14 09:56:42 -080020import shutil
Girish Moturucf4dccd2018-08-27 12:22:00 -070021import time
Ang Li73697b32015-12-03 00:41:53 +000022
David Sue4cd9c22019-03-26 18:07:26 -070023from collections import namedtuple
Ang Li73697b32015-12-03 00:41:53 +000024from enum import IntEnum
25from queue import Empty
26
Ang Li82522812016-06-02 13:57:21 -070027from acts import asserts
Xianyuan Jia0e39e552019-01-24 17:17:47 -080028from acts import context
Ang Li374d7602016-02-08 17:27:27 -080029from acts import signals
Ang Lifee28402016-07-13 13:43:29 -070030from acts import utils
Ang Li2d3fe982016-06-08 10:00:43 -070031from acts.controllers import attenuator
Bindu Mahadev7e5dc682019-02-01 16:53:34 -080032from acts.controllers.ap_lib import hostapd_security
33from acts.controllers.ap_lib import hostapd_ap_preset
Girish Moturucf4dccd2018-08-27 12:22:00 -070034from acts.controllers.ap_lib.hostapd_constants import BAND_2G
35from acts.controllers.ap_lib.hostapd_constants import BAND_5G
Bindu Mahadev4e710362016-11-17 16:17:11 -080036from acts.test_utils.wifi import wifi_constants
Rebecca Silberstein8c422e62016-07-19 15:04:46 -070037from acts.test_utils.tel import tel_defines
Ang Li73697b32015-12-03 00:41:53 +000038
Bindu Mahadev1d3991e2017-03-20 18:06:54 -070039# Default timeout used for reboot, toggle WiFi and Airplane mode,
40# for the system to settle down after the operation.
41DEFAULT_TIMEOUT = 10
Ang Li73697b32015-12-03 00:41:53 +000042# Number of seconds to wait for events that are supposed to happen quickly.
43# Like onSuccess for start background scan and confirmation on wifi state
44# change.
45SHORT_TIMEOUT = 30
Bindu Mahadev7060a9f2018-05-04 13:48:12 -070046ROAMING_TIMEOUT = 30
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -080047WIFI_CONNECTION_TIMEOUT_DEFAULT = 30
Ang Li73697b32015-12-03 00:41:53 +000048# Speed of light in m/s.
49SPEED_OF_LIGHT = 299792458
50
Qi Jiang8b443672018-03-16 14:46:50 -070051DEFAULT_PING_ADDR = "https://www.google.com/robots.txt"
Ang Li73697b32015-12-03 00:41:53 +000052
Girish Moturuddc0d382020-08-24 12:08:41 -070053CNSS_DIAG_CONFIG_PATH = "/data/vendor/wifi/cnss_diag/"
54CNSS_DIAG_CONFIG_FILE = "cnss_diag.conf"
55
Girish Moturu36348a32019-12-10 08:41:54 -080056ROAMING_ATTN = {
Bindu Mahadev7060a9f2018-05-04 13:48:12 -070057 "AP1_on_AP2_off": [
58 0,
59 0,
Girish Moturu8adc02f2020-07-08 16:01:29 -070060 95,
61 95
Bindu Mahadev7060a9f2018-05-04 13:48:12 -070062 ],
63 "AP1_off_AP2_on": [
Girish Moturu8adc02f2020-07-08 16:01:29 -070064 95,
65 95,
Bindu Mahadev7060a9f2018-05-04 13:48:12 -070066 0,
67 0
68 ],
69 "default": [
70 0,
71 0,
72 0,
73 0
74 ]
75 }
Ang Li82522812016-06-02 13:57:21 -070076
Xianyuan Jia0e39e552019-01-24 17:17:47 -080077
Ang Li73697b32015-12-03 00:41:53 +000078class WifiEnums():
79
leslce9cf6d2020-02-19 16:37:07 +080080 SSID_KEY = "SSID" # Used for Wifi & SoftAp
Roshan Piusc999e5e2018-11-09 10:59:52 -080081 SSID_PATTERN_KEY = "ssidPattern"
Bindu Mahadev4c94b532019-01-09 12:20:10 -080082 NETID_KEY = "network_id"
leslce9cf6d2020-02-19 16:37:07 +080083 BSSID_KEY = "BSSID" # Used for Wifi & SoftAp
Roshan Piusc999e5e2018-11-09 10:59:52 -080084 BSSID_PATTERN_KEY = "bssidPattern"
leslce9cf6d2020-02-19 16:37:07 +080085 PWD_KEY = "password" # Used for Wifi & SoftAp
Ang Li73697b32015-12-03 00:41:53 +000086 frequency_key = "frequency"
lesl6d30a172020-03-05 15:05:22 +080087 HIDDEN_KEY = "hiddenSSID" # Used for Wifi & SoftAp
Roshan Piusd1204442018-11-12 12:20:39 -080088 IS_APP_INTERACTION_REQUIRED = "isAppInteractionRequired"
89 IS_USER_INTERACTION_REQUIRED = "isUserInteractionRequired"
Roshan Pius55fb7c42020-04-03 14:47:18 -070090 IS_SUGGESTION_METERED = "isMetered"
Roshan Piusd1204442018-11-12 12:20:39 -080091 PRIORITY = "priority"
leslce9cf6d2020-02-19 16:37:07 +080092 SECURITY = "security" # Used for Wifi & SoftAp
Ang Li73697b32015-12-03 00:41:53 +000093
leslce9cf6d2020-02-19 16:37:07 +080094 # Used for SoftAp
lesl6d30a172020-03-05 15:05:22 +080095 AP_BAND_KEY = "apBand"
96 AP_CHANNEL_KEY = "apChannel"
97 AP_MAXCLIENTS_KEY = "MaxNumberOfClients"
98 AP_SHUTDOWNTIMEOUT_KEY = "ShutdownTimeoutMillis"
99 AP_SHUTDOWNTIMEOUTENABLE_KEY = "AutoShutdownEnabled"
100 AP_CLIENTCONTROL_KEY = "ClientControlByUserEnabled"
101 AP_ALLOWEDLIST_KEY = "AllowedClientList"
102 AP_BLOCKEDLIST_KEY = "BlockedClientList"
103
leslce9cf6d2020-02-19 16:37:07 +0800104 WIFI_CONFIG_SOFTAP_BAND_2G = 1
105 WIFI_CONFIG_SOFTAP_BAND_5G = 2
106 WIFI_CONFIG_SOFTAP_BAND_2G_5G = 3
107 WIFI_CONFIG_SOFTAP_BAND_6G = 4
108 WIFI_CONFIG_SOFTAP_BAND_2G_6G = 5
109 WIFI_CONFIG_SOFTAP_BAND_5G_6G = 6
110 WIFI_CONFIG_SOFTAP_BAND_ANY = 7
111
112 # DO NOT USE IT for new test case! Replaced by WIFI_CONFIG_SOFTAP_BAND_
113 WIFI_CONFIG_APBAND_2G = WIFI_CONFIG_SOFTAP_BAND_2G
114 WIFI_CONFIG_APBAND_5G = WIFI_CONFIG_SOFTAP_BAND_5G
115 WIFI_CONFIG_APBAND_AUTO = WIFI_CONFIG_SOFTAP_BAND_2G_5G
116
117 WIFI_CONFIG_APBAND_2G_OLD = 0
118 WIFI_CONFIG_APBAND_5G_OLD = 1
119 WIFI_CONFIG_APBAND_AUTO_OLD = -1
Ang Li73697b32015-12-03 00:41:53 +0000120
Ang Li82522812016-06-02 13:57:21 -0700121 WIFI_WPS_INFO_PBC = 0
122 WIFI_WPS_INFO_DISPLAY = 1
123 WIFI_WPS_INFO_KEYPAD = 2
124 WIFI_WPS_INFO_LABEL = 3
125 WIFI_WPS_INFO_INVALID = 4
Ang Li73697b32015-12-03 00:41:53 +0000126
lesl6d30a172020-03-05 15:05:22 +0800127 class SoftApSecurityType():
128 OPEN = "NONE"
129 WPA2 = "WPA2_PSK"
130 WPA3_SAE_TRANSITION = "WPA3_SAE_TRANSITION"
131 WPA3_SAE = "WPA3_SAE"
132
Ang Li73697b32015-12-03 00:41:53 +0000133 class CountryCode():
134 CHINA = "CN"
Girish Moturua5ef35d2020-10-19 14:58:01 -0700135 GERMANY = "DE"
Ang Li73697b32015-12-03 00:41:53 +0000136 JAPAN = "JP"
137 UK = "GB"
138 US = "US"
139 UNKNOWN = "UNKNOWN"
140
141 # Start of Macros for EAP
142 # EAP types
143 class Eap(IntEnum):
144 NONE = -1
145 PEAP = 0
Ang Li82522812016-06-02 13:57:21 -0700146 TLS = 1
Ang Li73697b32015-12-03 00:41:53 +0000147 TTLS = 2
Ang Li82522812016-06-02 13:57:21 -0700148 PWD = 3
149 SIM = 4
150 AKA = 5
151 AKA_PRIME = 6
152 UNAUTH_TLS = 7
Ang Li73697b32015-12-03 00:41:53 +0000153
154 # EAP Phase2 types
155 class EapPhase2(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700156 NONE = 0
157 PAP = 1
158 MSCHAP = 2
159 MSCHAPV2 = 3
160 GTC = 4
Ang Li73697b32015-12-03 00:41:53 +0000161
162 class Enterprise:
Ang Li82522812016-06-02 13:57:21 -0700163 # Enterprise Config Macros
164 EMPTY_VALUE = "NULL"
165 EAP = "eap"
166 PHASE2 = "phase2"
167 IDENTITY = "identity"
168 ANON_IDENTITY = "anonymous_identity"
169 PASSWORD = "password"
170 SUBJECT_MATCH = "subject_match"
Ang Li73697b32015-12-03 00:41:53 +0000171 ALTSUBJECT_MATCH = "altsubject_match"
172 DOM_SUFFIX_MATCH = "domain_suffix_match"
Ang Li82522812016-06-02 13:57:21 -0700173 CLIENT_CERT = "client_cert"
174 CA_CERT = "ca_cert"
175 ENGINE = "engine"
176 ENGINE_ID = "engine_id"
177 PRIVATE_KEY_ID = "key_id"
178 REALM = "realm"
179 PLMN = "plmn"
180 FQDN = "FQDN"
181 FRIENDLY_NAME = "providerFriendlyName"
182 ROAMING_IDS = "roamingConsortiumIds"
Jimmy Chen7baec622020-06-23 19:00:33 +0800183 OCSP = "ocsp"
Ang Li73697b32015-12-03 00:41:53 +0000184 # End of Macros for EAP
185
186 # Macros for wifi p2p.
187 WIFI_P2P_SERVICE_TYPE_ALL = 0
188 WIFI_P2P_SERVICE_TYPE_BONJOUR = 1
189 WIFI_P2P_SERVICE_TYPE_UPNP = 2
190 WIFI_P2P_SERVICE_TYPE_VENDOR_SPECIFIC = 255
191
192 class ScanResult:
193 CHANNEL_WIDTH_20MHZ = 0
194 CHANNEL_WIDTH_40MHZ = 1
195 CHANNEL_WIDTH_80MHZ = 2
196 CHANNEL_WIDTH_160MHZ = 3
197 CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4
198
199 # Macros for wifi rtt.
200 class RttType(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700201 TYPE_ONE_SIDED = 1
202 TYPE_TWO_SIDED = 2
Ang Li73697b32015-12-03 00:41:53 +0000203
204 class RttPeerType(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700205 PEER_TYPE_AP = 1
206 PEER_TYPE_STA = 2 # Requires NAN.
207 PEER_P2P_GO = 3
208 PEER_P2P_CLIENT = 4
209 PEER_NAN = 5
Ang Li73697b32015-12-03 00:41:53 +0000210
211 class RttPreamble(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700212 PREAMBLE_LEGACY = 0x01
213 PREAMBLE_HT = 0x02
214 PREAMBLE_VHT = 0x04
Ang Li73697b32015-12-03 00:41:53 +0000215
216 class RttBW(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700217 BW_5_SUPPORT = 0x01
218 BW_10_SUPPORT = 0x02
219 BW_20_SUPPORT = 0x04
220 BW_40_SUPPORT = 0x08
221 BW_80_SUPPORT = 0x10
Ang Li73697b32015-12-03 00:41:53 +0000222 BW_160_SUPPORT = 0x20
223
224 class Rtt(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700225 STATUS_SUCCESS = 0
226 STATUS_FAILURE = 1
227 STATUS_FAIL_NO_RSP = 2
228 STATUS_FAIL_REJECTED = 3
229 STATUS_FAIL_NOT_SCHEDULED_YET = 4
230 STATUS_FAIL_TM_TIMEOUT = 5
231 STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6
232 STATUS_FAIL_NO_CAPABILITY = 7
233 STATUS_ABORTED = 8
234 STATUS_FAIL_INVALID_TS = 9
235 STATUS_FAIL_PROTOCOL = 10
236 STATUS_FAIL_SCHEDULE = 11
237 STATUS_FAIL_BUSY_TRY_LATER = 12
238 STATUS_INVALID_REQ = 13
239 STATUS_NO_WIFI = 14
240 STATUS_FAIL_FTM_PARAM_OVERRIDE = 15
Ang Li73697b32015-12-03 00:41:53 +0000241
Ang Li82522812016-06-02 13:57:21 -0700242 REASON_UNSPECIFIED = -1
243 REASON_NOT_AVAILABLE = -2
244 REASON_INVALID_LISTENER = -3
245 REASON_INVALID_REQUEST = -4
Ang Li73697b32015-12-03 00:41:53 +0000246
247 class RttParam:
248 device_type = "deviceType"
249 request_type = "requestType"
250 BSSID = "bssid"
251 channel_width = "channelWidth"
252 frequency = "frequency"
253 center_freq0 = "centerFreq0"
254 center_freq1 = "centerFreq1"
255 number_burst = "numberBurst"
256 interval = "interval"
257 num_samples_per_burst = "numSamplesPerBurst"
258 num_retries_per_measurement_frame = "numRetriesPerMeasurementFrame"
259 num_retries_per_FTMR = "numRetriesPerFTMR"
260 lci_request = "LCIRequest"
261 lcr_request = "LCRRequest"
262 burst_timeout = "burstTimeout"
263 preamble = "preamble"
264 bandwidth = "bandwidth"
265 margin = "margin"
266
267 RTT_MARGIN_OF_ERROR = {
268 RttBW.BW_80_SUPPORT: 2,
269 RttBW.BW_40_SUPPORT: 5,
270 RttBW.BW_20_SUPPORT: 5
271 }
272
273 # Macros as specified in the WifiScanner code.
Ang Li82522812016-06-02 13:57:21 -0700274 WIFI_BAND_UNSPECIFIED = 0 # not specified
275 WIFI_BAND_24_GHZ = 1 # 2.4 GHz band
276 WIFI_BAND_5_GHZ = 2 # 5 GHz band without DFS channels
277 WIFI_BAND_5_GHZ_DFS_ONLY = 4 # 5 GHz band with DFS channels
278 WIFI_BAND_5_GHZ_WITH_DFS = 6 # 5 GHz band with DFS channels
279 WIFI_BAND_BOTH = 3 # both bands without DFS channels
280 WIFI_BAND_BOTH_WITH_DFS = 7 # both bands with DFS channels
Ang Li73697b32015-12-03 00:41:53 +0000281
282 REPORT_EVENT_AFTER_BUFFER_FULL = 0
283 REPORT_EVENT_AFTER_EACH_SCAN = 1
284 REPORT_EVENT_FULL_SCAN_RESULT = 2
285
xshuaabcfeb2018-02-14 11:43:24 -0800286 SCAN_TYPE_LOW_LATENCY = 0
287 SCAN_TYPE_LOW_POWER = 1
288 SCAN_TYPE_HIGH_ACCURACY = 2
289
Ang Li73697b32015-12-03 00:41:53 +0000290 # US Wifi frequencies
291 ALL_2G_FREQUENCIES = [2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452,
292 2457, 2462]
293 DFS_5G_FREQUENCIES = [5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580,
294 5600, 5620, 5640, 5660, 5680, 5700, 5720]
295 NONE_DFS_5G_FREQUENCIES = [5180, 5200, 5220, 5240, 5745, 5765, 5785, 5805,
296 5825]
297 ALL_5G_FREQUENCIES = DFS_5G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES
298
299 band_to_frequencies = {
Ang Li82522812016-06-02 13:57:21 -0700300 WIFI_BAND_24_GHZ: ALL_2G_FREQUENCIES,
301 WIFI_BAND_5_GHZ: NONE_DFS_5G_FREQUENCIES,
302 WIFI_BAND_5_GHZ_DFS_ONLY: DFS_5G_FREQUENCIES,
303 WIFI_BAND_5_GHZ_WITH_DFS: ALL_5G_FREQUENCIES,
304 WIFI_BAND_BOTH: ALL_2G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES,
305 WIFI_BAND_BOTH_WITH_DFS: ALL_5G_FREQUENCIES + ALL_2G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000306 }
307
308 # All Wifi frequencies to channels lookup.
309 freq_to_channel = {
310 2412: 1,
311 2417: 2,
312 2422: 3,
313 2427: 4,
314 2432: 5,
315 2437: 6,
316 2442: 7,
317 2447: 8,
318 2452: 9,
319 2457: 10,
320 2462: 11,
321 2467: 12,
322 2472: 13,
323 2484: 14,
324 4915: 183,
325 4920: 184,
326 4925: 185,
327 4935: 187,
328 4940: 188,
329 4945: 189,
330 4960: 192,
331 4980: 196,
332 5035: 7,
333 5040: 8,
334 5045: 9,
335 5055: 11,
336 5060: 12,
337 5080: 16,
338 5170: 34,
339 5180: 36,
340 5190: 38,
341 5200: 40,
342 5210: 42,
343 5220: 44,
344 5230: 46,
345 5240: 48,
346 5260: 52,
347 5280: 56,
348 5300: 60,
349 5320: 64,
350 5500: 100,
351 5520: 104,
352 5540: 108,
353 5560: 112,
354 5580: 116,
355 5600: 120,
356 5620: 124,
357 5640: 128,
358 5660: 132,
359 5680: 136,
360 5700: 140,
361 5745: 149,
362 5765: 153,
363 5785: 157,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700364 5795: 159,
Ang Li73697b32015-12-03 00:41:53 +0000365 5805: 161,
366 5825: 165,
367 }
368
369 # All Wifi channels to frequencies lookup.
370 channel_2G_to_freq = {
371 1: 2412,
372 2: 2417,
373 3: 2422,
374 4: 2427,
375 5: 2432,
376 6: 2437,
377 7: 2442,
378 8: 2447,
379 9: 2452,
380 10: 2457,
381 11: 2462,
382 12: 2467,
383 13: 2472,
384 14: 2484
385 }
386
387 channel_5G_to_freq = {
388 183: 4915,
389 184: 4920,
390 185: 4925,
391 187: 4935,
392 188: 4940,
393 189: 4945,
394 192: 4960,
395 196: 4980,
396 7: 5035,
397 8: 5040,
398 9: 5045,
399 11: 5055,
400 12: 5060,
401 16: 5080,
402 34: 5170,
403 36: 5180,
404 38: 5190,
405 40: 5200,
406 42: 5210,
407 44: 5220,
408 46: 5230,
409 48: 5240,
410 52: 5260,
411 56: 5280,
412 60: 5300,
413 64: 5320,
414 100: 5500,
415 104: 5520,
416 108: 5540,
417 112: 5560,
418 116: 5580,
419 120: 5600,
420 124: 5620,
421 128: 5640,
422 132: 5660,
423 136: 5680,
424 140: 5700,
425 149: 5745,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700426 151: 5755,
Ang Li73697b32015-12-03 00:41:53 +0000427 153: 5765,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700428 155: 5775,
Ang Li73697b32015-12-03 00:41:53 +0000429 157: 5785,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700430 159: 5795,
Ang Li73697b32015-12-03 00:41:53 +0000431 161: 5805,
432 165: 5825
433 }
434
Ang Li82522812016-06-02 13:57:21 -0700435
Ang Li73697b32015-12-03 00:41:53 +0000436class WifiChannelBase:
437 ALL_2G_FREQUENCIES = []
438 DFS_5G_FREQUENCIES = []
439 NONE_DFS_5G_FREQUENCIES = []
440 ALL_5G_FREQUENCIES = DFS_5G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES
441 MIX_CHANNEL_SCAN = []
442
443 def band_to_freq(self, band):
444 _band_to_frequencies = {
445 WifiEnums.WIFI_BAND_24_GHZ: self.ALL_2G_FREQUENCIES,
446 WifiEnums.WIFI_BAND_5_GHZ: self.NONE_DFS_5G_FREQUENCIES,
447 WifiEnums.WIFI_BAND_5_GHZ_DFS_ONLY: self.DFS_5G_FREQUENCIES,
448 WifiEnums.WIFI_BAND_5_GHZ_WITH_DFS: self.ALL_5G_FREQUENCIES,
Ang Li82522812016-06-02 13:57:21 -0700449 WifiEnums.WIFI_BAND_BOTH:
450 self.ALL_2G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES,
451 WifiEnums.WIFI_BAND_BOTH_WITH_DFS:
452 self.ALL_5G_FREQUENCIES + self.ALL_2G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000453 }
454 return _band_to_frequencies[band]
455
Ang Li82522812016-06-02 13:57:21 -0700456
Ang Li73697b32015-12-03 00:41:53 +0000457class WifiChannelUS(WifiChannelBase):
458 # US Wifi frequencies
459 ALL_2G_FREQUENCIES = [2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452,
460 2457, 2462]
461 NONE_DFS_5G_FREQUENCIES = [5180, 5200, 5220, 5240, 5745, 5765, 5785, 5805,
462 5825]
Ang Li82522812016-06-02 13:57:21 -0700463 MIX_CHANNEL_SCAN = [2412, 2437, 2462, 5180, 5200, 5280, 5260, 5300, 5500,
464 5320, 5520, 5560, 5700, 5745, 5805]
Ang Li73697b32015-12-03 00:41:53 +0000465
466 def __init__(self, model=None):
Girish Moturu0c567b02017-08-11 16:20:01 -0700467 self.DFS_5G_FREQUENCIES = [5260, 5280, 5300, 5320, 5500, 5520,
468 5540, 5560, 5580, 5600, 5620, 5640,
469 5660, 5680, 5700, 5720]
470 self.ALL_5G_FREQUENCIES = self.DFS_5G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000471
Bindu Mahadevff295782019-02-08 16:17:48 -0800472
Girish Moturuf02fa1d2017-05-21 09:51:23 +0530473class WifiReferenceNetworks:
474 """ Class to parse and return networks of different band and
475 auth type from reference_networks
476 """
477 def __init__(self, obj):
478 self.reference_networks = obj
479 self.WIFI_2G = "2g"
480 self.WIFI_5G = "5g"
481
482 self.secure_networks_2g = []
483 self.secure_networks_5g = []
484 self.open_networks_2g = []
485 self.open_networks_5g = []
486 self._parse_networks()
487
488 def _parse_networks(self):
489 for network in self.reference_networks:
490 for key in network:
491 if key == self.WIFI_2G:
492 if "password" in network[key]:
493 self.secure_networks_2g.append(network[key])
494 else:
495 self.open_networks_2g.append(network[key])
496 else:
497 if "password" in network[key]:
498 self.secure_networks_5g.append(network[key])
499 else:
500 self.open_networks_5g.append(network[key])
501
502 def return_2g_secure_networks(self):
503 return self.secure_networks_2g
504
505 def return_5g_secure_networks(self):
506 return self.secure_networks_5g
507
508 def return_2g_open_networks(self):
509 return self.open_networks_2g
510
511 def return_5g_open_networks(self):
512 return self.open_networks_5g
513
514 def return_secure_networks(self):
515 return self.secure_networks_2g + self.secure_networks_5g
516
517 def return_open_networks(self):
518 return self.open_networks_2g + self.open_networks_5g
519
Ang Li82522812016-06-02 13:57:21 -0700520
521def _assert_on_fail_handler(func, assert_on_fail, *args, **kwargs):
522 """Wrapper function that handles the bahevior of assert_on_fail.
523
524 When assert_on_fail is True, let all test signals through, which can
525 terminate test cases directly. When assert_on_fail is False, the wrapper
526 raises no test signals and reports operation status by returning True or
527 False.
528
529 Args:
530 func: The function to wrap. This function reports operation status by
531 raising test signals.
532 assert_on_fail: A boolean that specifies if the output of the wrapper
533 is test signal based or return value based.
534 args: Positional args for func.
535 kwargs: Name args for func.
536
537 Returns:
538 If assert_on_fail is True, returns True/False to signal operation
539 status, otherwise return nothing.
540 """
541 try:
542 func(*args, **kwargs)
543 if not assert_on_fail:
544 return True
545 except signals.TestSignal:
546 if assert_on_fail:
547 raise
548 return False
549
550
551def assert_network_in_list(target, network_list):
552 """Makes sure a specified target Wi-Fi network exists in a list of Wi-Fi
553 networks.
554
555 Args:
556 target: A dict representing a Wi-Fi network.
557 E.g. {WifiEnums.SSID_KEY: "SomeNetwork"}
558 network_list: A list of dicts, each representing a Wi-Fi network.
559 """
560 match_results = match_networks(target, network_list)
561 asserts.assert_true(
562 match_results, "Target network %s, does not exist in network list %s" %
563 (target, network_list))
564
565
Ang Li73697b32015-12-03 00:41:53 +0000566def match_networks(target_params, networks):
567 """Finds the WiFi networks that match a given set of parameters in a list
568 of WiFi networks.
569
Girish Moturubc48d9f2016-11-01 13:24:14 -0700570 To be considered a match, the network should contain every key-value pair
571 of target_params
Ang Li73697b32015-12-03 00:41:53 +0000572
573 Args:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700574 target_params: A dict with 1 or more key-value pairs representing a Wi-Fi network.
575 E.g { 'SSID': 'wh_ap1_5g', 'BSSID': '30:b5:c2:33:e4:47' }
Ang Li73697b32015-12-03 00:41:53 +0000576 networks: A list of dict objects representing WiFi networks.
577
578 Returns:
579 The networks that match the target parameters.
580 """
581 results = []
Betty Zhou3caa0982017-02-22 19:26:20 -0800582 asserts.assert_true(target_params,
583 "Expected networks object 'target_params' is empty")
Ang Li73697b32015-12-03 00:41:53 +0000584 for n in networks:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700585 add_network = 1
Ang Li9a66de72016-02-08 15:26:38 -0800586 for k, v in target_params.items():
587 if k not in n:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700588 add_network = 0
589 break
Ang Li9a66de72016-02-08 15:26:38 -0800590 if n[k] != v:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700591 add_network = 0
592 break
593 if add_network:
Ang Li73697b32015-12-03 00:41:53 +0000594 results.append(n)
595 return results
596
Bindu Mahadevff295782019-02-08 16:17:48 -0800597
Roshan Pius93b519c2018-05-09 12:07:11 -0700598def wait_for_wifi_state(ad, state, assert_on_fail=True):
599 """Waits for the device to transition to the specified wifi state
600
601 Args:
602 ad: An AndroidDevice object.
603 state: Wifi state to wait for.
604 assert_on_fail: If True, error checks in this function will raise test
605 failure signals.
606
607 Returns:
608 If assert_on_fail is False, function returns True if the device transitions
609 to the specified state, False otherwise. If assert_on_fail is True, no return value.
610 """
611 return _assert_on_fail_handler(
612 _wait_for_wifi_state, assert_on_fail, ad, state=state)
613
614
615def _wait_for_wifi_state(ad, state):
616 """Toggles the state of wifi.
617
618 TestFailure signals are raised when something goes wrong.
619
620 Args:
621 ad: An AndroidDevice object.
622 state: Wifi state to wait for.
623 """
624 if state == ad.droid.wifiCheckState():
625 # Check if the state is already achieved, so we don't wait for the
626 # state change event by mistake.
627 return
628 ad.droid.wifiStartTrackingStateChange()
629 fail_msg = "Device did not transition to Wi-Fi state to %s on %s." % (state,
630 ad.serial)
631 try:
632 ad.ed.wait_for_event(wifi_constants.WIFI_STATE_CHANGED,
633 lambda x: x["data"]["enabled"] == state,
634 SHORT_TIMEOUT)
635 except Empty:
636 asserts.assert_equal(state, ad.droid.wifiCheckState(), fail_msg)
637 finally:
638 ad.droid.wifiStopTrackingStateChange()
Ang Li82522812016-06-02 13:57:21 -0700639
Bindu Mahadevff295782019-02-08 16:17:48 -0800640
Ang Li82522812016-06-02 13:57:21 -0700641def wifi_toggle_state(ad, new_state=None, assert_on_fail=True):
Ang Li6b557182015-11-11 17:19:17 -0800642 """Toggles the state of wifi.
Ang Li73697b32015-12-03 00:41:53 +0000643
Ang Li6b557182015-11-11 17:19:17 -0800644 Args:
645 ad: An AndroidDevice object.
646 new_state: Wifi state to set to. If None, opposite of the current state.
Ang Li82522812016-06-02 13:57:21 -0700647 assert_on_fail: If True, error checks in this function will raise test
648 failure signals.
Ang Li73697b32015-12-03 00:41:53 +0000649
Ang Li6b557182015-11-11 17:19:17 -0800650 Returns:
Ang Li82522812016-06-02 13:57:21 -0700651 If assert_on_fail is False, function returns True if the toggle was
652 successful, False otherwise. If assert_on_fail is True, no return value.
653 """
Betty Zhou3caa0982017-02-22 19:26:20 -0800654 return _assert_on_fail_handler(
655 _wifi_toggle_state, assert_on_fail, ad, new_state=new_state)
Ang Li82522812016-06-02 13:57:21 -0700656
657
658def _wifi_toggle_state(ad, new_state=None):
659 """Toggles the state of wifi.
660
661 TestFailure signals are raised when something goes wrong.
662
663 Args:
664 ad: An AndroidDevice object.
665 new_state: The state to set Wi-Fi to. If None, opposite of the current
666 state will be set.
Ang Li6b557182015-11-11 17:19:17 -0800667 """
Ang Li31b00782016-06-21 13:04:23 -0700668 if new_state is None:
669 new_state = not ad.droid.wifiCheckState()
Ang Lie5c85c92016-07-27 15:38:09 -0700670 elif new_state == ad.droid.wifiCheckState():
671 # Check if the new_state is already achieved, so we don't wait for the
672 # state change event by mistake.
673 return
674 ad.droid.wifiStartTrackingStateChange()
Ang Li31b00782016-06-21 13:04:23 -0700675 ad.log.info("Setting Wi-Fi state to %s.", new_state)
Roshan Pius5a027fa2018-05-04 13:59:38 -0700676 ad.ed.clear_all_events()
Ang Li31b00782016-06-21 13:04:23 -0700677 # Setting wifi state.
Ang Li6b557182015-11-11 17:19:17 -0800678 ad.droid.wifiToggleState(new_state)
Jaineel3bd9bea2019-12-13 12:44:17 -0800679 time.sleep(2)
Ang Lie2e93a22016-06-22 16:43:28 -0700680 fail_msg = "Failed to set Wi-Fi state to %s on %s." % (new_state,
681 ad.serial)
Ang Li73697b32015-12-03 00:41:53 +0000682 try:
Roshan Pius5a027fa2018-05-04 13:59:38 -0700683 ad.ed.wait_for_event(wifi_constants.WIFI_STATE_CHANGED,
684 lambda x: x["data"]["enabled"] == new_state,
685 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +0000686 except Empty:
Ang Li82522812016-06-02 13:57:21 -0700687 asserts.assert_equal(new_state, ad.droid.wifiCheckState(), fail_msg)
Ang Li6b557182015-11-11 17:19:17 -0800688 finally:
689 ad.droid.wifiStopTrackingStateChange()
690
Ang Li82522812016-06-02 13:57:21 -0700691
Ang Li6b557182015-11-11 17:19:17 -0800692def reset_wifi(ad):
Ang Li1179fa72016-06-16 09:44:06 -0700693 """Clears all saved Wi-Fi networks on a device.
694
695 This will turn Wi-Fi on.
Ang Li6b557182015-11-11 17:19:17 -0800696
697 Args:
698 ad: An AndroidDevice object.
699
Ang Li6b557182015-11-11 17:19:17 -0800700 """
Ang Li6b557182015-11-11 17:19:17 -0800701 networks = ad.droid.wifiGetConfiguredNetworks()
702 if not networks:
703 return
704 for n in networks:
705 ad.droid.wifiForgetNetwork(n['networkId'])
706 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800707 event = ad.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS,
Ang Li82522812016-06-02 13:57:21 -0700708 SHORT_TIMEOUT)
Ang Li6b557182015-11-11 17:19:17 -0800709 except Empty:
Ang Li1179fa72016-06-16 09:44:06 -0700710 logging.warning("Could not confirm the removal of network %s.", n)
711 # Check again to see if there's any network left.
Betty Zhou3caa0982017-02-22 19:26:20 -0800712 asserts.assert_true(
713 not ad.droid.wifiGetConfiguredNetworks(),
714 "Failed to remove these configured Wi-Fi networks: %s" % networks)
Ang Li82522812016-06-02 13:57:21 -0700715
Ang Li73697b32015-12-03 00:41:53 +0000716
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700717def toggle_airplane_mode_on_and_off(ad):
718 """Turn ON and OFF Airplane mode.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800719
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700720 ad: An AndroidDevice object.
721 Returns: Assert if turning on/off Airplane mode fails.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800722
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700723 """
724 ad.log.debug("Toggling Airplane mode ON.")
725 asserts.assert_true(
726 utils.force_airplane_mode(ad, True),
727 "Can not turn on airplane mode on: %s" % ad.serial)
728 time.sleep(DEFAULT_TIMEOUT)
729 ad.log.debug("Toggling Airplane mode OFF.")
730 asserts.assert_true(
731 utils.force_airplane_mode(ad, False),
732 "Can not turn on airplane mode on: %s" % ad.serial)
733 time.sleep(DEFAULT_TIMEOUT)
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800734
735
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700736def toggle_wifi_off_and_on(ad):
737 """Turn OFF and ON WiFi.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800738
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700739 ad: An AndroidDevice object.
740 Returns: Assert if turning off/on WiFi fails.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800741
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700742 """
743 ad.log.debug("Toggling wifi OFF.")
744 wifi_toggle_state(ad, False)
745 time.sleep(DEFAULT_TIMEOUT)
746 ad.log.debug("Toggling wifi ON.")
747 wifi_toggle_state(ad, True)
748 time.sleep(DEFAULT_TIMEOUT)
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800749
750
Ang Li73697b32015-12-03 00:41:53 +0000751def wifi_forget_network(ad, net_ssid):
Ang Li8e767182015-12-09 17:29:24 -0800752 """Remove configured Wifi network on an android device.
Ang Li73697b32015-12-03 00:41:53 +0000753
Ang Li8e767182015-12-09 17:29:24 -0800754 Args:
755 ad: android_device object for forget network.
756 net_ssid: ssid of network to be forget
Ang Li73697b32015-12-03 00:41:53 +0000757
Ang Li8e767182015-12-09 17:29:24 -0800758 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700759 networks = ad.droid.wifiGetConfiguredNetworks()
Ang Li8e767182015-12-09 17:29:24 -0800760 if not networks:
761 return
762 for n in networks:
763 if net_ssid in n[WifiEnums.SSID_KEY]:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700764 ad.droid.wifiForgetNetwork(n['networkId'])
Ang Li8e767182015-12-09 17:29:24 -0800765 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800766 event = ad.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS,
Betty Zhou3caa0982017-02-22 19:26:20 -0800767 SHORT_TIMEOUT)
Ang Li8e767182015-12-09 17:29:24 -0800768 except Empty:
Girish Moturu1bf82302016-11-01 13:27:00 -0700769 asserts.fail("Failed to remove network %s." % n)
Ang Li73697b32015-12-03 00:41:53 +0000770
Ang Li82522812016-06-02 13:57:21 -0700771
Ang Li73697b32015-12-03 00:41:53 +0000772def wifi_test_device_init(ad):
773 """Initializes an android device for wifi testing.
774
775 0. Make sure SL4A connection is established on the android device.
776 1. Disable location service's WiFi scan.
777 2. Turn WiFi on.
778 3. Clear all saved networks.
779 4. Set country code to US.
780 5. Enable WiFi verbose logging.
781 6. Sync device time with computer time.
782 7. Turn off cellular data.
Ang Lifee28402016-07-13 13:43:29 -0700783 8. Turn off ambient display.
Ang Li73697b32015-12-03 00:41:53 +0000784 """
Ang Lifee28402016-07-13 13:43:29 -0700785 utils.require_sl4a((ad, ))
Ang Li73697b32015-12-03 00:41:53 +0000786 ad.droid.wifiScannerToggleAlwaysAvailable(False)
787 msg = "Failed to turn off location service's scan."
Ang Li82522812016-06-02 13:57:21 -0700788 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
789 wifi_toggle_state(ad, True)
Ang Li6b557182015-11-11 17:19:17 -0800790 reset_wifi(ad)
Ang Li73697b32015-12-03 00:41:53 +0000791 ad.droid.wifiEnableVerboseLogging(1)
Ang Li8e767182015-12-09 17:29:24 -0800792 msg = "Failed to enable WiFi verbose logging."
Ang Li82522812016-06-02 13:57:21 -0700793 asserts.assert_equal(ad.droid.wifiGetVerboseLoggingLevel(), 1, msg)
Ang Li73697b32015-12-03 00:41:53 +0000794 # We don't verify the following settings since they are not critical.
Ang Lie2e93a22016-06-22 16:43:28 -0700795 # Set wpa_supplicant log level to EXCESSIVE.
796 output = ad.adb.shell("wpa_cli -i wlan0 -p -g@android:wpa_wlan0 IFNAME="
797 "wlan0 log_level EXCESSIVE")
798 ad.log.info("wpa_supplicant log change status: %s", output)
Ang Lifee28402016-07-13 13:43:29 -0700799 utils.sync_device_time(ad)
Ang Li0bf8e022016-01-04 17:34:48 -0800800 ad.droid.telephonyToggleDataConnection(False)
Roshan Pius48df08c2019-09-13 08:07:30 -0700801 set_wifi_country_code(ad, WifiEnums.CountryCode.US)
Ang Lifee28402016-07-13 13:43:29 -0700802 utils.set_ambient_display(ad, False)
Ang Li73697b32015-12-03 00:41:53 +0000803
Roshan Pius48df08c2019-09-13 08:07:30 -0700804def set_wifi_country_code(ad, country_code):
805 """Sets the wifi country code on the device.
806
807 Args:
808 ad: An AndroidDevice object.
809 country_code: 2 letter ISO country code
codycaldwell35b87182020-01-16 14:08:01 -0800810
811 Raises:
812 An RpcException if unable to set the country code.
Roshan Pius48df08c2019-09-13 08:07:30 -0700813 """
Jaineelc5b56a62019-10-10 17:12:02 -0700814 try:
codycaldwell35b87182020-01-16 14:08:01 -0800815 ad.adb.shell("cmd wifi force-country-code enabled %s" % country_code)
816 except ad.adb.AdbError as e:
Jaineelc5b56a62019-10-10 17:12:02 -0700817 ad.droid.wifiSetCountryCode(WifiEnums.CountryCode.US)
Roshan Pius48df08c2019-09-13 08:07:30 -0700818
Ang Li82522812016-06-02 13:57:21 -0700819
Ang Li6b557182015-11-11 17:19:17 -0800820def start_wifi_connection_scan(ad):
Ang Li73697b32015-12-03 00:41:53 +0000821 """Starts a wifi connection scan and wait for results to become available.
822
823 Args:
Ang Li6b557182015-11-11 17:19:17 -0800824 ad: An AndroidDevice object.
Ang Li73697b32015-12-03 00:41:53 +0000825 """
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800826 ad.ed.clear_all_events()
Ang Li6b557182015-11-11 17:19:17 -0800827 ad.droid.wifiStartScan()
Ang Li82522812016-06-02 13:57:21 -0700828 try:
829 ad.ed.pop_event("WifiManagerScanResultsAvailable", 60)
830 except Empty:
831 asserts.fail("Wi-Fi results did not become available within 60s.")
832
Ang Li73697b32015-12-03 00:41:53 +0000833
Roshan Piuscb9bc482018-02-01 14:27:09 -0800834def start_wifi_connection_scan_and_return_status(ad):
835 """
836 Starts a wifi connection scan and wait for results to become available
837 or a scan failure to be reported.
838
839 Args:
840 ad: An AndroidDevice object.
841 Returns:
842 True: if scan succeeded & results are available
843 False: if scan failed
844 """
845 ad.ed.clear_all_events()
846 ad.droid.wifiStartScan()
847 try:
848 events = ad.ed.pop_events(
849 "WifiManagerScan(ResultsAvailable|Failure)", 60)
850 except Empty:
851 asserts.fail(
852 "Wi-Fi scan results/failure did not become available within 60s.")
853 # If there are multiple matches, we check for atleast one success.
854 for event in events:
855 if event["name"] == "WifiManagerScanResultsAvailable":
856 return True
857 elif event["name"] == "WifiManagerScanFailure":
858 ad.log.debug("Scan failure received")
859 return False
860
861
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800862def start_wifi_connection_scan_and_check_for_network(ad, network_ssid,
Roshan Piuscb9bc482018-02-01 14:27:09 -0800863 max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800864 """
865 Start connectivity scans & checks if the |network_ssid| is seen in
866 scan results. The method performs a max of |max_tries| connectivity scans
867 to find the network.
868
869 Args:
870 ad: An AndroidDevice object.
871 network_ssid: SSID of the network we are looking for.
872 max_tries: Number of scans to try.
873 Returns:
874 True: if network_ssid is found in scan results.
875 False: if network_ssid is not found in scan results.
876 """
877 for num_tries in range(max_tries):
Roshan Piuscb9bc482018-02-01 14:27:09 -0800878 if start_wifi_connection_scan_and_return_status(ad):
879 scan_results = ad.droid.wifiGetScanResults()
880 match_results = match_networks(
881 {WifiEnums.SSID_KEY: network_ssid}, scan_results)
882 if len(match_results) > 0:
883 return True
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800884 return False
885
886
887def start_wifi_connection_scan_and_ensure_network_found(ad, network_ssid,
Roshan Piuscb9bc482018-02-01 14:27:09 -0800888 max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800889 """
890 Start connectivity scans & ensure the |network_ssid| is seen in
891 scan results. The method performs a max of |max_tries| connectivity scans
892 to find the network.
893 This method asserts on failure!
894
895 Args:
896 ad: An AndroidDevice object.
897 network_ssid: SSID of the network we are looking for.
898 max_tries: Number of scans to try.
899 """
900 ad.log.info("Starting scans to ensure %s is present", network_ssid)
901 assert_msg = "Failed to find " + network_ssid + " in scan results" \
902 " after " + str(max_tries) + " tries"
903 asserts.assert_true(start_wifi_connection_scan_and_check_for_network(
904 ad, network_ssid, max_tries), assert_msg)
905
906
907def start_wifi_connection_scan_and_ensure_network_not_found(ad, network_ssid,
Roshan Piuscb9bc482018-02-01 14:27:09 -0800908 max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800909 """
910 Start connectivity scans & ensure the |network_ssid| is not seen in
911 scan results. The method performs a max of |max_tries| connectivity scans
912 to find the network.
913 This method asserts on failure!
914
915 Args:
916 ad: An AndroidDevice object.
917 network_ssid: SSID of the network we are looking for.
918 max_tries: Number of scans to try.
919 """
920 ad.log.info("Starting scans to ensure %s is not present", network_ssid)
921 assert_msg = "Found " + network_ssid + " in scan results" \
922 " after " + str(max_tries) + " tries"
923 asserts.assert_false(start_wifi_connection_scan_and_check_for_network(
924 ad, network_ssid, max_tries), assert_msg)
925
926
Ang Li73697b32015-12-03 00:41:53 +0000927def start_wifi_background_scan(ad, scan_setting):
928 """Starts wifi background scan.
929
930 Args:
931 ad: android_device object to initiate connection on.
932 scan_setting: A dict representing the settings of the scan.
933
934 Returns:
935 If scan was started successfully, event data of success event is returned.
936 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700937 idx = ad.droid.wifiScannerStartBackgroundScan(scan_setting)
938 event = ad.ed.pop_event("WifiScannerScan{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -0800939 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +0000940 return event['data']
941
Ang Li82522812016-06-02 13:57:21 -0700942
Roshan Piusce821342018-01-10 11:03:04 -0800943def start_wifi_tethering(ad, ssid, password, band=None, hidden=None):
Ang Li73697b32015-12-03 00:41:53 +0000944 """Starts wifi tethering on an android_device.
945
946 Args:
947 ad: android_device to start wifi tethering on.
948 ssid: The SSID the soft AP should broadcast.
949 password: The password the soft AP should use.
950 band: The band the soft AP should be set on. It should be either
951 WifiEnums.WIFI_CONFIG_APBAND_2G or WifiEnums.WIFI_CONFIG_APBAND_5G.
Roshan Piusce821342018-01-10 11:03:04 -0800952 hidden: boolean to indicate if the AP needs to be hidden or not.
Ang Li73697b32015-12-03 00:41:53 +0000953
954 Returns:
Girish Moturu3581d612016-11-02 15:08:51 -0700955 No return value. Error checks in this function will raise test failure signals
Ang Li73697b32015-12-03 00:41:53 +0000956 """
Ang Li82522812016-06-02 13:57:21 -0700957 config = {WifiEnums.SSID_KEY: ssid}
Ang Li73697b32015-12-03 00:41:53 +0000958 if password:
959 config[WifiEnums.PWD_KEY] = password
960 if band:
lesl6d30a172020-03-05 15:05:22 +0800961 config[WifiEnums.AP_BAND_KEY] = band
Roshan Piusce821342018-01-10 11:03:04 -0800962 if hidden:
963 config[WifiEnums.HIDDEN_KEY] = hidden
Betty Zhou3caa0982017-02-22 19:26:20 -0800964 asserts.assert_true(
965 ad.droid.wifiSetWifiApConfiguration(config),
966 "Failed to update WifiAp Configuration")
Girish Moturu40d7dc22016-11-02 12:14:56 -0700967 ad.droid.wifiStartTrackingTetherStateChange()
968 ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
Rebecca Silbersteina2889852016-08-11 00:48:53 -0700969 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700970 ad.ed.pop_event("ConnectivityManagerOnTetheringStarted")
971 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -0800972 lambda x: x["data"]["ACTIVE_TETHER"], 30)
Ang Li76216d12016-09-20 14:51:57 -0700973 ad.log.debug("Tethering started successfully.")
Rebecca Silbersteina2889852016-08-11 00:48:53 -0700974 except Empty:
975 msg = "Failed to receive confirmation of wifi tethering starting"
976 asserts.fail(msg)
977 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700978 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li73697b32015-12-03 00:41:53 +0000979
Bindu Mahadevff295782019-02-08 16:17:48 -0800980
lesl6d30a172020-03-05 15:05:22 +0800981def save_wifi_soft_ap_config(ad, wifi_config, band=None, hidden=None,
982 security=None, password=None,
983 channel=None, max_clients=None,
984 shutdown_timeout_enable=None,
985 shutdown_timeout_millis=None,
986 client_control_enable=None,
987 allowedList=None, blockedList=None):
988 """ Save a soft ap configuration and verified
989 Args:
990 ad: android_device to set soft ap configuration.
991 wifi_config: a soft ap configuration object, at least include SSID.
992 band: specifies the band for the soft ap.
993 hidden: specifies the soft ap need to broadcast its SSID or not.
994 security: specifies the security type for the soft ap.
995 password: specifies the password for the soft ap.
996 channel: specifies the channel for the soft ap.
997 max_clients: specifies the maximum connected client number.
998 shutdown_timeout_enable: specifies the auto shut down enable or not.
999 shutdown_timeout_millis: specifies the shut down timeout value.
1000 client_control_enable: specifies the client control enable or not.
1001 allowedList: specifies allowed clients list.
1002 blockedList: specifies blocked clients list.
1003 """
1004 if security and password:
1005 wifi_config[WifiEnums.SECURITY] = security
1006 wifi_config[WifiEnums.PWD_KEY] = password
Girish Moturu528b5442018-06-07 10:48:14 -07001007 if band:
lesl6d30a172020-03-05 15:05:22 +08001008 wifi_config[WifiEnums.AP_BAND_KEY] = band
Girish Moturu528b5442018-06-07 10:48:14 -07001009 if hidden:
1010 wifi_config[WifiEnums.HIDDEN_KEY] = hidden
lesl6d30a172020-03-05 15:05:22 +08001011 if channel and band:
1012 wifi_config[WifiEnums.AP_BAND_KEY] = band
1013 wifi_config[WifiEnums.AP_CHANNEL_KEY] = channel
1014 if max_clients:
1015 wifi_config[WifiEnums.AP_MAXCLIENTS_KEY] = max_clients
1016 if shutdown_timeout_enable:
1017 wifi_config[
1018 WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] = shutdown_timeout_enable
1019 if shutdown_timeout_millis:
1020 wifi_config[
1021 WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] = shutdown_timeout_millis
1022 if client_control_enable:
1023 wifi_config[WifiEnums.AP_CLIENTCONTROL_KEY] = client_control_enable
1024 if allowedList:
1025 wifi_config[WifiEnums.AP_ALLOWEDLIST_KEY] = allowedList
1026 if blockedList:
1027 wifi_config[WifiEnums.AP_BLOCKEDLIST_KEY] = blockedList
1028
1029 if WifiEnums.AP_CHANNEL_KEY in wifi_config and wifi_config[
1030 WifiEnums.AP_CHANNEL_KEY] == 0:
1031 del wifi_config[WifiEnums.AP_CHANNEL_KEY]
1032
1033 if WifiEnums.SECURITY in wifi_config and wifi_config[
1034 WifiEnums.SECURITY] == WifiEnums.SoftApSecurityType.OPEN:
1035 del wifi_config[WifiEnums.SECURITY]
1036 del wifi_config[WifiEnums.PWD_KEY]
1037
Girish Moturu528b5442018-06-07 10:48:14 -07001038 asserts.assert_true(ad.droid.wifiSetWifiApConfiguration(wifi_config),
1039 "Failed to set WifiAp Configuration")
1040
1041 wifi_ap = ad.droid.wifiGetApConfiguration()
1042 asserts.assert_true(
1043 wifi_ap[WifiEnums.SSID_KEY] == wifi_config[WifiEnums.SSID_KEY],
lesl6d30a172020-03-05 15:05:22 +08001044 "Hotspot SSID doesn't match")
1045 if WifiEnums.SECURITY in wifi_config:
1046 asserts.assert_true(
1047 wifi_ap[WifiEnums.SECURITY] == wifi_config[WifiEnums.SECURITY],
1048 "Hotspot Security doesn't match")
1049 if WifiEnums.PWD_KEY in wifi_config:
1050 asserts.assert_true(
1051 wifi_ap[WifiEnums.PWD_KEY] == wifi_config[WifiEnums.PWD_KEY],
1052 "Hotspot Password doesn't match")
Girish Moturu528b5442018-06-07 10:48:14 -07001053
lesl6d30a172020-03-05 15:05:22 +08001054 if WifiEnums.HIDDEN_KEY in wifi_config:
1055 asserts.assert_true(
1056 wifi_ap[WifiEnums.HIDDEN_KEY] == wifi_config[WifiEnums.HIDDEN_KEY],
1057 "Hotspot hidden setting doesn't match")
1058
1059 if WifiEnums.AP_BAND_KEY in wifi_config:
1060 asserts.assert_true(
1061 wifi_ap[WifiEnums.AP_BAND_KEY] == wifi_config[WifiEnums.AP_BAND_KEY],
1062 "Hotspot Band doesn't match")
1063 if WifiEnums.AP_CHANNEL_KEY in wifi_config:
1064 asserts.assert_true(
1065 wifi_ap[WifiEnums.AP_CHANNEL_KEY] == wifi_config[
1066 WifiEnums.AP_CHANNEL_KEY], "Hotspot Channel doesn't match")
1067 if WifiEnums.AP_MAXCLIENTS_KEY in wifi_config:
1068 asserts.assert_true(
1069 wifi_ap[WifiEnums.AP_MAXCLIENTS_KEY] == wifi_config[
1070 WifiEnums.AP_MAXCLIENTS_KEY], "Hotspot Max Clients doesn't match")
1071 if WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY in wifi_config:
1072 asserts.assert_true(
1073 wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] == wifi_config[
1074 WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY],
1075 "Hotspot ShutDown feature flag doesn't match")
1076 if WifiEnums.AP_SHUTDOWNTIMEOUT_KEY in wifi_config:
1077 asserts.assert_true(
1078 wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] == wifi_config[
1079 WifiEnums.AP_SHUTDOWNTIMEOUT_KEY],
1080 "Hotspot ShutDown timeout setting doesn't match")
1081 if WifiEnums.AP_CLIENTCONTROL_KEY in wifi_config:
1082 asserts.assert_true(
1083 wifi_ap[WifiEnums.AP_CLIENTCONTROL_KEY] == wifi_config[
1084 WifiEnums.AP_CLIENTCONTROL_KEY],
1085 "Hotspot Client control flag doesn't match")
1086 if WifiEnums.AP_ALLOWEDLIST_KEY in wifi_config:
1087 asserts.assert_true(
1088 wifi_ap[WifiEnums.AP_ALLOWEDLIST_KEY] == wifi_config[
1089 WifiEnums.AP_ALLOWEDLIST_KEY],
1090 "Hotspot Allowed List doesn't match")
1091 if WifiEnums.AP_BLOCKEDLIST_KEY in wifi_config:
1092 asserts.assert_true(
1093 wifi_ap[WifiEnums.AP_BLOCKEDLIST_KEY] == wifi_config[
1094 WifiEnums.AP_BLOCKEDLIST_KEY],
1095 "Hotspot Blocked List doesn't match")
Bindu Mahadevff295782019-02-08 16:17:48 -08001096
Girish Moturu528b5442018-06-07 10:48:14 -07001097def start_wifi_tethering_saved_config(ad):
1098 """ Turn on wifi hotspot with a config that is already saved """
1099 ad.droid.wifiStartTrackingTetherStateChange()
1100 ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
1101 try:
1102 ad.ed.pop_event("ConnectivityManagerOnTetheringStarted")
1103 ad.ed.wait_for_event("TetherStateChanged",
1104 lambda x: x["data"]["ACTIVE_TETHER"], 30)
1105 except:
1106 asserts.fail("Didn't receive wifi tethering starting confirmation")
1107 finally:
1108 ad.droid.wifiStopTrackingTetherStateChange()
Betty Zhou3caa0982017-02-22 19:26:20 -08001109
Bindu Mahadevff295782019-02-08 16:17:48 -08001110
Ang Li73697b32015-12-03 00:41:53 +00001111def stop_wifi_tethering(ad):
1112 """Stops wifi tethering on an android_device.
Ang Li73697b32015-12-03 00:41:53 +00001113 Args:
1114 ad: android_device to stop wifi tethering on.
1115 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001116 ad.droid.wifiStartTrackingTetherStateChange()
1117 ad.droid.connectivityStopTethering(tel_defines.TETHERING_WIFI)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001118 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001119 ad.ed.pop_event("WifiManagerApDisabled", 30)
1120 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -08001121 lambda x: not x["data"]["ACTIVE_TETHER"], 30)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001122 except Empty:
1123 msg = "Failed to receive confirmation of wifi tethering stopping"
1124 asserts.fail(msg)
1125 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001126 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li82522812016-06-02 13:57:21 -07001127
Ang Li76216d12016-09-20 14:51:57 -07001128
Roshan Pius58916a32016-06-16 16:26:44 -07001129def toggle_wifi_and_wait_for_reconnection(ad,
1130 network,
1131 num_of_tries=1,
1132 assert_on_fail=True):
1133 """Toggle wifi state and then wait for Android device to reconnect to
1134 the provided wifi network.
1135
1136 This expects the device to be already connected to the provided network.
1137
1138 Logic steps are
1139 1. Ensure that we're connected to the network.
1140 2. Turn wifi off.
1141 3. Wait for 10 seconds.
1142 4. Turn wifi on.
1143 5. Wait for the "connected" event, then confirm the connected ssid is the
1144 one requested.
1145
1146 Args:
1147 ad: android_device object to initiate connection on.
1148 network: A dictionary representing the network to await connection. The
1149 dictionary must have the key "SSID".
1150 num_of_tries: An integer that is the number of times to try before
1151 delaring failure. Default is 1.
1152 assert_on_fail: If True, error checks in this function will raise test
1153 failure signals.
1154
1155 Returns:
1156 If assert_on_fail is False, function returns True if the toggle was
1157 successful, False otherwise. If assert_on_fail is True, no return value.
1158 """
Betty Zhou3caa0982017-02-22 19:26:20 -08001159 return _assert_on_fail_handler(
1160 _toggle_wifi_and_wait_for_reconnection,
1161 assert_on_fail,
1162 ad,
1163 network,
1164 num_of_tries=num_of_tries)
Roshan Pius58916a32016-06-16 16:26:44 -07001165
1166
Girish Moturu5d9f4202019-12-03 15:29:21 -08001167def _toggle_wifi_and_wait_for_reconnection(ad, network, num_of_tries=3):
Roshan Pius58916a32016-06-16 16:26:44 -07001168 """Toggle wifi state and then wait for Android device to reconnect to
1169 the provided wifi network.
1170
1171 This expects the device to be already connected to the provided network.
1172
1173 Logic steps are
1174 1. Ensure that we're connected to the network.
1175 2. Turn wifi off.
1176 3. Wait for 10 seconds.
1177 4. Turn wifi on.
1178 5. Wait for the "connected" event, then confirm the connected ssid is the
1179 one requested.
1180
1181 This will directly fail a test if anything goes wrong.
1182
1183 Args:
1184 ad: android_device object to initiate connection on.
1185 network: A dictionary representing the network to await connection. The
1186 dictionary must have the key "SSID".
1187 num_of_tries: An integer that is the number of times to try before
1188 delaring failure. Default is 1.
1189 """
Roshan Pius58916a32016-06-16 16:26:44 -07001190 expected_ssid = network[WifiEnums.SSID_KEY]
1191 # First ensure that we're already connected to the provided network.
1192 verify_con = {WifiEnums.SSID_KEY: expected_ssid}
1193 verify_wifi_connection_info(ad, verify_con)
1194 # Now toggle wifi state and wait for the connection event.
1195 wifi_toggle_state(ad, False)
1196 time.sleep(10)
1197 wifi_toggle_state(ad, True)
1198 ad.droid.wifiStartTrackingStateChange()
1199 try:
1200 connect_result = None
1201 for i in range(num_of_tries):
1202 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -08001203 connect_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
Roshan Pius58916a32016-06-16 16:26:44 -07001204 30)
1205 break
1206 except Empty:
1207 pass
1208 asserts.assert_true(connect_result,
1209 "Failed to connect to Wi-Fi network %s on %s" %
Girish Moturu40d7dc22016-11-02 12:14:56 -07001210 (network, ad.serial))
Betty Zhou3caa0982017-02-22 19:26:20 -08001211 logging.debug("Connection result on %s: %s.", ad.serial,
1212 connect_result)
Roshan Pius58916a32016-06-16 16:26:44 -07001213 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1214 asserts.assert_equal(actual_ssid, expected_ssid,
1215 "Connected to the wrong network on %s."
1216 "Expected %s, but got %s." %
Girish Moturu40d7dc22016-11-02 12:14:56 -07001217 (ad.serial, expected_ssid, actual_ssid))
Betty Zhou3caa0982017-02-22 19:26:20 -08001218 logging.info("Connected to Wi-Fi network %s on %s", actual_ssid,
1219 ad.serial)
Roshan Pius58916a32016-06-16 16:26:44 -07001220 finally:
1221 ad.droid.wifiStopTrackingStateChange()
1222
1223
Roshan Piusd1204442018-11-12 12:20:39 -08001224def wait_for_connect(ad, expected_ssid=None, expected_id=None, tries=2,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001225 assert_on_fail=True):
Roshan Piusd1204442018-11-12 12:20:39 -08001226 """Wait for a connect event.
1227
1228 This will directly fail a test if anything goes wrong.
1229
1230 Args:
1231 ad: An Android device object.
1232 expected_ssid: SSID of the network to connect to.
1233 expected_id: Network Id of the network to connect to.
1234 tries: An integer that is the number of times to try before failing.
1235 assert_on_fail: If True, error checks in this function will raise test
1236 failure signals.
1237
1238 Returns:
1239 Returns a value only if assert_on_fail is false.
1240 Returns True if the connection was successful, False otherwise.
1241 """
1242 return _assert_on_fail_handler(
1243 _wait_for_connect, assert_on_fail, ad, expected_ssid, expected_id,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001244 tries)
Roshan Piusd1204442018-11-12 12:20:39 -08001245
1246
Oscar Shucb9af9b2019-05-02 20:01:49 +00001247def _wait_for_connect(ad, expected_ssid=None, expected_id=None, tries=2):
Roshan Piusd1204442018-11-12 12:20:39 -08001248 """Wait for a connect event.
1249
1250 Args:
1251 ad: An Android device object.
1252 expected_ssid: SSID of the network to connect to.
1253 expected_id: Network Id of the network to connect to.
1254 tries: An integer that is the number of times to try before failing.
1255 """
1256 ad.droid.wifiStartTrackingStateChange()
1257 try:
1258 connect_result = _wait_for_connect_event(
Oscar Shucb9af9b2019-05-02 20:01:49 +00001259 ad, ssid=expected_ssid, id=expected_id, tries=tries)
Roshan Piusd1204442018-11-12 12:20:39 -08001260 asserts.assert_true(connect_result,
1261 "Failed to connect to Wi-Fi network %s" %
1262 expected_ssid)
1263 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
1264 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1265 if expected_ssid:
1266 asserts.assert_equal(actual_ssid, expected_ssid,
1267 "Connected to the wrong network")
1268 actual_id = connect_result['data'][WifiEnums.NETID_KEY]
1269 if expected_id:
1270 asserts.assert_equal(actual_id, expected_id,
1271 "Connected to the wrong network")
1272 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
1273 except Empty:
1274 asserts.fail("Failed to start connection process to %s" %
1275 expected_ssid)
1276 except Exception as error:
1277 ad.log.error("Failed to connect to %s with error %s", expected_ssid,
1278 error)
1279 raise signals.TestFailure("Failed to connect to %s network" %
1280 expected_ssid)
1281 finally:
1282 ad.droid.wifiStopTrackingStateChange()
1283
1284
Oscar Shucb9af9b2019-05-02 20:01:49 +00001285def _wait_for_connect_event(ad, ssid=None, id=None, tries=1):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001286 """Wait for a connect event on queue and pop when available.
1287
1288 Args:
1289 ad: An Android device object.
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001290 ssid: SSID of the network to connect to.
1291 id: Network Id of the network to connect to.
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001292 tries: An integer that is the number of times to try before failing.
1293
1294 Returns:
1295 A dict with details of the connection data, which looks like this:
1296 {
1297 'time': 1485460337798,
1298 'name': 'WifiNetworkConnected',
1299 'data': {
1300 'rssi': -27,
1301 'is_24ghz': True,
1302 'mac_address': '02:00:00:00:00:00',
1303 'network_id': 1,
1304 'BSSID': '30:b5:c2:33:d3:fc',
1305 'ip_address': 117483712,
1306 'link_speed': 54,
1307 'supplicant_state': 'completed',
1308 'hidden_ssid': False,
1309 'SSID': 'wh_ap1_2g',
1310 'is_5ghz': False}
1311 }
1312
1313 """
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001314 conn_result = None
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001315
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001316 # If ssid and network id is None, just wait for any connect event.
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001317 if id is None and ssid is None:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001318 for i in range(tries):
1319 try:
1320 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED, 30)
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001321 break
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001322 except Empty:
1323 pass
1324 else:
1325 # If ssid or network id is specified, wait for specific connect event.
1326 for i in range(tries):
1327 try:
1328 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED, 30)
1329 if id and conn_result['data'][WifiEnums.NETID_KEY] == id:
1330 break
1331 elif ssid and conn_result['data'][WifiEnums.SSID_KEY] == ssid:
1332 break
1333 except Empty:
1334 pass
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001335
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001336 return conn_result
1337
Bindu Mahadevff295782019-02-08 16:17:48 -08001338
Roshan Piusffc29912019-01-18 13:39:49 -08001339def wait_for_disconnect(ad, timeout=10):
1340 """Wait for a disconnect event within the specified timeout.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001341
1342 Args:
1343 ad: Android device object.
Roshan Piusffc29912019-01-18 13:39:49 -08001344 timeout: Timeout in seconds.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001345
1346 """
1347 try:
1348 ad.droid.wifiStartTrackingStateChange()
Roshan Piusffc29912019-01-18 13:39:49 -08001349 event = ad.ed.pop_event("WifiNetworkDisconnected", timeout)
Roshan Piusbf7e3982018-02-15 12:37:41 -08001350 except Empty:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001351 raise signals.TestFailure("Device did not disconnect from the network")
Roshan Piusffc29912019-01-18 13:39:49 -08001352 finally:
1353 ad.droid.wifiStopTrackingStateChange()
1354
1355
1356def ensure_no_disconnect(ad, duration=10):
1357 """Ensure that there is no disconnect for the specified duration.
1358
1359 Args:
1360 ad: Android device object.
1361 duration: Duration in seconds.
1362
1363 """
1364 try:
1365 ad.droid.wifiStartTrackingStateChange()
1366 event = ad.ed.pop_event("WifiNetworkDisconnected", duration)
1367 raise signals.TestFailure("Device disconnected from the network")
1368 except Empty:
1369 pass
1370 finally:
1371 ad.droid.wifiStopTrackingStateChange()
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001372
1373
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001374def connect_to_wifi_network(ad, network, assert_on_fail=True,
Joe Brennan48c3f692019-04-11 08:30:16 -07001375 check_connectivity=True, hidden=False):
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001376 """Connection logic for open and psk wifi networks.
1377
1378 Args:
Jong Wook Kim92356922018-02-06 18:32:49 -08001379 ad: AndroidDevice to use for connection
1380 network: network info of the network to connect to
1381 assert_on_fail: If true, errors from wifi_connect will raise
1382 test failure signals.
Joe Brennan48c3f692019-04-11 08:30:16 -07001383 hidden: Is the Wifi network hidden.
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001384 """
Joe Brennan48c3f692019-04-11 08:30:16 -07001385 if hidden:
1386 start_wifi_connection_scan_and_ensure_network_not_found(
1387 ad, network[WifiEnums.SSID_KEY])
1388 else:
1389 start_wifi_connection_scan_and_ensure_network_found(
1390 ad, network[WifiEnums.SSID_KEY])
Jong Wook Kim92356922018-02-06 18:32:49 -08001391 wifi_connect(ad,
1392 network,
1393 num_of_tries=3,
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001394 assert_on_fail=assert_on_fail,
1395 check_connectivity=check_connectivity)
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001396
1397
1398def connect_to_wifi_network_with_id(ad, network_id, network_ssid):
1399 """Connect to the given network using network id and verify SSID.
1400
1401 Args:
1402 network_id: int Network Id of the network.
1403 network_ssid: string SSID of the network.
1404
1405 Returns: True if connect using network id was successful;
1406 False otherwise.
1407
1408 """
Jong Wook Kim92356922018-02-06 18:32:49 -08001409 start_wifi_connection_scan_and_ensure_network_found(ad, network_ssid)
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001410 wifi_connect_by_id(ad, network_id)
1411 connect_data = ad.droid.wifiGetConnectionInfo()
1412 connect_ssid = connect_data[WifiEnums.SSID_KEY]
1413 ad.log.debug("Expected SSID = %s Connected SSID = %s" %
1414 (network_ssid, connect_ssid))
1415 if connect_ssid != network_ssid:
1416 return False
1417 return True
1418
1419
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001420def wifi_connect(ad, network, num_of_tries=1, assert_on_fail=True,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001421 check_connectivity=True):
Ang Li99d8c6d2015-12-09 15:56:13 -08001422 """Connect an Android device to a wifi network.
Ang Li73697b32015-12-03 00:41:53 +00001423
1424 Initiate connection to a wifi network, wait for the "connected" event, then
Ang Li99d8c6d2015-12-09 15:56:13 -08001425 confirm the connected ssid is the one requested.
Ang Li73697b32015-12-03 00:41:53 +00001426
Ang Li82522812016-06-02 13:57:21 -07001427 This will directly fail a test if anything goes wrong.
1428
Ang Li73697b32015-12-03 00:41:53 +00001429 Args:
1430 ad: android_device object to initiate connection on.
Ang Li99d8c6d2015-12-09 15:56:13 -08001431 network: A dictionary representing the network to connect to. The
Ang Li82522812016-06-02 13:57:21 -07001432 dictionary must have the key "SSID".
1433 num_of_tries: An integer that is the number of times to try before
1434 delaring failure. Default is 1.
1435 assert_on_fail: If True, error checks in this function will raise test
1436 failure signals.
1437
1438 Returns:
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001439 Returns a value only if assert_on_fail is false.
1440 Returns True if the connection was successful, False otherwise.
Ang Li73697b32015-12-03 00:41:53 +00001441 """
Betty Zhou3caa0982017-02-22 19:26:20 -08001442 return _assert_on_fail_handler(
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001443 _wifi_connect, assert_on_fail, ad, network, num_of_tries=num_of_tries,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001444 check_connectivity=check_connectivity)
Ang Li82522812016-06-02 13:57:21 -07001445
1446
Oscar Shucb9af9b2019-05-02 20:01:49 +00001447def _wifi_connect(ad, network, num_of_tries=1, check_connectivity=True):
Ang Li82522812016-06-02 13:57:21 -07001448 """Connect an Android device to a wifi network.
1449
1450 Initiate connection to a wifi network, wait for the "connected" event, then
1451 confirm the connected ssid is the one requested.
1452
1453 This will directly fail a test if anything goes wrong.
1454
1455 Args:
1456 ad: android_device object to initiate connection on.
1457 network: A dictionary representing the network to connect to. The
1458 dictionary must have the key "SSID".
1459 num_of_tries: An integer that is the number of times to try before
1460 delaring failure. Default is 1.
1461 """
Ang Li82522812016-06-02 13:57:21 -07001462 asserts.assert_true(WifiEnums.SSID_KEY in network,
1463 "Key '%s' must be present in network definition." %
1464 WifiEnums.SSID_KEY)
Ang Li99d8c6d2015-12-09 15:56:13 -08001465 ad.droid.wifiStartTrackingStateChange()
Betty Zhoud35dab82016-12-06 15:24:23 -08001466 expected_ssid = network[WifiEnums.SSID_KEY]
Bindu Mahadev50374df2017-01-04 11:03:32 -08001467 ad.droid.wifiConnectByConfig(network)
1468 ad.log.info("Starting connection process to %s", expected_ssid)
Ang Li73697b32015-12-03 00:41:53 +00001469 try:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001470 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_CONFIG_SUCCESS, 30)
Roshan Piusd1204442018-11-12 12:20:39 -08001471 connect_result = _wait_for_connect_event(
Oscar Shucb9af9b2019-05-02 20:01:49 +00001472 ad, ssid=expected_ssid, tries=num_of_tries)
Ang Li82522812016-06-02 13:57:21 -07001473 asserts.assert_true(connect_result,
1474 "Failed to connect to Wi-Fi network %s on %s" %
Girish Moturubc48d9f2016-11-01 13:24:14 -07001475 (network, ad.serial))
Ang Li31b00782016-06-21 13:04:23 -07001476 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
Ang Li99d8c6d2015-12-09 15:56:13 -08001477 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Ang Li82522812016-06-02 13:57:21 -07001478 asserts.assert_equal(actual_ssid, expected_ssid,
Betty Zhou3caa0982017-02-22 19:26:20 -08001479 "Connected to the wrong network on %s." %
1480 ad.serial)
Ang Li31b00782016-06-21 13:04:23 -07001481 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
Bindu Mahadev50374df2017-01-04 11:03:32 -08001482
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001483 if check_connectivity:
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08001484 internet = validate_connection(ad, DEFAULT_PING_ADDR)
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001485 if not internet:
1486 raise signals.TestFailure("Failed to connect to internet on %s" %
1487 expected_ssid)
Bindu Mahadev50374df2017-01-04 11:03:32 -08001488 except Empty:
1489 asserts.fail("Failed to start connection process to %s on %s" %
1490 (network, ad.serial))
Bindu Mahadev4e710362016-11-17 16:17:11 -08001491 except Exception as error:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001492 ad.log.error("Failed to connect to %s with error %s", expected_ssid,
1493 error)
1494 raise signals.TestFailure("Failed to connect to %s network" % network)
1495
Ang Li73697b32015-12-03 00:41:53 +00001496 finally:
Ang Li99d8c6d2015-12-09 15:56:13 -08001497 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001498
Bindu Mahadev50374df2017-01-04 11:03:32 -08001499
Oscar Shucb9af9b2019-05-02 20:01:49 +00001500def wifi_connect_by_id(ad, network_id, num_of_tries=3, assert_on_fail=True):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001501 """Connect an Android device to a wifi network using network Id.
1502
1503 Start connection to the wifi network, with the given network Id, wait for
1504 the "connected" event, then verify the connected network is the one requested.
1505
1506 This will directly fail a test if anything goes wrong.
1507
1508 Args:
1509 ad: android_device object to initiate connection on.
1510 network_id: Integer specifying the network id of the network.
1511 num_of_tries: An integer that is the number of times to try before
1512 delaring failure. Default is 1.
1513 assert_on_fail: If True, error checks in this function will raise test
1514 failure signals.
1515
1516 Returns:
1517 Returns a value only if assert_on_fail is false.
1518 Returns True if the connection was successful, False otherwise.
1519 """
1520 _assert_on_fail_handler(_wifi_connect_by_id, assert_on_fail, ad,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001521 network_id, num_of_tries)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001522
1523
Oscar Shucb9af9b2019-05-02 20:01:49 +00001524def _wifi_connect_by_id(ad, network_id, num_of_tries=1):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001525 """Connect an Android device to a wifi network using it's network id.
1526
1527 Start connection to the wifi network, with the given network id, wait for
1528 the "connected" event, then verify the connected network is the one requested.
1529
1530 Args:
1531 ad: android_device object to initiate connection on.
1532 network_id: Integer specifying the network id of the network.
1533 num_of_tries: An integer that is the number of times to try before
1534 delaring failure. Default is 1.
1535 """
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001536 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001537 # Clear all previous events.
1538 ad.ed.clear_all_events()
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001539 ad.droid.wifiConnectByNetworkId(network_id)
1540 ad.log.info("Starting connection to network with id %d", network_id)
1541 try:
1542 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_NETID_SUCCESS, 60)
Roshan Piusd1204442018-11-12 12:20:39 -08001543 connect_result = _wait_for_connect_event(
Oscar Shucb9af9b2019-05-02 20:01:49 +00001544 ad, id=network_id, tries=num_of_tries)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001545 asserts.assert_true(connect_result,
1546 "Failed to connect to Wi-Fi network using network id")
1547 ad.log.debug("Wi-Fi connection result: %s", connect_result)
1548 actual_id = connect_result['data'][WifiEnums.NETID_KEY]
1549 asserts.assert_equal(actual_id, network_id,
1550 "Connected to the wrong network on %s."
1551 "Expected network id = %d, but got %d." %
1552 (ad.serial, network_id, actual_id))
1553 expected_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1554 ad.log.info("Connected to Wi-Fi network %s with %d network id.",
1555 expected_ssid, network_id)
1556
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001557 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1558 if not internet:
1559 raise signals.TestFailure("Failed to connect to internet on %s" %
1560 expected_ssid)
1561 except Empty:
1562 asserts.fail("Failed to connect to network with id %d on %s" %
1563 (network_id, ad.serial))
1564 except Exception as error:
1565 ad.log.error("Failed to connect to network with id %d with error %s",
1566 network_id, error)
1567 raise signals.TestFailure("Failed to connect to network with network"
1568 " id %d" % network_id)
1569 finally:
1570 ad.droid.wifiStopTrackingStateChange()
1571
Oscar Shu0b5ff4d2019-08-07 18:11:56 +00001572
Roshan Piusc999e5e2018-11-09 10:59:52 -08001573def wifi_connect_using_network_request(ad, network, network_specifier,
1574 num_of_tries=3, assert_on_fail=True):
1575 """Connect an Android device to a wifi network using network request.
1576
1577 Trigger a network request with the provided network specifier,
1578 wait for the "onMatch" event, ensure that the scan results in "onMatch"
1579 event contain the specified network, then simulate the user granting the
1580 request with the specified network selected. Then wait for the "onAvailable"
1581 network callback indicating successful connection to network.
1582
1583 This will directly fail a test if anything goes wrong.
1584
1585 Args:
1586 ad: android_device object to initiate connection on.
1587 network_specifier: A dictionary representing the network specifier to
1588 use.
1589 network: A dictionary representing the network to connect to. The
1590 dictionary must have the key "SSID".
1591 num_of_tries: An integer that is the number of times to try before
1592 delaring failure.
1593 assert_on_fail: If True, error checks in this function will raise test
1594 failure signals.
1595
1596 Returns:
1597 Returns a value only if assert_on_fail is false.
1598 Returns True if the connection was successful, False otherwise.
1599 """
1600 _assert_on_fail_handler(_wifi_connect_using_network_request, assert_on_fail,
1601 ad, network, network_specifier, num_of_tries)
1602
1603
1604def _wifi_connect_using_network_request(ad, network, network_specifier,
1605 num_of_tries=3):
1606 """Connect an Android device to a wifi network using network request.
1607
1608 Trigger a network request with the provided network specifier,
1609 wait for the "onMatch" event, ensure that the scan results in "onMatch"
1610 event contain the specified network, then simulate the user granting the
1611 request with the specified network selected. Then wait for the "onAvailable"
1612 network callback indicating successful connection to network.
1613
1614 Args:
1615 ad: android_device object to initiate connection on.
1616 network_specifier: A dictionary representing the network specifier to
1617 use.
1618 network: A dictionary representing the network to connect to. The
1619 dictionary must have the key "SSID".
1620 num_of_tries: An integer that is the number of times to try before
1621 delaring failure.
1622 """
1623 ad.droid.wifiRequestNetworkWithSpecifier(network_specifier)
1624 ad.log.info("Sent network request with %s", network_specifier)
1625 # Need a delay here because UI interaction should only start once wifi
1626 # starts processing the request.
1627 time.sleep(wifi_constants.NETWORK_REQUEST_CB_REGISTER_DELAY_SEC)
1628 _wait_for_wifi_connect_after_network_request(ad, network, num_of_tries)
1629
1630
1631def wait_for_wifi_connect_after_network_request(ad, network, num_of_tries=3,
1632 assert_on_fail=True):
1633 """
1634 Simulate and verify the connection flow after initiating the network
1635 request.
1636
1637 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1638 event contain the specified network, then simulate the user granting the
1639 request with the specified network selected. Then wait for the "onAvailable"
1640 network callback indicating successful connection to network.
1641
1642 Args:
1643 ad: android_device object to initiate connection on.
1644 network: A dictionary representing the network to connect to. The
1645 dictionary must have the key "SSID".
1646 num_of_tries: An integer that is the number of times to try before
1647 delaring failure.
1648 assert_on_fail: If True, error checks in this function will raise test
1649 failure signals.
1650
1651 Returns:
1652 Returns a value only if assert_on_fail is false.
1653 Returns True if the connection was successful, False otherwise.
1654 """
1655 _assert_on_fail_handler(_wait_for_wifi_connect_after_network_request,
1656 assert_on_fail, ad, network, num_of_tries)
1657
1658
1659def _wait_for_wifi_connect_after_network_request(ad, network, num_of_tries=3):
1660 """
1661 Simulate and verify the connection flow after initiating the network
1662 request.
1663
1664 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1665 event contain the specified network, then simulate the user granting the
1666 request with the specified network selected. Then wait for the "onAvailable"
1667 network callback indicating successful connection to network.
1668
1669 Args:
1670 ad: android_device object to initiate connection on.
1671 network: A dictionary representing the network to connect to. The
1672 dictionary must have the key "SSID".
1673 num_of_tries: An integer that is the number of times to try before
1674 delaring failure.
1675 """
1676 asserts.assert_true(WifiEnums.SSID_KEY in network,
1677 "Key '%s' must be present in network definition." %
1678 WifiEnums.SSID_KEY)
1679 ad.droid.wifiStartTrackingStateChange()
1680 expected_ssid = network[WifiEnums.SSID_KEY]
1681 ad.droid.wifiRegisterNetworkRequestMatchCallback()
1682 # Wait for the platform to scan and return a list of networks
1683 # matching the request
1684 try:
1685 matched_network = None
1686 for _ in [0, num_of_tries]:
1687 on_match_event = ad.ed.pop_event(
1688 wifi_constants.WIFI_NETWORK_REQUEST_MATCH_CB_ON_MATCH, 60)
1689 asserts.assert_true(on_match_event,
1690 "Network request on match not received.")
1691 matched_scan_results = on_match_event["data"]
1692 ad.log.debug("Network request on match results %s",
1693 matched_scan_results)
1694 matched_network = match_networks(
1695 {WifiEnums.SSID_KEY: network[WifiEnums.SSID_KEY]},
1696 matched_scan_results)
1697 if matched_network:
1698 break;
1699
1700 asserts.assert_true(
1701 matched_network, "Target network %s not found" % network)
1702
1703 ad.droid.wifiSendUserSelectionForNetworkRequestMatch(network)
1704 ad.log.info("Sent user selection for network request %s",
1705 expected_ssid)
1706
1707 # Wait for the platform to connect to the network.
1708 on_available_event = ad.ed.pop_event(
1709 wifi_constants.WIFI_NETWORK_CB_ON_AVAILABLE, 60)
1710 asserts.assert_true(on_available_event,
1711 "Network request on available not received.")
1712 connected_network = on_available_event["data"]
1713 ad.log.info("Connected to network %s", connected_network)
1714 asserts.assert_equal(connected_network[WifiEnums.SSID_KEY],
1715 expected_ssid,
1716 "Connected to the wrong network."
1717 "Expected %s, but got %s." %
1718 (network, connected_network))
1719 except Empty:
1720 asserts.fail("Failed to connect to %s" % expected_ssid)
1721 except Exception as error:
1722 ad.log.error("Failed to connect to %s with error %s",
1723 (expected_ssid, error))
1724 raise signals.TestFailure("Failed to connect to %s network" % network)
1725 finally:
1726 ad.droid.wifiStopTrackingStateChange()
1727
1728
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001729def wifi_passpoint_connect(ad, passpoint_network, num_of_tries=1,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001730 assert_on_fail=True):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001731 """Connect an Android device to a wifi network.
1732
1733 Initiate connection to a wifi network, wait for the "connected" event, then
1734 confirm the connected ssid is the one requested.
1735
1736 This will directly fail a test if anything goes wrong.
1737
1738 Args:
1739 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001740 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001741 num_of_tries: An integer that is the number of times to try before
1742 delaring failure. Default is 1.
1743 assert_on_fail: If True, error checks in this function will raise test
1744 failure signals.
1745
1746 Returns:
1747 If assert_on_fail is False, function returns network id, if the connect was
1748 successful, False otherwise. If assert_on_fail is True, no return value.
1749 """
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001750 _assert_on_fail_handler(_wifi_passpoint_connect, assert_on_fail, ad,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001751 passpoint_network, num_of_tries = num_of_tries)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001752
1753
Oscar Shucb9af9b2019-05-02 20:01:49 +00001754def _wifi_passpoint_connect(ad, passpoint_network, num_of_tries=1):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001755 """Connect an Android device to a wifi network.
1756
1757 Initiate connection to a wifi network, wait for the "connected" event, then
1758 confirm the connected ssid is the one requested.
1759
1760 This will directly fail a test if anything goes wrong.
1761
1762 Args:
1763 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001764 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001765 num_of_tries: An integer that is the number of times to try before
1766 delaring failure. Default is 1.
1767 """
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001768 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001769 expected_ssid = passpoint_network
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001770 ad.log.info("Starting connection process to passpoint %s", expected_ssid)
1771
1772 try:
Roshan Piusd1204442018-11-12 12:20:39 -08001773 connect_result = _wait_for_connect_event(
Oscar Shucb9af9b2019-05-02 20:01:49 +00001774 ad, expected_ssid, num_of_tries)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001775 asserts.assert_true(connect_result,
1776 "Failed to connect to WiFi passpoint network %s on"
1777 " %s" % (expected_ssid, ad.serial))
1778 ad.log.info("Wi-Fi connection result: %s.", connect_result)
1779 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1780 asserts.assert_equal(actual_ssid, expected_ssid,
1781 "Connected to the wrong network on %s." % ad.serial)
1782 ad.log.info("Connected to Wi-Fi passpoint network %s.", actual_ssid)
1783
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001784 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1785 if not internet:
1786 raise signals.TestFailure("Failed to connect to internet on %s" %
1787 expected_ssid)
1788 except Exception as error:
1789 ad.log.error("Failed to connect to passpoint network %s with error %s",
1790 expected_ssid, error)
1791 raise signals.TestFailure("Failed to connect to %s passpoint network" %
1792 expected_ssid)
1793
1794 finally:
1795 ad.droid.wifiStopTrackingStateChange()
1796
1797
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001798def delete_passpoint(ad, fqdn):
1799 """Delete a required Passpoint configuration."""
1800 try:
1801 ad.droid.removePasspointConfig(fqdn)
1802 return True
1803 except Exception as error:
1804 ad.log.error("Failed to remove passpoint configuration with FQDN=%s "
1805 "and error=%s" , fqdn, error)
1806 return False
1807
1808
Ang Li73697b32015-12-03 00:41:53 +00001809def start_wifi_single_scan(ad, scan_setting):
1810 """Starts wifi single shot scan.
1811
1812 Args:
1813 ad: android_device object to initiate connection on.
1814 scan_setting: A dict representing the settings of the scan.
1815
1816 Returns:
1817 If scan was started successfully, event data of success event is returned.
1818 """
Ang Li82522812016-06-02 13:57:21 -07001819 idx = ad.droid.wifiScannerStartScan(scan_setting)
1820 event = ad.ed.pop_event("WifiScannerScan%sonSuccess" % idx, SHORT_TIMEOUT)
Ang Li31b00782016-06-21 13:04:23 -07001821 ad.log.debug("Got event %s", event)
Ang Li73697b32015-12-03 00:41:53 +00001822 return event['data']
1823
Ang Li82522812016-06-02 13:57:21 -07001824
Ang Li73697b32015-12-03 00:41:53 +00001825def track_connection(ad, network_ssid, check_connection_count):
1826 """Track wifi connection to network changes for given number of counts
1827
1828 Args:
1829 ad: android_device object for forget network.
1830 network_ssid: network ssid to which connection would be tracked
1831 check_connection_count: Integer for maximum number network connection
Ang Li82522812016-06-02 13:57:21 -07001832 check.
Ang Li73697b32015-12-03 00:41:53 +00001833 Returns:
Ang Li73697b32015-12-03 00:41:53 +00001834 True if connection to given network happen, else return False.
1835 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001836 ad.droid.wifiStartTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001837 while check_connection_count > 0:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001838 connect_network = ad.ed.pop_event("WifiNetworkConnected", 120)
Ang Li31b00782016-06-21 13:04:23 -07001839 ad.log.info("Connected to network %s", connect_network)
Ang Li82522812016-06-02 13:57:21 -07001840 if (WifiEnums.SSID_KEY in connect_network['data'] and
1841 connect_network['data'][WifiEnums.SSID_KEY] == network_ssid):
1842 return True
Ang Li8e767182015-12-09 17:29:24 -08001843 check_connection_count -= 1
Girish Moturu40d7dc22016-11-02 12:14:56 -07001844 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001845 return False
1846
Ang Li82522812016-06-02 13:57:21 -07001847
Ang Li73697b32015-12-03 00:41:53 +00001848def get_scan_time_and_channels(wifi_chs, scan_setting, stime_channel):
1849 """Calculate the scan time required based on the band or channels in scan
1850 setting
1851
1852 Args:
1853 wifi_chs: Object of channels supported
1854 scan_setting: scan setting used for start scan
1855 stime_channel: scan time per channel
1856
1857 Returns:
1858 scan_time: time required for completing a scan
1859 scan_channels: channel used for scanning
1860 """
1861 scan_time = 0
1862 scan_channels = []
1863 if "band" in scan_setting and "channels" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001864 scan_channels = wifi_chs.band_to_freq(scan_setting["band"])
Ang Li73697b32015-12-03 00:41:53 +00001865 elif "channels" in scan_setting and "band" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001866 scan_channels = scan_setting["channels"]
Ang Li73697b32015-12-03 00:41:53 +00001867 scan_time = len(scan_channels) * stime_channel
1868 for channel in scan_channels:
Ang Li8e767182015-12-09 17:29:24 -08001869 if channel in WifiEnums.DFS_5G_FREQUENCIES:
Ang Li82522812016-06-02 13:57:21 -07001870 scan_time += 132 #passive scan time on DFS
Ang Li73697b32015-12-03 00:41:53 +00001871 return scan_time, scan_channels
1872
Ang Li82522812016-06-02 13:57:21 -07001873
Ang Li73697b32015-12-03 00:41:53 +00001874def start_wifi_track_bssid(ad, track_setting):
1875 """Start tracking Bssid for the given settings.
1876
1877 Args:
1878 ad: android_device object.
1879 track_setting: Setting for which the bssid tracking should be started
1880
1881 Returns:
1882 If tracking started successfully, event data of success event is returned.
1883 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001884 idx = ad.droid.wifiScannerStartTrackingBssids(
Ang Li82522812016-06-02 13:57:21 -07001885 track_setting["bssidInfos"], track_setting["apLostThreshold"])
Girish Moturu40d7dc22016-11-02 12:14:56 -07001886 event = ad.ed.pop_event("WifiScannerBssid{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -08001887 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +00001888 return event['data']
1889
Ang Li82522812016-06-02 13:57:21 -07001890
Ang Li73697b32015-12-03 00:41:53 +00001891def convert_pem_key_to_pkcs8(in_file, out_file):
1892 """Converts the key file generated by us to the format required by
1893 Android using openssl.
1894
1895 The input file must have the extension "pem". The output file must
1896 have the extension "der".
1897
1898 Args:
1899 in_file: The original key file.
1900 out_file: The full path to the converted key file, including
1901 filename.
1902 """
Ang Li82522812016-06-02 13:57:21 -07001903 asserts.assert_true(in_file.endswith(".pem"), "Input file has to be .pem.")
1904 asserts.assert_true(
1905 out_file.endswith(".der"), "Output file has to be .der.")
Ang Li73697b32015-12-03 00:41:53 +00001906 cmd = ("openssl pkcs8 -inform PEM -in {} -outform DER -out {} -nocrypt"
1907 " -topk8").format(in_file, out_file)
Ang Lifee28402016-07-13 13:43:29 -07001908 utils.exe_cmd(cmd)
Ang Li73697b32015-12-03 00:41:53 +00001909
Ang Li82522812016-06-02 13:57:21 -07001910
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08001911def validate_connection(ad, ping_addr=DEFAULT_PING_ADDR, wait_time=15,
Girish Moturu804a3492020-02-17 14:32:02 -08001912 ping_gateway=True):
Ang Li73697b32015-12-03 00:41:53 +00001913 """Validate internet connection by pinging the address provided.
1914
1915 Args:
1916 ad: android_device object.
1917 ping_addr: address on internet for pinging.
Girish Moturua2a5bf22019-08-16 09:52:29 -07001918 wait_time: wait for some time before validating connection
Ang Li73697b32015-12-03 00:41:53 +00001919
1920 Returns:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001921 ping output if successful, NULL otherwise.
Ang Li73697b32015-12-03 00:41:53 +00001922 """
Girish Moturua2a5bf22019-08-16 09:52:29 -07001923 # wait_time to allow for DHCP to complete.
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08001924 for i in range(wait_time):
1925 if ad.droid.connectivityNetworkIsConnected():
1926 break
1927 time.sleep(1)
Girish Moturu804a3492020-02-17 14:32:02 -08001928 ping = False
1929 try:
1930 ping = ad.droid.httpPing(ping_addr)
1931 ad.log.info("Http ping result: %s.", ping)
1932 except:
1933 pass
1934 if not ping and ping_gateway:
1935 ad.log.info("Http ping failed. Pinging default gateway")
1936 gw = ad.droid.connectivityGetIPv4DefaultGateway()
1937 result = ad.adb.shell("ping -c 6 {}".format(gw))
1938 ad.log.info("Default gateway ping result: %s" % result)
1939 ping = False if "100% packet loss" in result else True
Ang Li73697b32015-12-03 00:41:53 +00001940 return ping
1941
Ang Li82522812016-06-02 13:57:21 -07001942
Ang Li73697b32015-12-03 00:41:53 +00001943#TODO(angli): This can only verify if an actual value is exactly the same.
1944# Would be nice to be able to verify an actual value is one of serveral.
1945def verify_wifi_connection_info(ad, expected_con):
1946 """Verifies that the information of the currently connected wifi network is
1947 as expected.
1948
1949 Args:
1950 expected_con: A dict representing expected key-value pairs for wifi
1951 connection. e.g. {"SSID": "test_wifi"}
1952 """
1953 current_con = ad.droid.wifiGetConnectionInfo()
Ang Li374d7602016-02-08 17:27:27 -08001954 case_insensitive = ["BSSID", "supplicant_state"]
Ang Li31b00782016-06-21 13:04:23 -07001955 ad.log.debug("Current connection: %s", current_con)
Ang Li73697b32015-12-03 00:41:53 +00001956 for k, expected_v in expected_con.items():
Ang Li9a66de72016-02-08 15:26:38 -08001957 # Do not verify authentication related fields.
1958 if k == "password":
1959 continue
Ang Li82522812016-06-02 13:57:21 -07001960 msg = "Field %s does not exist in wifi connection info %s." % (
1961 k, current_con)
Ang Li374d7602016-02-08 17:27:27 -08001962 if k not in current_con:
1963 raise signals.TestFailure(msg)
1964 actual_v = current_con[k]
1965 if k in case_insensitive:
1966 actual_v = actual_v.lower()
1967 expected_v = expected_v.lower()
Ang Li73697b32015-12-03 00:41:53 +00001968 msg = "Expected %s to be %s, actual %s is %s." % (k, expected_v, k,
Ang Li82522812016-06-02 13:57:21 -07001969 actual_v)
Ang Li374d7602016-02-08 17:27:27 -08001970 if actual_v != expected_v:
1971 raise signals.TestFailure(msg)
Ang Li73697b32015-12-03 00:41:53 +00001972
Ang Li82522812016-06-02 13:57:21 -07001973
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08001974def check_autoconnect_to_open_network(ad, conn_timeout=WIFI_CONNECTION_TIMEOUT_DEFAULT):
1975 """Connects to any open WiFI AP
1976 Args:
1977 timeout value in sec to wait for UE to connect to a WiFi AP
1978 Returns:
1979 True if UE connects to WiFi AP (supplicant_state = completed)
1980 False if UE fails to complete connection within WIFI_CONNECTION_TIMEOUT time.
1981 """
1982 if ad.droid.wifiCheckState():
1983 return True
1984 ad.droid.wifiToggleState()
1985 wifi_connection_state = None
1986 timeout = time.time() + conn_timeout
1987 while wifi_connection_state != "completed":
1988 wifi_connection_state = ad.droid.wifiGetConnectionInfo()[
1989 'supplicant_state']
1990 if time.time() > timeout:
1991 ad.log.warning("Failed to connect to WiFi AP")
1992 return False
1993 return True
1994
1995
Ang Li73697b32015-12-03 00:41:53 +00001996def expand_enterprise_config_by_phase2(config):
1997 """Take an enterprise config and generate a list of configs, each with
1998 a different phase2 auth type.
1999
2000 Args:
2001 config: A dict representing enterprise config.
2002
2003 Returns
2004 A list of enterprise configs.
2005 """
2006 results = []
Ang Li0e7e58f2016-02-22 12:15:02 -08002007 phase2_types = WifiEnums.EapPhase2
2008 if config[WifiEnums.Enterprise.EAP] == WifiEnums.Eap.PEAP:
2009 # Skip unsupported phase2 types for PEAP.
2010 phase2_types = [WifiEnums.EapPhase2.GTC, WifiEnums.EapPhase2.MSCHAPV2]
2011 for phase2_type in phase2_types:
Ang Li73697b32015-12-03 00:41:53 +00002012 # Skip a special case for passpoint TTLS.
2013 if (WifiEnums.Enterprise.FQDN in config and
Ang Li82522812016-06-02 13:57:21 -07002014 phase2_type == WifiEnums.EapPhase2.GTC):
Ang Li73697b32015-12-03 00:41:53 +00002015 continue
2016 c = dict(config)
Girish Moturu150d32f2017-02-14 12:27:07 -08002017 c[WifiEnums.Enterprise.PHASE2] = phase2_type.value
Ang Li73697b32015-12-03 00:41:53 +00002018 results.append(c)
2019 return results
Ang Li2d3fe982016-06-08 10:00:43 -07002020
2021
Girish Moturub48a13c2017-02-27 11:36:42 -08002022def generate_eap_test_name(config, ad=None):
Girish Moturu150d32f2017-02-14 12:27:07 -08002023 """ Generates a test case name based on an EAP configuration.
2024
2025 Args:
2026 config: A dict representing an EAP credential.
Girish Moturub48a13c2017-02-27 11:36:42 -08002027 ad object: Redundant but required as the same param is passed
2028 to test_func in run_generated_tests
Girish Moturu150d32f2017-02-14 12:27:07 -08002029
2030 Returns:
2031 A string representing the name of a generated EAP test case.
2032 """
2033 eap = WifiEnums.Eap
2034 eap_phase2 = WifiEnums.EapPhase2
Girish Moturub48a13c2017-02-27 11:36:42 -08002035 Ent = WifiEnums.Enterprise
Girish Moturu150d32f2017-02-14 12:27:07 -08002036 name = "test_connect-"
2037 eap_name = ""
2038 for e in eap:
2039 if e.value == config[Ent.EAP]:
2040 eap_name = e.name
2041 break
2042 if "peap0" in config[WifiEnums.SSID_KEY].lower():
2043 eap_name = "PEAP0"
2044 if "peap1" in config[WifiEnums.SSID_KEY].lower():
2045 eap_name = "PEAP1"
2046 name += eap_name
2047 if Ent.PHASE2 in config:
2048 for e in eap_phase2:
2049 if e.value == config[Ent.PHASE2]:
2050 name += "-{}".format(e.name)
2051 break
2052 return name
2053
2054
Ang Li2d3fe982016-06-08 10:00:43 -07002055def group_attenuators(attenuators):
2056 """Groups a list of attenuators into attenuator groups for backward
2057 compatibility reasons.
2058
2059 Most legacy Wi-Fi setups have two attenuators each connected to a separate
2060 AP. The new Wi-Fi setup has four attenuators, each connected to one channel
2061 on an AP, so two of them are connected to one AP.
2062
2063 To make the existing scripts work in the new setup, when the script needs
2064 to attenuate one AP, it needs to set attenuation on both attenuators
2065 connected to the same AP.
2066
2067 This function groups attenuators properly so the scripts work in both
2068 legacy and new Wi-Fi setups.
2069
2070 Args:
2071 attenuators: A list of attenuator objects, either two or four in length.
2072
2073 Raises:
2074 signals.TestFailure is raised if the attenuator list does not have two
2075 or four objects.
2076 """
2077 attn0 = attenuator.AttenuatorGroup("AP0")
2078 attn1 = attenuator.AttenuatorGroup("AP1")
2079 # Legacy testbed setup has two attenuation channels.
2080 num_of_attns = len(attenuators)
2081 if num_of_attns == 2:
2082 attn0.add(attenuators[0])
2083 attn1.add(attenuators[1])
2084 elif num_of_attns == 4:
2085 attn0.add(attenuators[0])
2086 attn0.add(attenuators[1])
2087 attn1.add(attenuators[2])
2088 attn1.add(attenuators[3])
2089 else:
2090 asserts.fail(("Either two or four attenuators are required for this "
2091 "test, but found %s") % num_of_attns)
2092 return [attn0, attn1]
Jong Wook Kim92356922018-02-06 18:32:49 -08002093
Bindu Mahadevff295782019-02-08 16:17:48 -08002094
Girish Moturu36348a32019-12-10 08:41:54 -08002095def set_attns(attenuator, attn_val_name, roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002096 """Sets attenuation values on attenuators used in this test.
2097
2098 Args:
2099 attenuator: The attenuator object.
2100 attn_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002101 roaming_attn: Dictionary specifying the attenuation params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002102 """
2103 logging.info("Set attenuation values to %s", roaming_attn[attn_val_name])
2104 try:
2105 attenuator[0].set_atten(roaming_attn[attn_val_name][0])
2106 attenuator[1].set_atten(roaming_attn[attn_val_name][1])
2107 attenuator[2].set_atten(roaming_attn[attn_val_name][2])
2108 attenuator[3].set_atten(roaming_attn[attn_val_name][3])
2109 except:
2110 logging.exception("Failed to set attenuation values %s.",
2111 attn_val_name)
2112 raise
2113
Girish Moturu36348a32019-12-10 08:41:54 -08002114def set_attns_steps(attenuators,
2115 atten_val_name,
2116 roaming_attn=ROAMING_ATTN,
2117 steps=10,
2118 wait_time=12):
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002119 """Set attenuation values on attenuators used in this test. It will change
2120 the attenuation values linearly from current value to target value step by
2121 step.
2122
2123 Args:
2124 attenuators: The list of attenuator objects that you want to change
2125 their attenuation value.
2126 atten_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002127 roaming_attn: Dictionary specifying the attenuation params.
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002128 steps: Number of attenuator changes to reach the target value.
2129 wait_time: Sleep time for each change of attenuator.
2130 """
2131 logging.info("Set attenuation values to %s in %d step(s)",
2132 roaming_attn[atten_val_name], steps)
2133 start_atten = [attenuator.get_atten() for attenuator in attenuators]
2134 target_atten = roaming_attn[atten_val_name]
2135 for current_step in range(steps):
2136 progress = (current_step + 1) / steps
2137 for i, attenuator in enumerate(attenuators):
2138 amount_since_start = (target_atten[i] - start_atten[i]) * progress
2139 attenuator.set_atten(round(start_atten[i] + amount_since_start))
2140 time.sleep(wait_time)
2141
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002142
Girish Moturu36348a32019-12-10 08:41:54 -08002143def trigger_roaming_and_validate(dut,
2144 attenuator,
2145 attn_val_name,
2146 expected_con,
2147 roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002148 """Sets attenuators to trigger roaming and validate the DUT connected
2149 to the BSSID expected.
2150
2151 Args:
2152 attenuator: The attenuator object.
2153 attn_val_name: Name of the attenuation value pair to use.
2154 expected_con: The network information of the expected network.
Girish Moturu36348a32019-12-10 08:41:54 -08002155 roaming_attn: Dictionary specifying the attenaution params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002156 """
2157 expected_con = {
2158 WifiEnums.SSID_KEY: expected_con[WifiEnums.SSID_KEY],
2159 WifiEnums.BSSID_KEY: expected_con["bssid"],
2160 }
Girish Moturu36348a32019-12-10 08:41:54 -08002161 set_attns_steps(attenuator, attn_val_name, roaming_attn)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002162
Hsiu-Chang Chenef856402018-09-18 12:32:49 +08002163 verify_wifi_connection_info(dut, expected_con)
2164 expected_bssid = expected_con[WifiEnums.BSSID_KEY]
2165 logging.info("Roamed to %s successfully", expected_bssid)
2166 if not validate_connection(dut):
2167 raise signals.TestFailure("Fail to connect to internet on %s" %
2168 expected_bssid)
Jong Wook Kim92356922018-02-06 18:32:49 -08002169
2170def create_softap_config():
2171 """Create a softap config with random ssid and password."""
2172 ap_ssid = "softap_" + utils.rand_ascii_str(8)
2173 ap_password = utils.rand_ascii_str(8)
2174 logging.info("softap setup: %s %s", ap_ssid, ap_password)
2175 config = {
2176 WifiEnums.SSID_KEY: ap_ssid,
2177 WifiEnums.PWD_KEY: ap_password,
2178 }
2179 return config
Girish Moturucf4dccd2018-08-27 12:22:00 -07002180
Bindu Mahadevff295782019-02-08 16:17:48 -08002181def start_softap_and_verify(ad, band):
2182 """Bring-up softap and verify AP mode and in scan results.
2183
2184 Args:
2185 band: The band to use for softAP.
2186
2187 Returns: dict, the softAP config.
2188
2189 """
lesl2f0fb232019-11-05 16:35:28 +08002190 # Register before start the test.
2191 callbackId = ad.dut.droid.registerSoftApCallback()
2192 # Check softap info value is default
2193 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2194 asserts.assert_true(frequency == 0, "Softap frequency is not reset")
2195 asserts.assert_true(bandwdith == 0, "Softap bandwdith is not reset")
2196
Bindu Mahadevff295782019-02-08 16:17:48 -08002197 config = create_softap_config()
2198 start_wifi_tethering(ad.dut,
2199 config[WifiEnums.SSID_KEY],
2200 config[WifiEnums.PWD_KEY], band=band)
2201 asserts.assert_true(ad.dut.droid.wifiIsApEnabled(),
2202 "SoftAp is not reported as running")
2203 start_wifi_connection_scan_and_ensure_network_found(ad.dut_client,
2204 config[WifiEnums.SSID_KEY])
lesl2f0fb232019-11-05 16:35:28 +08002205
2206 # Check softap info can get from callback succeed and assert value should be
2207 # valid.
2208 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2209 asserts.assert_true(frequency > 0, "Softap frequency is not valid")
2210 asserts.assert_true(bandwdith > 0, "Softap bandwdith is not valid")
2211 # Unregister callback
2212 ad.dut.droid.unregisterSoftApCallback(callbackId)
2213
Bindu Mahadevff295782019-02-08 16:17:48 -08002214 return config
2215
lesle8e3c0a2019-02-22 17:06:04 +08002216def wait_for_expected_number_of_softap_clients(ad, callbackId,
2217 expected_num_of_softap_clients):
2218 """Wait for the number of softap clients to be updated as expected.
2219 Args:
2220 callbackId: Id of the callback associated with registering.
2221 expected_num_of_softap_clients: expected number of softap clients.
2222 """
2223 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
2224 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
James Mattis5a5dd492020-05-14 13:09:43 -07002225 clientData = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data']
2226 clientCount = clientData[wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
2227 clientMacAddresses = clientData[wifi_constants.SOFTAP_CLIENTS_MACS_CALLBACK_KEY]
2228 asserts.assert_equal(clientCount, expected_num_of_softap_clients,
2229 "The number of softap clients doesn't match the expected number")
2230 asserts.assert_equal(len(clientMacAddresses), expected_num_of_softap_clients,
2231 "The number of mac addresses doesn't match the expected number")
2232 for macAddress in clientMacAddresses:
2233 asserts.assert_true(checkMacAddress(macAddress), "An invalid mac address was returned")
2234
2235def checkMacAddress(input):
2236 """Validate whether a string is a valid mac address or not.
2237
2238 Args:
2239 input: The string to validate.
2240
2241 Returns: True/False, returns true for a valid mac address and false otherwise.
2242 """
2243 macValidationRegex = "[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$"
2244 if re.match(macValidationRegex, input.lower()):
2245 return True
2246 return False
lesle8e3c0a2019-02-22 17:06:04 +08002247
2248def wait_for_expected_softap_state(ad, callbackId, expected_softap_state):
2249 """Wait for the expected softap state change.
2250 Args:
2251 callbackId: Id of the callback associated with registering.
2252 expected_softap_state: The expected softap state.
2253 """
2254 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
2255 callbackId) + wifi_constants.SOFTAP_STATE_CHANGED
2256 asserts.assert_equal(ad.ed.pop_event(eventStr,
2257 SHORT_TIMEOUT)['data'][wifi_constants.
2258 SOFTAP_STATE_CHANGE_CALLBACK_KEY],
2259 expected_softap_state,
2260 "Softap state doesn't match with expected state")
2261
2262def get_current_number_of_softap_clients(ad, callbackId):
2263 """pop up all of softap client updated event from queue.
2264 Args:
2265 callbackId: Id of the callback associated with registering.
2266
2267 Returns:
2268 If exist aleast callback, returns last updated number_of_softap_clients.
2269 Returns None when no any match callback event in queue.
2270 """
2271 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
2272 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
2273 events = ad.ed.pop_all(eventStr)
2274 for event in events:
2275 num_of_clients = event['data'][wifi_constants.
2276 SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
2277 if len(events) == 0:
2278 return None
2279 return num_of_clients
Bindu Mahadevff295782019-02-08 16:17:48 -08002280
lesl2f0fb232019-11-05 16:35:28 +08002281def get_current_softap_info(ad, callbackId, least_one):
2282 """pop up all of softap info changed event from queue.
2283 Args:
2284 callbackId: Id of the callback associated with registering.
2285 least_one: Wait for the info callback event before pop all.
2286 Returns:
2287 Returns last updated information of softap.
2288 """
2289 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
2290 callbackId) + wifi_constants.SOFTAP_INFO_CHANGED
2291 ad.log.info("softap info dump from eventStr %s",
2292 eventStr)
2293 frequency = 0
2294 bandwidth = 0
2295 if (least_one):
2296 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
2297 frequency = event['data'][wifi_constants.
2298 SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2299 bandwidth = event['data'][wifi_constants.
2300 SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
2301 ad.log.info("softap info updated, frequency is %s, bandwidth is %s",
2302 frequency, bandwidth)
2303
2304 events = ad.ed.pop_all(eventStr)
2305 for event in events:
2306 frequency = event['data'][wifi_constants.
2307 SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2308 bandwidth = event['data'][wifi_constants.
2309 SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
2310 ad.log.info("softap info, frequency is %s, bandwidth is %s",
2311 frequency, bandwidth)
2312 return frequency, bandwidth
2313
2314
2315
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002316def get_ssrdumps(ad):
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002317 """Pulls dumps in the ssrdump dir
2318 Args:
2319 ad: android device object.
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002320 """
2321 logs = ad.get_file_names("/data/vendor/ssrdump/")
2322 if logs:
2323 ad.log.info("Pulling ssrdumps %s", logs)
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002324 log_path = os.path.join(ad.device_log_path, "SSRDUMPS_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002325 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002326 ad.pull_files(logs, log_path)
Hsiu-Chang Chen769bef12020-10-10 06:07:52 +00002327 ad.adb.shell("find /data/vendor/ssrdump/ -type f -delete",
2328 ignore_status=True)
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002329
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002330def start_pcap(pcap, wifi_band, test_name):
Girish Moturucf4dccd2018-08-27 12:22:00 -07002331 """Start packet capture in monitor mode.
2332
2333 Args:
2334 pcap: packet capture object
2335 wifi_band: '2g' or '5g' or 'dual'
Bindu Mahadev76551c12018-12-13 19:42:14 +00002336 test_name: test name to be used for pcap file name
2337
2338 Returns:
xianyuanjia0431ba32018-12-14 09:56:42 -08002339 Dictionary with wifi band as key and the tuple
2340 (pcap Process object, log directory) as the value
Girish Moturucf4dccd2018-08-27 12:22:00 -07002341 """
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002342 log_dir = os.path.join(
Xianyuan Jia5cd06bb2019-06-10 16:29:57 -07002343 context.get_current_context().get_full_output_path(), 'PacketCapture')
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002344 os.makedirs(log_dir, exist_ok=True)
Girish Moturucf4dccd2018-08-27 12:22:00 -07002345 if wifi_band == 'dual':
2346 bands = [BAND_2G, BAND_5G]
2347 else:
2348 bands = [wifi_band]
xianyuanjia0431ba32018-12-14 09:56:42 -08002349 procs = {}
Girish Moturucf4dccd2018-08-27 12:22:00 -07002350 for band in bands:
xianyuanjia0431ba32018-12-14 09:56:42 -08002351 proc = pcap.start_packet_capture(band, log_dir, test_name)
2352 procs[band] = (proc, os.path.join(log_dir, test_name))
2353 return procs
Girish Moturucf4dccd2018-08-27 12:22:00 -07002354
Bindu Mahadevff295782019-02-08 16:17:48 -08002355
xianyuanjia0431ba32018-12-14 09:56:42 -08002356def stop_pcap(pcap, procs, test_status=None):
Bindu Mahadev76551c12018-12-13 19:42:14 +00002357 """Stop packet capture in monitor mode.
2358
2359 Since, the pcap logs in monitor mode can be very large, we will
2360 delete them if they are not required. 'test_status' if True, will delete
2361 the pcap files. If False, we will keep them.
Girish Moturucf4dccd2018-08-27 12:22:00 -07002362
2363 Args:
2364 pcap: packet capture object
xianyuanjia0431ba32018-12-14 09:56:42 -08002365 procs: dictionary returned by start_pcap
Bindu Mahadev76551c12018-12-13 19:42:14 +00002366 test_status: status of the test case
Girish Moturucf4dccd2018-08-27 12:22:00 -07002367 """
xianyuanjia0431ba32018-12-14 09:56:42 -08002368 for proc, fname in procs.values():
2369 pcap.stop_packet_capture(proc)
Bindu Mahadev76551c12018-12-13 19:42:14 +00002370
2371 if test_status:
xianyuanjia0431ba32018-12-14 09:56:42 -08002372 shutil.rmtree(os.path.dirname(fname))
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002373
Jaineel95887fd2019-10-16 16:19:01 -07002374def verify_mac_not_found_in_pcap(ad, mac, packets):
xshuf7267682019-06-03 14:41:56 -07002375 """Verify that a mac address is not found in the captured packets.
2376
2377 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002378 ad: android device object
xshuf7267682019-06-03 14:41:56 -07002379 mac: string representation of the mac address
2380 packets: packets obtained by rdpcap(pcap_fname)
2381 """
2382 for pkt in packets:
2383 logging.debug("Packet Summary = %s", pkt.summary())
2384 if mac in pkt.summary():
Jaineel95887fd2019-10-16 16:19:01 -07002385 asserts.fail("Device %s caught Factory MAC: %s in packet sniffer."
2386 "Packet = %s" % (ad.serial, mac, pkt.show()))
Bindu Mahadevff295782019-02-08 16:17:48 -08002387
Jaineel95887fd2019-10-16 16:19:01 -07002388def verify_mac_is_found_in_pcap(ad, mac, packets):
Nate Jiangc2c09c62019-06-05 17:26:08 -07002389 """Verify that a mac address is found in the captured packets.
2390
2391 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002392 ad: android device object
Nate Jiangc2c09c62019-06-05 17:26:08 -07002393 mac: string representation of the mac address
2394 packets: packets obtained by rdpcap(pcap_fname)
2395 """
2396 for pkt in packets:
2397 if mac in pkt.summary():
2398 return
Jaineel95887fd2019-10-16 16:19:01 -07002399 asserts.fail("Did not find MAC = %s in packet sniffer."
2400 "for device %s" % (mac, ad.serial))
Nate Jiangc2c09c62019-06-05 17:26:08 -07002401
Girish Moturuddc0d382020-08-24 12:08:41 -07002402def start_cnss_diags(ads, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002403 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002404 start_cnss_diag(ad, cnss_diag_file, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002405
Bindu Mahadevff295782019-02-08 16:17:48 -08002406
Girish Moturuddc0d382020-08-24 12:08:41 -07002407def start_cnss_diag(ad, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002408 """Start cnss_diag to record extra wifi logs
2409
2410 Args:
2411 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002412 cnss_diag_file: cnss diag config file to push to device.
2413 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002414 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002415 if ad.model not in pixel_models:
2416 ad.log.info("Device not supported to collect pixel logger")
2417 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002418 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2419 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2420 else:
2421 prop = wifi_constants.CNSS_DIAG_PROP
2422 if ad.adb.getprop(prop) != 'true':
Girish Moturuddc0d382020-08-24 12:08:41 -07002423 if not int(ad.adb.shell("ls -l %s%s | wc -l" %
2424 (CNSS_DIAG_CONFIG_PATH,
2425 CNSS_DIAG_CONFIG_FILE))):
2426 ad.adb.push("%s %s" % (cnss_diag_file, CNSS_DIAG_CONFIG_PATH))
Hsiu-Chang Chen769bef12020-10-10 06:07:52 +00002427 ad.adb.shell("find /data/vendor/wifi/cnss_diag/wlan_logs/ -type f -delete",
2428 ignore_status=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002429 ad.adb.shell("setprop %s true" % prop, ignore_status=True)
2430
Bindu Mahadevff295782019-02-08 16:17:48 -08002431
Girish Moturuddc0d382020-08-24 12:08:41 -07002432def stop_cnss_diags(ads, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002433 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002434 stop_cnss_diag(ad, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002435
Bindu Mahadevff295782019-02-08 16:17:48 -08002436
Girish Moturuddc0d382020-08-24 12:08:41 -07002437def stop_cnss_diag(ad, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002438 """Stops cnss_diag
2439
2440 Args:
2441 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002442 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002443 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002444 if ad.model not in pixel_models:
2445 ad.log.info("Device not supported to collect pixel logger")
2446 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002447 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2448 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2449 else:
2450 prop = wifi_constants.CNSS_DIAG_PROP
2451 ad.adb.shell("setprop %s false" % prop, ignore_status=True)
2452
Bindu Mahadevff295782019-02-08 16:17:48 -08002453
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002454def get_cnss_diag_log(ad):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002455 """Pulls the cnss_diag logs in the wlan_logs dir
2456 Args:
2457 ad: android device object.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002458 """
2459 logs = ad.get_file_names("/data/vendor/wifi/cnss_diag/wlan_logs/")
2460 if logs:
2461 ad.log.info("Pulling cnss_diag logs %s", logs)
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002462 log_path = os.path.join(ad.device_log_path, "CNSS_DIAG_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002463 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002464 ad.pull_files(logs, log_path)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002465
Bindu Mahadevff295782019-02-08 16:17:48 -08002466
David Sue4cd9c22019-03-26 18:07:26 -07002467LinkProbeResult = namedtuple('LinkProbeResult', (
2468 'is_success', 'stdout', 'elapsed_time', 'failure_reason'))
2469
2470
2471def send_link_probe(ad):
2472 """Sends a link probe to the currently connected AP, and returns whether the
2473 probe succeeded or not.
2474
2475 Args:
2476 ad: android device object
2477 Returns:
2478 LinkProbeResult namedtuple
2479 """
2480 stdout = ad.adb.shell('cmd wifi send-link-probe')
2481 asserts.assert_false('Error' in stdout or 'Exception' in stdout,
2482 'Exception while sending link probe: ' + stdout)
2483
2484 is_success = False
2485 elapsed_time = None
2486 failure_reason = None
2487 if 'succeeded' in stdout:
2488 is_success = True
2489 elapsed_time = next(
2490 (int(token) for token in stdout.split() if token.isdigit()), None)
2491 elif 'failed with reason' in stdout:
2492 failure_reason = next(
2493 (int(token) for token in stdout.split() if token.isdigit()), None)
2494 else:
2495 asserts.fail('Unexpected link probe result: ' + stdout)
2496
2497 return LinkProbeResult(
2498 is_success=is_success, stdout=stdout,
2499 elapsed_time=elapsed_time, failure_reason=failure_reason)
2500
2501
2502def send_link_probes(ad, num_probes, delay_sec):
2503 """Sends a sequence of link probes to the currently connected AP, and
2504 returns whether the probes succeeded or not.
2505
2506 Args:
2507 ad: android device object
2508 num_probes: number of probes to perform
2509 delay_sec: delay time between probes, in seconds
2510 Returns:
2511 List[LinkProbeResult] one LinkProbeResults for each probe
2512 """
2513 logging.info('Sending link probes')
2514 results = []
2515 for _ in range(num_probes):
2516 # send_link_probe() will also fail the test if it sees an exception
2517 # in the stdout of the adb shell command
2518 result = send_link_probe(ad)
2519 logging.info('link probe results: ' + str(result))
2520 results.append(result)
2521 time.sleep(delay_sec)
2522
2523 return results
2524
2525
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002526def ap_setup(test, index, ap, network, bandwidth=80, channel=6):
2527 """Set up the AP with provided network info.
2528
2529 Args:
2530 test: the calling test class object.
2531 index: int, index of the AP.
2532 ap: access_point object of the AP.
2533 network: dict with information of the network, including ssid,
2534 password and bssid.
2535 bandwidth: the operation bandwidth for the AP, default 80MHz.
2536 channel: the channel number for the AP.
2537 Returns:
2538 brconfigs: the bridge interface configs
2539 """
2540 bss_settings = []
2541 ssid = network[WifiEnums.SSID_KEY]
2542 test.access_points[index].close()
2543 time.sleep(5)
2544
2545 # Configure AP as required.
2546 if "password" in network.keys():
2547 password = network["password"]
2548 security = hostapd_security.Security(
2549 security_mode="wpa", password=password)
2550 else:
2551 security = hostapd_security.Security(security_mode=None, password=None)
2552 config = hostapd_ap_preset.create_ap_preset(
2553 channel=channel,
2554 ssid=ssid,
2555 security=security,
2556 bss_settings=bss_settings,
2557 vht_bandwidth=bandwidth,
2558 profile_name='whirlwind',
2559 iface_wlan_2g=ap.wlan_2g,
2560 iface_wlan_5g=ap.wlan_5g)
2561 ap.start_ap(config)
2562 logging.info("AP started on channel {} with SSID {}".format(channel, ssid))
Bindu Mahadevff295782019-02-08 16:17:48 -08002563
2564
2565def turn_ap_off(test, AP):
2566 """Bring down hostapd on the Access Point.
2567 Args:
2568 test: The test class object.
2569 AP: int, indicating which AP to turn OFF.
2570 """
2571 hostapd_2g = test.access_points[AP-1]._aps['wlan0'].hostapd
2572 if hostapd_2g.is_alive():
2573 hostapd_2g.stop()
2574 logging.debug('Turned WLAN0 AP%d off' % AP)
2575 hostapd_5g = test.access_points[AP-1]._aps['wlan1'].hostapd
2576 if hostapd_5g.is_alive():
2577 hostapd_5g.stop()
2578 logging.debug('Turned WLAN1 AP%d off' % AP)
2579
2580
2581def turn_ap_on(test, AP):
2582 """Bring up hostapd on the Access Point.
2583 Args:
2584 test: The test class object.
2585 AP: int, indicating which AP to turn ON.
2586 """
2587 hostapd_2g = test.access_points[AP-1]._aps['wlan0'].hostapd
2588 if not hostapd_2g.is_alive():
2589 hostapd_2g.start(hostapd_2g.config)
2590 logging.debug('Turned WLAN0 AP%d on' % AP)
2591 hostapd_5g = test.access_points[AP-1]._aps['wlan1'].hostapd
2592 if not hostapd_5g.is_alive():
2593 hostapd_5g.start(hostapd_5g.config)
2594 logging.debug('Turned WLAN1 AP%d on' % AP)
Joe Brennan48c3f692019-04-11 08:30:16 -07002595
2596
2597def turn_location_off_and_scan_toggle_off(ad):
2598 """Turns off wifi location scans."""
2599 utils.set_location_service(ad, False)
2600 ad.droid.wifiScannerToggleAlwaysAvailable(False)
2601 msg = "Failed to turn off location service's scan."
2602 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
Alfie Chen675be872020-06-04 10:48:14 +08002603
2604
2605def set_softap_channel(dut, ap_iface='wlan1', cs_count=10, channel=2462):
2606 """ Set SoftAP mode channel
2607
2608 Args:
2609 dut: android device object
2610 ap_iface: interface of SoftAP mode.
2611 cs_count: how many beacon frames before switch channel, default = 10
2612 channel: a wifi channel.
2613 """
2614 chan_switch_cmd = 'hostapd_cli -i {} chan_switch {} {}'
2615 chan_switch_cmd_show = chan_switch_cmd.format(ap_iface,cs_count,channel)
2616 dut.log.info('adb shell {}'.format(chan_switch_cmd_show))
2617 chan_switch_result = dut.adb.shell(chan_switch_cmd.format(ap_iface,
2618 cs_count,
2619 channel))
2620 if chan_switch_result == 'OK':
2621 dut.log.info('switch hotspot channel to {}'.format(channel))
2622 return chan_switch_result
2623
2624 asserts.fail("Failed to switch hotspot channel")
2625