blob: 1729a7cb990875494b5ebb4e507177dc088491be [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
“Alfie90ee7cb2021-04-20 23:16:12 +080023from retry import retry
24
David Sue4cd9c22019-03-26 18:07:26 -070025from collections import namedtuple
Ang Li73697b32015-12-03 00:41:53 +000026from enum import IntEnum
27from queue import Empty
28
Ang Li82522812016-06-02 13:57:21 -070029from acts import asserts
Xianyuan Jia0e39e552019-01-24 17:17:47 -080030from acts import context
Ang Li374d7602016-02-08 17:27:27 -080031from acts import signals
Ang Lifee28402016-07-13 13:43:29 -070032from acts import utils
Ang Li2d3fe982016-06-08 10:00:43 -070033from acts.controllers import attenuator
Bindu Mahadev7e5dc682019-02-01 16:53:34 -080034from acts.controllers.ap_lib import hostapd_security
35from acts.controllers.ap_lib import hostapd_ap_preset
Girish Moturucf4dccd2018-08-27 12:22:00 -070036from acts.controllers.ap_lib.hostapd_constants import BAND_2G
37from acts.controllers.ap_lib.hostapd_constants import BAND_5G
Roshan Pius5fd42eb2021-01-21 12:26:31 -080038from acts_contrib.test_utils.net import connectivity_const as cconsts
Xianyuan Jia63751fb2020-11-17 00:07:40 +000039from acts_contrib.test_utils.tel import tel_defines
Roshan Pius5fd42eb2021-01-21 12:26:31 -080040from acts_contrib.test_utils.wifi import wifi_constants
41from acts_contrib.test_utils.wifi.aware import aware_test_utils as autils
Ang Li73697b32015-12-03 00:41:53 +000042
Bindu Mahadev1d3991e2017-03-20 18:06:54 -070043# Default timeout used for reboot, toggle WiFi and Airplane mode,
44# for the system to settle down after the operation.
45DEFAULT_TIMEOUT = 10
Ang Li73697b32015-12-03 00:41:53 +000046# Number of seconds to wait for events that are supposed to happen quickly.
47# Like onSuccess for start background scan and confirmation on wifi state
48# change.
49SHORT_TIMEOUT = 30
Bindu Mahadev7060a9f2018-05-04 13:48:12 -070050ROAMING_TIMEOUT = 30
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -080051WIFI_CONNECTION_TIMEOUT_DEFAULT = 30
Ang Li73697b32015-12-03 00:41:53 +000052# Speed of light in m/s.
53SPEED_OF_LIGHT = 299792458
54
Qi Jiang8b443672018-03-16 14:46:50 -070055DEFAULT_PING_ADDR = "https://www.google.com/robots.txt"
Ang Li73697b32015-12-03 00:41:53 +000056
Girish Moturuddc0d382020-08-24 12:08:41 -070057CNSS_DIAG_CONFIG_PATH = "/data/vendor/wifi/cnss_diag/"
58CNSS_DIAG_CONFIG_FILE = "cnss_diag.conf"
59
Girish Moturu36348a32019-12-10 08:41:54 -080060ROAMING_ATTN = {
Omar El Ayach8c017902020-10-18 10:26:57 -070061 "AP1_on_AP2_off": [0, 0, 95, 95],
62 "AP1_off_AP2_on": [95, 95, 0, 0],
63 "default": [0, 0, 0, 0]
64}
Ang Li82522812016-06-02 13:57:21 -070065
Xianyuan Jia0e39e552019-01-24 17:17:47 -080066
Ang Li73697b32015-12-03 00:41:53 +000067class WifiEnums():
68
Omar El Ayach8c017902020-10-18 10:26:57 -070069 SSID_KEY = "SSID" # Used for Wifi & SoftAp
Roshan Piusc999e5e2018-11-09 10:59:52 -080070 SSID_PATTERN_KEY = "ssidPattern"
Bindu Mahadev4c94b532019-01-09 12:20:10 -080071 NETID_KEY = "network_id"
Omar El Ayach8c017902020-10-18 10:26:57 -070072 BSSID_KEY = "BSSID" # Used for Wifi & SoftAp
Roshan Piusc999e5e2018-11-09 10:59:52 -080073 BSSID_PATTERN_KEY = "bssidPattern"
Omar El Ayach8c017902020-10-18 10:26:57 -070074 PWD_KEY = "password" # Used for Wifi & SoftAp
Ang Li73697b32015-12-03 00:41:53 +000075 frequency_key = "frequency"
Omar El Ayach8c017902020-10-18 10:26:57 -070076 HIDDEN_KEY = "hiddenSSID" # Used for Wifi & SoftAp
Roshan Piusd1204442018-11-12 12:20:39 -080077 IS_APP_INTERACTION_REQUIRED = "isAppInteractionRequired"
78 IS_USER_INTERACTION_REQUIRED = "isUserInteractionRequired"
Roshan Pius55fb7c42020-04-03 14:47:18 -070079 IS_SUGGESTION_METERED = "isMetered"
Roshan Piusd1204442018-11-12 12:20:39 -080080 PRIORITY = "priority"
Omar El Ayach8c017902020-10-18 10:26:57 -070081 SECURITY = "security" # Used for Wifi & SoftAp
Ang Li73697b32015-12-03 00:41:53 +000082
leslce9cf6d2020-02-19 16:37:07 +080083 # Used for SoftAp
lesl6d30a172020-03-05 15:05:22 +080084 AP_BAND_KEY = "apBand"
85 AP_CHANNEL_KEY = "apChannel"
lesl67124362021-05-04 19:33:14 +080086 AP_BANDS_KEY = "apBands"
87 AP_CHANNEL_FREQUENCYS_KEY = "apChannelFrequencies"
88 AP_MAC_RANDOMIZATION_SETTING_KEY = "MacRandomizationSetting"
89 AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY = "BridgedModeOpportunisticShutdownEnabled"
90 AP_IEEE80211AX_ENABLED_KEY = "Ieee80211axEnabled"
lesl6d30a172020-03-05 15:05:22 +080091 AP_MAXCLIENTS_KEY = "MaxNumberOfClients"
92 AP_SHUTDOWNTIMEOUT_KEY = "ShutdownTimeoutMillis"
93 AP_SHUTDOWNTIMEOUTENABLE_KEY = "AutoShutdownEnabled"
94 AP_CLIENTCONTROL_KEY = "ClientControlByUserEnabled"
95 AP_ALLOWEDLIST_KEY = "AllowedClientList"
96 AP_BLOCKEDLIST_KEY = "BlockedClientList"
97
leslce9cf6d2020-02-19 16:37:07 +080098 WIFI_CONFIG_SOFTAP_BAND_2G = 1
99 WIFI_CONFIG_SOFTAP_BAND_5G = 2
100 WIFI_CONFIG_SOFTAP_BAND_2G_5G = 3
101 WIFI_CONFIG_SOFTAP_BAND_6G = 4
102 WIFI_CONFIG_SOFTAP_BAND_2G_6G = 5
103 WIFI_CONFIG_SOFTAP_BAND_5G_6G = 6
104 WIFI_CONFIG_SOFTAP_BAND_ANY = 7
105
106 # DO NOT USE IT for new test case! Replaced by WIFI_CONFIG_SOFTAP_BAND_
107 WIFI_CONFIG_APBAND_2G = WIFI_CONFIG_SOFTAP_BAND_2G
108 WIFI_CONFIG_APBAND_5G = WIFI_CONFIG_SOFTAP_BAND_5G
109 WIFI_CONFIG_APBAND_AUTO = WIFI_CONFIG_SOFTAP_BAND_2G_5G
110
111 WIFI_CONFIG_APBAND_2G_OLD = 0
112 WIFI_CONFIG_APBAND_5G_OLD = 1
113 WIFI_CONFIG_APBAND_AUTO_OLD = -1
Ang Li73697b32015-12-03 00:41:53 +0000114
Ang Li82522812016-06-02 13:57:21 -0700115 WIFI_WPS_INFO_PBC = 0
116 WIFI_WPS_INFO_DISPLAY = 1
117 WIFI_WPS_INFO_KEYPAD = 2
118 WIFI_WPS_INFO_LABEL = 3
119 WIFI_WPS_INFO_INVALID = 4
Ang Li73697b32015-12-03 00:41:53 +0000120
lesl6d30a172020-03-05 15:05:22 +0800121 class SoftApSecurityType():
122 OPEN = "NONE"
123 WPA2 = "WPA2_PSK"
124 WPA3_SAE_TRANSITION = "WPA3_SAE_TRANSITION"
125 WPA3_SAE = "WPA3_SAE"
126
Ang Li73697b32015-12-03 00:41:53 +0000127 class CountryCode():
Girish Moturue648b6a2021-03-04 13:52:15 -0800128 AUSTRALIA = "AU"
Ang Li73697b32015-12-03 00:41:53 +0000129 CHINA = "CN"
Girish Moturua5ef35d2020-10-19 14:58:01 -0700130 GERMANY = "DE"
Ang Li73697b32015-12-03 00:41:53 +0000131 JAPAN = "JP"
132 UK = "GB"
133 US = "US"
134 UNKNOWN = "UNKNOWN"
135
136 # Start of Macros for EAP
137 # EAP types
138 class Eap(IntEnum):
139 NONE = -1
140 PEAP = 0
Ang Li82522812016-06-02 13:57:21 -0700141 TLS = 1
Ang Li73697b32015-12-03 00:41:53 +0000142 TTLS = 2
Ang Li82522812016-06-02 13:57:21 -0700143 PWD = 3
144 SIM = 4
145 AKA = 5
146 AKA_PRIME = 6
147 UNAUTH_TLS = 7
Ang Li73697b32015-12-03 00:41:53 +0000148
149 # EAP Phase2 types
150 class EapPhase2(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700151 NONE = 0
152 PAP = 1
153 MSCHAP = 2
154 MSCHAPV2 = 3
155 GTC = 4
Ang Li73697b32015-12-03 00:41:53 +0000156
157 class Enterprise:
Ang Li82522812016-06-02 13:57:21 -0700158 # Enterprise Config Macros
159 EMPTY_VALUE = "NULL"
160 EAP = "eap"
161 PHASE2 = "phase2"
162 IDENTITY = "identity"
163 ANON_IDENTITY = "anonymous_identity"
164 PASSWORD = "password"
165 SUBJECT_MATCH = "subject_match"
Ang Li73697b32015-12-03 00:41:53 +0000166 ALTSUBJECT_MATCH = "altsubject_match"
167 DOM_SUFFIX_MATCH = "domain_suffix_match"
Ang Li82522812016-06-02 13:57:21 -0700168 CLIENT_CERT = "client_cert"
169 CA_CERT = "ca_cert"
170 ENGINE = "engine"
171 ENGINE_ID = "engine_id"
172 PRIVATE_KEY_ID = "key_id"
173 REALM = "realm"
174 PLMN = "plmn"
175 FQDN = "FQDN"
176 FRIENDLY_NAME = "providerFriendlyName"
177 ROAMING_IDS = "roamingConsortiumIds"
Jimmy Chen7baec622020-06-23 19:00:33 +0800178 OCSP = "ocsp"
Omar El Ayach8c017902020-10-18 10:26:57 -0700179
Ang Li73697b32015-12-03 00:41:53 +0000180 # End of Macros for EAP
181
182 # Macros for wifi p2p.
183 WIFI_P2P_SERVICE_TYPE_ALL = 0
184 WIFI_P2P_SERVICE_TYPE_BONJOUR = 1
185 WIFI_P2P_SERVICE_TYPE_UPNP = 2
186 WIFI_P2P_SERVICE_TYPE_VENDOR_SPECIFIC = 255
187
188 class ScanResult:
189 CHANNEL_WIDTH_20MHZ = 0
190 CHANNEL_WIDTH_40MHZ = 1
191 CHANNEL_WIDTH_80MHZ = 2
192 CHANNEL_WIDTH_160MHZ = 3
193 CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4
194
195 # Macros for wifi rtt.
196 class RttType(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700197 TYPE_ONE_SIDED = 1
198 TYPE_TWO_SIDED = 2
Ang Li73697b32015-12-03 00:41:53 +0000199
200 class RttPeerType(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700201 PEER_TYPE_AP = 1
202 PEER_TYPE_STA = 2 # Requires NAN.
203 PEER_P2P_GO = 3
204 PEER_P2P_CLIENT = 4
205 PEER_NAN = 5
Ang Li73697b32015-12-03 00:41:53 +0000206
207 class RttPreamble(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700208 PREAMBLE_LEGACY = 0x01
209 PREAMBLE_HT = 0x02
210 PREAMBLE_VHT = 0x04
Ang Li73697b32015-12-03 00:41:53 +0000211
212 class RttBW(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700213 BW_5_SUPPORT = 0x01
214 BW_10_SUPPORT = 0x02
215 BW_20_SUPPORT = 0x04
216 BW_40_SUPPORT = 0x08
217 BW_80_SUPPORT = 0x10
Ang Li73697b32015-12-03 00:41:53 +0000218 BW_160_SUPPORT = 0x20
219
220 class Rtt(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700221 STATUS_SUCCESS = 0
222 STATUS_FAILURE = 1
223 STATUS_FAIL_NO_RSP = 2
224 STATUS_FAIL_REJECTED = 3
225 STATUS_FAIL_NOT_SCHEDULED_YET = 4
226 STATUS_FAIL_TM_TIMEOUT = 5
227 STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6
228 STATUS_FAIL_NO_CAPABILITY = 7
229 STATUS_ABORTED = 8
230 STATUS_FAIL_INVALID_TS = 9
231 STATUS_FAIL_PROTOCOL = 10
232 STATUS_FAIL_SCHEDULE = 11
233 STATUS_FAIL_BUSY_TRY_LATER = 12
234 STATUS_INVALID_REQ = 13
235 STATUS_NO_WIFI = 14
236 STATUS_FAIL_FTM_PARAM_OVERRIDE = 15
Ang Li73697b32015-12-03 00:41:53 +0000237
Ang Li82522812016-06-02 13:57:21 -0700238 REASON_UNSPECIFIED = -1
239 REASON_NOT_AVAILABLE = -2
240 REASON_INVALID_LISTENER = -3
241 REASON_INVALID_REQUEST = -4
Ang Li73697b32015-12-03 00:41:53 +0000242
243 class RttParam:
244 device_type = "deviceType"
245 request_type = "requestType"
246 BSSID = "bssid"
247 channel_width = "channelWidth"
248 frequency = "frequency"
249 center_freq0 = "centerFreq0"
250 center_freq1 = "centerFreq1"
251 number_burst = "numberBurst"
252 interval = "interval"
253 num_samples_per_burst = "numSamplesPerBurst"
254 num_retries_per_measurement_frame = "numRetriesPerMeasurementFrame"
255 num_retries_per_FTMR = "numRetriesPerFTMR"
256 lci_request = "LCIRequest"
257 lcr_request = "LCRRequest"
258 burst_timeout = "burstTimeout"
259 preamble = "preamble"
260 bandwidth = "bandwidth"
261 margin = "margin"
262
263 RTT_MARGIN_OF_ERROR = {
264 RttBW.BW_80_SUPPORT: 2,
265 RttBW.BW_40_SUPPORT: 5,
266 RttBW.BW_20_SUPPORT: 5
267 }
268
269 # Macros as specified in the WifiScanner code.
Ang Li82522812016-06-02 13:57:21 -0700270 WIFI_BAND_UNSPECIFIED = 0 # not specified
271 WIFI_BAND_24_GHZ = 1 # 2.4 GHz band
272 WIFI_BAND_5_GHZ = 2 # 5 GHz band without DFS channels
273 WIFI_BAND_5_GHZ_DFS_ONLY = 4 # 5 GHz band with DFS channels
274 WIFI_BAND_5_GHZ_WITH_DFS = 6 # 5 GHz band with DFS channels
275 WIFI_BAND_BOTH = 3 # both bands without DFS channels
276 WIFI_BAND_BOTH_WITH_DFS = 7 # both bands with DFS channels
Ang Li73697b32015-12-03 00:41:53 +0000277
278 REPORT_EVENT_AFTER_BUFFER_FULL = 0
279 REPORT_EVENT_AFTER_EACH_SCAN = 1
280 REPORT_EVENT_FULL_SCAN_RESULT = 2
281
xshuaabcfeb2018-02-14 11:43:24 -0800282 SCAN_TYPE_LOW_LATENCY = 0
283 SCAN_TYPE_LOW_POWER = 1
284 SCAN_TYPE_HIGH_ACCURACY = 2
285
Ang Li73697b32015-12-03 00:41:53 +0000286 # US Wifi frequencies
Omar El Ayach8c017902020-10-18 10:26:57 -0700287 ALL_2G_FREQUENCIES = [
288 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462
289 ]
290 DFS_5G_FREQUENCIES = [
291 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640,
292 5660, 5680, 5700, 5720
293 ]
294 NONE_DFS_5G_FREQUENCIES = [
295 5180, 5200, 5220, 5240, 5745, 5765, 5785, 5805, 5825
296 ]
Ang Li73697b32015-12-03 00:41:53 +0000297 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
Alfie Chen4c96efe2021-05-21 20:48:54 +0800308 # TODO: add all of the band mapping.
309 softap_band_frequencies = {
310 WIFI_CONFIG_SOFTAP_BAND_2G: ALL_2G_FREQUENCIES,
311 WIFI_CONFIG_SOFTAP_BAND_5G: ALL_5G_FREQUENCIES
312 }
313
Ang Li73697b32015-12-03 00:41:53 +0000314 # All Wifi frequencies to channels lookup.
315 freq_to_channel = {
316 2412: 1,
317 2417: 2,
318 2422: 3,
319 2427: 4,
320 2432: 5,
321 2437: 6,
322 2442: 7,
323 2447: 8,
324 2452: 9,
325 2457: 10,
326 2462: 11,
327 2467: 12,
328 2472: 13,
329 2484: 14,
330 4915: 183,
331 4920: 184,
332 4925: 185,
333 4935: 187,
334 4940: 188,
335 4945: 189,
336 4960: 192,
337 4980: 196,
338 5035: 7,
339 5040: 8,
340 5045: 9,
341 5055: 11,
342 5060: 12,
343 5080: 16,
344 5170: 34,
345 5180: 36,
346 5190: 38,
347 5200: 40,
348 5210: 42,
349 5220: 44,
350 5230: 46,
351 5240: 48,
352 5260: 52,
353 5280: 56,
354 5300: 60,
355 5320: 64,
356 5500: 100,
357 5520: 104,
358 5540: 108,
359 5560: 112,
360 5580: 116,
361 5600: 120,
362 5620: 124,
363 5640: 128,
364 5660: 132,
365 5680: 136,
366 5700: 140,
367 5745: 149,
368 5765: 153,
369 5785: 157,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700370 5795: 159,
Ang Li73697b32015-12-03 00:41:53 +0000371 5805: 161,
372 5825: 165,
373 }
374
375 # All Wifi channels to frequencies lookup.
376 channel_2G_to_freq = {
377 1: 2412,
378 2: 2417,
379 3: 2422,
380 4: 2427,
381 5: 2432,
382 6: 2437,
383 7: 2442,
384 8: 2447,
385 9: 2452,
386 10: 2457,
387 11: 2462,
388 12: 2467,
389 13: 2472,
390 14: 2484
391 }
392
393 channel_5G_to_freq = {
394 183: 4915,
395 184: 4920,
396 185: 4925,
397 187: 4935,
398 188: 4940,
399 189: 4945,
400 192: 4960,
401 196: 4980,
402 7: 5035,
403 8: 5040,
404 9: 5045,
405 11: 5055,
406 12: 5060,
407 16: 5080,
408 34: 5170,
409 36: 5180,
410 38: 5190,
411 40: 5200,
412 42: 5210,
413 44: 5220,
414 46: 5230,
415 48: 5240,
Omar El Ayach8c017902020-10-18 10:26:57 -0700416 50: 5250,
Ang Li73697b32015-12-03 00:41:53 +0000417 52: 5260,
418 56: 5280,
419 60: 5300,
420 64: 5320,
421 100: 5500,
422 104: 5520,
423 108: 5540,
424 112: 5560,
425 116: 5580,
426 120: 5600,
427 124: 5620,
428 128: 5640,
429 132: 5660,
430 136: 5680,
431 140: 5700,
432 149: 5745,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700433 151: 5755,
Ang Li73697b32015-12-03 00:41:53 +0000434 153: 5765,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700435 155: 5775,
Ang Li73697b32015-12-03 00:41:53 +0000436 157: 5785,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700437 159: 5795,
Ang Li73697b32015-12-03 00:41:53 +0000438 161: 5805,
439 165: 5825
440 }
441
Ang Li82522812016-06-02 13:57:21 -0700442
Ang Li73697b32015-12-03 00:41:53 +0000443class WifiChannelBase:
444 ALL_2G_FREQUENCIES = []
445 DFS_5G_FREQUENCIES = []
446 NONE_DFS_5G_FREQUENCIES = []
447 ALL_5G_FREQUENCIES = DFS_5G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES
448 MIX_CHANNEL_SCAN = []
449
450 def band_to_freq(self, band):
451 _band_to_frequencies = {
Omar El Ayach8c017902020-10-18 10:26:57 -0700452 WifiEnums.WIFI_BAND_24_GHZ:
453 self.ALL_2G_FREQUENCIES,
454 WifiEnums.WIFI_BAND_5_GHZ:
455 self.NONE_DFS_5G_FREQUENCIES,
456 WifiEnums.WIFI_BAND_5_GHZ_DFS_ONLY:
457 self.DFS_5G_FREQUENCIES,
458 WifiEnums.WIFI_BAND_5_GHZ_WITH_DFS:
459 self.ALL_5G_FREQUENCIES,
Ang Li82522812016-06-02 13:57:21 -0700460 WifiEnums.WIFI_BAND_BOTH:
461 self.ALL_2G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES,
462 WifiEnums.WIFI_BAND_BOTH_WITH_DFS:
463 self.ALL_5G_FREQUENCIES + self.ALL_2G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000464 }
465 return _band_to_frequencies[band]
466
Ang Li82522812016-06-02 13:57:21 -0700467
Ang Li73697b32015-12-03 00:41:53 +0000468class WifiChannelUS(WifiChannelBase):
469 # US Wifi frequencies
Omar El Ayach8c017902020-10-18 10:26:57 -0700470 ALL_2G_FREQUENCIES = [
471 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462
472 ]
473 NONE_DFS_5G_FREQUENCIES = [
474 5180, 5200, 5220, 5240, 5745, 5765, 5785, 5805, 5825
475 ]
476 MIX_CHANNEL_SCAN = [
477 2412, 2437, 2462, 5180, 5200, 5280, 5260, 5300, 5500, 5320, 5520, 5560,
478 5700, 5745, 5805
479 ]
Ang Li73697b32015-12-03 00:41:53 +0000480
“Sandy04280f82021-07-23 17:08:52 +0800481 def __init__(self, model=None, support_addition_channel=[]):
482 if model in support_addition_channel:
483 self.ALL_2G_FREQUENCIES = [
484 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457,
485 2462, 2467, 2472
486 ]
Omar El Ayach8c017902020-10-18 10:26:57 -0700487 self.DFS_5G_FREQUENCIES = [
488 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620,
489 5640, 5660, 5680, 5700, 5720
“Sandy04280f82021-07-23 17:08:52 +0800490 ]
Girish Moturu0c567b02017-08-11 16:20:01 -0700491 self.ALL_5G_FREQUENCIES = self.DFS_5G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000492
Bindu Mahadevff295782019-02-08 16:17:48 -0800493
Girish Moturuf02fa1d2017-05-21 09:51:23 +0530494class WifiReferenceNetworks:
495 """ Class to parse and return networks of different band and
496 auth type from reference_networks
497 """
498 def __init__(self, obj):
499 self.reference_networks = obj
500 self.WIFI_2G = "2g"
501 self.WIFI_5G = "5g"
502
503 self.secure_networks_2g = []
504 self.secure_networks_5g = []
505 self.open_networks_2g = []
506 self.open_networks_5g = []
507 self._parse_networks()
508
509 def _parse_networks(self):
510 for network in self.reference_networks:
511 for key in network:
512 if key == self.WIFI_2G:
513 if "password" in network[key]:
514 self.secure_networks_2g.append(network[key])
515 else:
516 self.open_networks_2g.append(network[key])
517 else:
518 if "password" in network[key]:
519 self.secure_networks_5g.append(network[key])
520 else:
521 self.open_networks_5g.append(network[key])
522
523 def return_2g_secure_networks(self):
524 return self.secure_networks_2g
525
526 def return_5g_secure_networks(self):
527 return self.secure_networks_5g
528
529 def return_2g_open_networks(self):
530 return self.open_networks_2g
531
532 def return_5g_open_networks(self):
533 return self.open_networks_5g
534
535 def return_secure_networks(self):
536 return self.secure_networks_2g + self.secure_networks_5g
537
538 def return_open_networks(self):
539 return self.open_networks_2g + self.open_networks_5g
540
Ang Li82522812016-06-02 13:57:21 -0700541
542def _assert_on_fail_handler(func, assert_on_fail, *args, **kwargs):
543 """Wrapper function that handles the bahevior of assert_on_fail.
544
545 When assert_on_fail is True, let all test signals through, which can
546 terminate test cases directly. When assert_on_fail is False, the wrapper
547 raises no test signals and reports operation status by returning True or
548 False.
549
550 Args:
551 func: The function to wrap. This function reports operation status by
552 raising test signals.
553 assert_on_fail: A boolean that specifies if the output of the wrapper
554 is test signal based or return value based.
555 args: Positional args for func.
556 kwargs: Name args for func.
557
558 Returns:
559 If assert_on_fail is True, returns True/False to signal operation
560 status, otherwise return nothing.
561 """
562 try:
563 func(*args, **kwargs)
564 if not assert_on_fail:
565 return True
566 except signals.TestSignal:
567 if assert_on_fail:
568 raise
569 return False
570
571
572def assert_network_in_list(target, network_list):
573 """Makes sure a specified target Wi-Fi network exists in a list of Wi-Fi
574 networks.
575
576 Args:
577 target: A dict representing a Wi-Fi network.
578 E.g. {WifiEnums.SSID_KEY: "SomeNetwork"}
579 network_list: A list of dicts, each representing a Wi-Fi network.
580 """
581 match_results = match_networks(target, network_list)
582 asserts.assert_true(
583 match_results, "Target network %s, does not exist in network list %s" %
584 (target, network_list))
585
586
Ang Li73697b32015-12-03 00:41:53 +0000587def match_networks(target_params, networks):
588 """Finds the WiFi networks that match a given set of parameters in a list
589 of WiFi networks.
590
Girish Moturubc48d9f2016-11-01 13:24:14 -0700591 To be considered a match, the network should contain every key-value pair
592 of target_params
Ang Li73697b32015-12-03 00:41:53 +0000593
594 Args:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700595 target_params: A dict with 1 or more key-value pairs representing a Wi-Fi network.
596 E.g { 'SSID': 'wh_ap1_5g', 'BSSID': '30:b5:c2:33:e4:47' }
Ang Li73697b32015-12-03 00:41:53 +0000597 networks: A list of dict objects representing WiFi networks.
598
599 Returns:
600 The networks that match the target parameters.
601 """
602 results = []
Betty Zhou3caa0982017-02-22 19:26:20 -0800603 asserts.assert_true(target_params,
604 "Expected networks object 'target_params' is empty")
Ang Li73697b32015-12-03 00:41:53 +0000605 for n in networks:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700606 add_network = 1
Ang Li9a66de72016-02-08 15:26:38 -0800607 for k, v in target_params.items():
608 if k not in n:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700609 add_network = 0
610 break
Ang Li9a66de72016-02-08 15:26:38 -0800611 if n[k] != v:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700612 add_network = 0
613 break
614 if add_network:
Ang Li73697b32015-12-03 00:41:53 +0000615 results.append(n)
616 return results
617
Bindu Mahadevff295782019-02-08 16:17:48 -0800618
Roshan Pius93b519c2018-05-09 12:07:11 -0700619def wait_for_wifi_state(ad, state, assert_on_fail=True):
620 """Waits for the device to transition to the specified wifi state
621
622 Args:
623 ad: An AndroidDevice object.
624 state: Wifi state to wait for.
625 assert_on_fail: If True, error checks in this function will raise test
626 failure signals.
627
628 Returns:
629 If assert_on_fail is False, function returns True if the device transitions
630 to the specified state, False otherwise. If assert_on_fail is True, no return value.
631 """
Omar El Ayach8c017902020-10-18 10:26:57 -0700632 return _assert_on_fail_handler(_wait_for_wifi_state,
633 assert_on_fail,
634 ad,
635 state=state)
Roshan Pius93b519c2018-05-09 12:07:11 -0700636
637
638def _wait_for_wifi_state(ad, state):
639 """Toggles the state of wifi.
640
641 TestFailure signals are raised when something goes wrong.
642
643 Args:
644 ad: An AndroidDevice object.
645 state: Wifi state to wait for.
646 """
647 if state == ad.droid.wifiCheckState():
648 # Check if the state is already achieved, so we don't wait for the
649 # state change event by mistake.
650 return
651 ad.droid.wifiStartTrackingStateChange()
Omar El Ayach8c017902020-10-18 10:26:57 -0700652 fail_msg = "Device did not transition to Wi-Fi state to %s on %s." % (
653 state, ad.serial)
Roshan Pius93b519c2018-05-09 12:07:11 -0700654 try:
655 ad.ed.wait_for_event(wifi_constants.WIFI_STATE_CHANGED,
656 lambda x: x["data"]["enabled"] == state,
657 SHORT_TIMEOUT)
658 except Empty:
659 asserts.assert_equal(state, ad.droid.wifiCheckState(), fail_msg)
660 finally:
661 ad.droid.wifiStopTrackingStateChange()
Ang Li82522812016-06-02 13:57:21 -0700662
Bindu Mahadevff295782019-02-08 16:17:48 -0800663
Ang Li82522812016-06-02 13:57:21 -0700664def wifi_toggle_state(ad, new_state=None, assert_on_fail=True):
Ang Li6b557182015-11-11 17:19:17 -0800665 """Toggles the state of wifi.
Ang Li73697b32015-12-03 00:41:53 +0000666
Ang Li6b557182015-11-11 17:19:17 -0800667 Args:
668 ad: An AndroidDevice object.
669 new_state: Wifi state to set to. If None, opposite of the current state.
Ang Li82522812016-06-02 13:57:21 -0700670 assert_on_fail: If True, error checks in this function will raise test
671 failure signals.
Ang Li73697b32015-12-03 00:41:53 +0000672
Ang Li6b557182015-11-11 17:19:17 -0800673 Returns:
Ang Li82522812016-06-02 13:57:21 -0700674 If assert_on_fail is False, function returns True if the toggle was
675 successful, False otherwise. If assert_on_fail is True, no return value.
676 """
Omar El Ayach8c017902020-10-18 10:26:57 -0700677 return _assert_on_fail_handler(_wifi_toggle_state,
678 assert_on_fail,
679 ad,
680 new_state=new_state)
Ang Li82522812016-06-02 13:57:21 -0700681
682
683def _wifi_toggle_state(ad, new_state=None):
684 """Toggles the state of wifi.
685
686 TestFailure signals are raised when something goes wrong.
687
688 Args:
689 ad: An AndroidDevice object.
690 new_state: The state to set Wi-Fi to. If None, opposite of the current
691 state will be set.
Ang Li6b557182015-11-11 17:19:17 -0800692 """
Ang Li31b00782016-06-21 13:04:23 -0700693 if new_state is None:
694 new_state = not ad.droid.wifiCheckState()
Ang Lie5c85c92016-07-27 15:38:09 -0700695 elif new_state == ad.droid.wifiCheckState():
696 # Check if the new_state is already achieved, so we don't wait for the
697 # state change event by mistake.
698 return
699 ad.droid.wifiStartTrackingStateChange()
Ang Li31b00782016-06-21 13:04:23 -0700700 ad.log.info("Setting Wi-Fi state to %s.", new_state)
Roshan Pius5a027fa2018-05-04 13:59:38 -0700701 ad.ed.clear_all_events()
Ang Li31b00782016-06-21 13:04:23 -0700702 # Setting wifi state.
Ang Li6b557182015-11-11 17:19:17 -0800703 ad.droid.wifiToggleState(new_state)
Jaineel3bd9bea2019-12-13 12:44:17 -0800704 time.sleep(2)
Ang Lie2e93a22016-06-22 16:43:28 -0700705 fail_msg = "Failed to set Wi-Fi state to %s on %s." % (new_state,
706 ad.serial)
Ang Li73697b32015-12-03 00:41:53 +0000707 try:
Roshan Pius5a027fa2018-05-04 13:59:38 -0700708 ad.ed.wait_for_event(wifi_constants.WIFI_STATE_CHANGED,
709 lambda x: x["data"]["enabled"] == new_state,
710 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +0000711 except Empty:
Ang Li82522812016-06-02 13:57:21 -0700712 asserts.assert_equal(new_state, ad.droid.wifiCheckState(), fail_msg)
Ang Li6b557182015-11-11 17:19:17 -0800713 finally:
714 ad.droid.wifiStopTrackingStateChange()
715
Ang Li82522812016-06-02 13:57:21 -0700716
Ang Li6b557182015-11-11 17:19:17 -0800717def reset_wifi(ad):
Ang Li1179fa72016-06-16 09:44:06 -0700718 """Clears all saved Wi-Fi networks on a device.
719
720 This will turn Wi-Fi on.
Ang Li6b557182015-11-11 17:19:17 -0800721
722 Args:
723 ad: An AndroidDevice object.
724
Ang Li6b557182015-11-11 17:19:17 -0800725 """
Ang Li6b557182015-11-11 17:19:17 -0800726 networks = ad.droid.wifiGetConfiguredNetworks()
727 if not networks:
728 return
Hsiu-Chang Chen7830de22021-08-11 20:41:29 +0800729 removed = []
Ang Li6b557182015-11-11 17:19:17 -0800730 for n in networks:
Hsiu-Chang Chen7830de22021-08-11 20:41:29 +0800731 if n['networkId'] not in removed:
732 ad.droid.wifiForgetNetwork(n['networkId'])
733 removed.append(n['networkId'])
734 else:
735 continue
Ang Li6b557182015-11-11 17:19:17 -0800736 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800737 event = ad.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS,
Ang Li82522812016-06-02 13:57:21 -0700738 SHORT_TIMEOUT)
Ang Li6b557182015-11-11 17:19:17 -0800739 except Empty:
Ang Li1179fa72016-06-16 09:44:06 -0700740 logging.warning("Could not confirm the removal of network %s.", n)
741 # Check again to see if there's any network left.
Betty Zhou3caa0982017-02-22 19:26:20 -0800742 asserts.assert_true(
743 not ad.droid.wifiGetConfiguredNetworks(),
744 "Failed to remove these configured Wi-Fi networks: %s" % networks)
Ang Li82522812016-06-02 13:57:21 -0700745
Ang Li73697b32015-12-03 00:41:53 +0000746
jerrypcchen49f629f2021-10-06 15:18:58 +0800747
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700748def toggle_airplane_mode_on_and_off(ad):
749 """Turn ON and OFF Airplane mode.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800750
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700751 ad: An AndroidDevice object.
752 Returns: Assert if turning on/off Airplane mode fails.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800753
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700754 """
755 ad.log.debug("Toggling Airplane mode ON.")
Omar El Ayach8c017902020-10-18 10:26:57 -0700756 asserts.assert_true(utils.force_airplane_mode(ad, True),
757 "Can not turn on airplane mode on: %s" % ad.serial)
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700758 time.sleep(DEFAULT_TIMEOUT)
759 ad.log.debug("Toggling Airplane mode OFF.")
Omar El Ayach8c017902020-10-18 10:26:57 -0700760 asserts.assert_true(utils.force_airplane_mode(ad, False),
761 "Can not turn on airplane mode on: %s" % ad.serial)
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700762 time.sleep(DEFAULT_TIMEOUT)
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800763
764
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700765def toggle_wifi_off_and_on(ad):
766 """Turn OFF and ON WiFi.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800767
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700768 ad: An AndroidDevice object.
769 Returns: Assert if turning off/on WiFi fails.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800770
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700771 """
772 ad.log.debug("Toggling wifi OFF.")
773 wifi_toggle_state(ad, False)
774 time.sleep(DEFAULT_TIMEOUT)
775 ad.log.debug("Toggling wifi ON.")
776 wifi_toggle_state(ad, True)
777 time.sleep(DEFAULT_TIMEOUT)
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800778
779
Ang Li73697b32015-12-03 00:41:53 +0000780def wifi_forget_network(ad, net_ssid):
Ang Li8e767182015-12-09 17:29:24 -0800781 """Remove configured Wifi network on an android device.
Ang Li73697b32015-12-03 00:41:53 +0000782
Ang Li8e767182015-12-09 17:29:24 -0800783 Args:
784 ad: android_device object for forget network.
785 net_ssid: ssid of network to be forget
Ang Li73697b32015-12-03 00:41:53 +0000786
Ang Li8e767182015-12-09 17:29:24 -0800787 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700788 networks = ad.droid.wifiGetConfiguredNetworks()
Ang Li8e767182015-12-09 17:29:24 -0800789 if not networks:
790 return
Hsiu-Chang Chen7830de22021-08-11 20:41:29 +0800791 removed = []
Ang Li8e767182015-12-09 17:29:24 -0800792 for n in networks:
Hsiu-Chang Chen7830de22021-08-11 20:41:29 +0800793 if net_ssid in n[WifiEnums.SSID_KEY] and n['networkId'] not in removed:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700794 ad.droid.wifiForgetNetwork(n['networkId'])
Hsiu-Chang Chen7830de22021-08-11 20:41:29 +0800795 removed.append(n['networkId'])
Ang Li8e767182015-12-09 17:29:24 -0800796 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800797 event = ad.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS,
Betty Zhou3caa0982017-02-22 19:26:20 -0800798 SHORT_TIMEOUT)
Ang Li8e767182015-12-09 17:29:24 -0800799 except Empty:
Girish Moturu1bf82302016-11-01 13:27:00 -0700800 asserts.fail("Failed to remove network %s." % n)
Jimmy Chen8e40e152021-05-06 14:37:18 +0800801 break
Ang Li73697b32015-12-03 00:41:53 +0000802
Ang Li82522812016-06-02 13:57:21 -0700803
Ang Li73697b32015-12-03 00:41:53 +0000804def wifi_test_device_init(ad):
805 """Initializes an android device for wifi testing.
806
807 0. Make sure SL4A connection is established on the android device.
808 1. Disable location service's WiFi scan.
809 2. Turn WiFi on.
810 3. Clear all saved networks.
811 4. Set country code to US.
812 5. Enable WiFi verbose logging.
813 6. Sync device time with computer time.
814 7. Turn off cellular data.
Ang Lifee28402016-07-13 13:43:29 -0700815 8. Turn off ambient display.
Ang Li73697b32015-12-03 00:41:53 +0000816 """
Ang Lifee28402016-07-13 13:43:29 -0700817 utils.require_sl4a((ad, ))
Ang Li73697b32015-12-03 00:41:53 +0000818 ad.droid.wifiScannerToggleAlwaysAvailable(False)
819 msg = "Failed to turn off location service's scan."
Ang Li82522812016-06-02 13:57:21 -0700820 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
821 wifi_toggle_state(ad, True)
Ang Li6b557182015-11-11 17:19:17 -0800822 reset_wifi(ad)
Ang Li73697b32015-12-03 00:41:53 +0000823 ad.droid.wifiEnableVerboseLogging(1)
Ang Li8e767182015-12-09 17:29:24 -0800824 msg = "Failed to enable WiFi verbose logging."
Ang Li82522812016-06-02 13:57:21 -0700825 asserts.assert_equal(ad.droid.wifiGetVerboseLoggingLevel(), 1, msg)
Ang Li73697b32015-12-03 00:41:53 +0000826 # We don't verify the following settings since they are not critical.
Ang Lie2e93a22016-06-22 16:43:28 -0700827 # Set wpa_supplicant log level to EXCESSIVE.
Omar El Ayach8c017902020-10-18 10:26:57 -0700828 output = ad.adb.shell(
829 "wpa_cli -i wlan0 -p -g@android:wpa_wlan0 IFNAME="
830 "wlan0 log_level EXCESSIVE",
831 ignore_status=True)
Ang Lie2e93a22016-06-22 16:43:28 -0700832 ad.log.info("wpa_supplicant log change status: %s", output)
Ang Lifee28402016-07-13 13:43:29 -0700833 utils.sync_device_time(ad)
Ang Li0bf8e022016-01-04 17:34:48 -0800834 ad.droid.telephonyToggleDataConnection(False)
Roshan Pius48df08c2019-09-13 08:07:30 -0700835 set_wifi_country_code(ad, WifiEnums.CountryCode.US)
Ang Lifee28402016-07-13 13:43:29 -0700836 utils.set_ambient_display(ad, False)
Ang Li73697b32015-12-03 00:41:53 +0000837
Omar El Ayach8c017902020-10-18 10:26:57 -0700838
Roshan Pius48df08c2019-09-13 08:07:30 -0700839def set_wifi_country_code(ad, country_code):
840 """Sets the wifi country code on the device.
841
842 Args:
843 ad: An AndroidDevice object.
844 country_code: 2 letter ISO country code
codycaldwell35b87182020-01-16 14:08:01 -0800845
846 Raises:
847 An RpcException if unable to set the country code.
Roshan Pius48df08c2019-09-13 08:07:30 -0700848 """
Jaineelc5b56a62019-10-10 17:12:02 -0700849 try:
codycaldwell35b87182020-01-16 14:08:01 -0800850 ad.adb.shell("cmd wifi force-country-code enabled %s" % country_code)
Jaineel Mehtacbad5cc2020-11-19 21:38:18 +0000851 except Exception as e:
Jaineelc5b56a62019-10-10 17:12:02 -0700852 ad.droid.wifiSetCountryCode(WifiEnums.CountryCode.US)
Roshan Pius48df08c2019-09-13 08:07:30 -0700853
Ang Li82522812016-06-02 13:57:21 -0700854
Ang Li6b557182015-11-11 17:19:17 -0800855def start_wifi_connection_scan(ad):
Ang Li73697b32015-12-03 00:41:53 +0000856 """Starts a wifi connection scan and wait for results to become available.
857
858 Args:
Ang Li6b557182015-11-11 17:19:17 -0800859 ad: An AndroidDevice object.
Ang Li73697b32015-12-03 00:41:53 +0000860 """
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800861 ad.ed.clear_all_events()
Ang Li6b557182015-11-11 17:19:17 -0800862 ad.droid.wifiStartScan()
Ang Li82522812016-06-02 13:57:21 -0700863 try:
864 ad.ed.pop_event("WifiManagerScanResultsAvailable", 60)
865 except Empty:
866 asserts.fail("Wi-Fi results did not become available within 60s.")
867
Ang Li73697b32015-12-03 00:41:53 +0000868
Roshan Piuscb9bc482018-02-01 14:27:09 -0800869def start_wifi_connection_scan_and_return_status(ad):
870 """
871 Starts a wifi connection scan and wait for results to become available
872 or a scan failure to be reported.
873
874 Args:
875 ad: An AndroidDevice object.
876 Returns:
877 True: if scan succeeded & results are available
878 False: if scan failed
879 """
880 ad.ed.clear_all_events()
881 ad.droid.wifiStartScan()
882 try:
Omar El Ayach8c017902020-10-18 10:26:57 -0700883 events = ad.ed.pop_events("WifiManagerScan(ResultsAvailable|Failure)",
884 60)
Roshan Piuscb9bc482018-02-01 14:27:09 -0800885 except Empty:
886 asserts.fail(
887 "Wi-Fi scan results/failure did not become available within 60s.")
888 # If there are multiple matches, we check for atleast one success.
889 for event in events:
890 if event["name"] == "WifiManagerScanResultsAvailable":
891 return True
892 elif event["name"] == "WifiManagerScanFailure":
893 ad.log.debug("Scan failure received")
894 return False
895
896
Omar El Ayach8c017902020-10-18 10:26:57 -0700897def start_wifi_connection_scan_and_check_for_network(ad,
898 network_ssid,
Roshan Piuscb9bc482018-02-01 14:27:09 -0800899 max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800900 """
901 Start connectivity scans & checks if the |network_ssid| is seen in
902 scan results. The method performs a max of |max_tries| connectivity scans
903 to find the network.
904
905 Args:
906 ad: An AndroidDevice object.
907 network_ssid: SSID of the network we are looking for.
908 max_tries: Number of scans to try.
909 Returns:
910 True: if network_ssid is found in scan results.
911 False: if network_ssid is not found in scan results.
912 """
jerrypcchen5cc385d2021-03-11 11:57:21 +0000913 start_time = time.time()
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800914 for num_tries in range(max_tries):
Roshan Piuscb9bc482018-02-01 14:27:09 -0800915 if start_wifi_connection_scan_and_return_status(ad):
916 scan_results = ad.droid.wifiGetScanResults()
Omar El Ayach8c017902020-10-18 10:26:57 -0700917 match_results = match_networks({WifiEnums.SSID_KEY: network_ssid},
918 scan_results)
Roshan Piuscb9bc482018-02-01 14:27:09 -0800919 if len(match_results) > 0:
jerrypcchen5cc385d2021-03-11 11:57:21 +0000920 ad.log.debug("Found network in %s seconds." %
921 (time.time() - start_time))
Roshan Piuscb9bc482018-02-01 14:27:09 -0800922 return True
jerrypcchen5cc385d2021-03-11 11:57:21 +0000923 ad.log.debug("Did not find network in %s seconds." %
924 (time.time() - start_time))
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800925 return False
926
927
Omar El Ayach8c017902020-10-18 10:26:57 -0700928def start_wifi_connection_scan_and_ensure_network_found(
929 ad, network_ssid, max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800930 """
931 Start connectivity scans & ensure the |network_ssid| is seen in
932 scan results. The method performs a max of |max_tries| connectivity scans
933 to find the network.
934 This method asserts on failure!
935
936 Args:
937 ad: An AndroidDevice object.
938 network_ssid: SSID of the network we are looking for.
939 max_tries: Number of scans to try.
940 """
941 ad.log.info("Starting scans to ensure %s is present", network_ssid)
942 assert_msg = "Failed to find " + network_ssid + " in scan results" \
943 " after " + str(max_tries) + " tries"
Omar El Ayach8c017902020-10-18 10:26:57 -0700944 asserts.assert_true(
945 start_wifi_connection_scan_and_check_for_network(
946 ad, network_ssid, max_tries), assert_msg)
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800947
948
Omar El Ayach8c017902020-10-18 10:26:57 -0700949def start_wifi_connection_scan_and_ensure_network_not_found(
950 ad, network_ssid, max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800951 """
952 Start connectivity scans & ensure the |network_ssid| is not seen in
953 scan results. The method performs a max of |max_tries| connectivity scans
954 to find the network.
955 This method asserts on failure!
956
957 Args:
958 ad: An AndroidDevice object.
959 network_ssid: SSID of the network we are looking for.
960 max_tries: Number of scans to try.
961 """
962 ad.log.info("Starting scans to ensure %s is not present", network_ssid)
963 assert_msg = "Found " + network_ssid + " in scan results" \
964 " after " + str(max_tries) + " tries"
Omar El Ayach8c017902020-10-18 10:26:57 -0700965 asserts.assert_false(
966 start_wifi_connection_scan_and_check_for_network(
967 ad, network_ssid, max_tries), assert_msg)
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800968
969
Ang Li73697b32015-12-03 00:41:53 +0000970def start_wifi_background_scan(ad, scan_setting):
971 """Starts wifi background scan.
972
973 Args:
974 ad: android_device object to initiate connection on.
975 scan_setting: A dict representing the settings of the scan.
976
977 Returns:
978 If scan was started successfully, event data of success event is returned.
979 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700980 idx = ad.droid.wifiScannerStartBackgroundScan(scan_setting)
981 event = ad.ed.pop_event("WifiScannerScan{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -0800982 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +0000983 return event['data']
984
Ang Li82522812016-06-02 13:57:21 -0700985
Girish Moturu38b993c2021-03-25 13:03:50 -0700986def start_wifi_tethering(ad, ssid, password, band=None, hidden=None,
987 security=None):
Ang Li73697b32015-12-03 00:41:53 +0000988 """Starts wifi tethering on an android_device.
989
990 Args:
991 ad: android_device to start wifi tethering on.
992 ssid: The SSID the soft AP should broadcast.
993 password: The password the soft AP should use.
994 band: The band the soft AP should be set on. It should be either
995 WifiEnums.WIFI_CONFIG_APBAND_2G or WifiEnums.WIFI_CONFIG_APBAND_5G.
Roshan Piusce821342018-01-10 11:03:04 -0800996 hidden: boolean to indicate if the AP needs to be hidden or not.
Girish Moturu38b993c2021-03-25 13:03:50 -0700997 security: security type of softap.
Ang Li73697b32015-12-03 00:41:53 +0000998
999 Returns:
Girish Moturu3581d612016-11-02 15:08:51 -07001000 No return value. Error checks in this function will raise test failure signals
Ang Li73697b32015-12-03 00:41:53 +00001001 """
Ang Li82522812016-06-02 13:57:21 -07001002 config = {WifiEnums.SSID_KEY: ssid}
Ang Li73697b32015-12-03 00:41:53 +00001003 if password:
1004 config[WifiEnums.PWD_KEY] = password
1005 if band:
lesl6d30a172020-03-05 15:05:22 +08001006 config[WifiEnums.AP_BAND_KEY] = band
Roshan Piusce821342018-01-10 11:03:04 -08001007 if hidden:
Omar El Ayach8c017902020-10-18 10:26:57 -07001008 config[WifiEnums.HIDDEN_KEY] = hidden
Girish Moturu38b993c2021-03-25 13:03:50 -07001009 if security:
1010 config[WifiEnums.SECURITY] = security
Omar El Ayach8c017902020-10-18 10:26:57 -07001011 asserts.assert_true(ad.droid.wifiSetWifiApConfiguration(config),
1012 "Failed to update WifiAp Configuration")
Girish Moturu40d7dc22016-11-02 12:14:56 -07001013 ad.droid.wifiStartTrackingTetherStateChange()
1014 ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001015 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001016 ad.ed.pop_event("ConnectivityManagerOnTetheringStarted")
1017 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -08001018 lambda x: x["data"]["ACTIVE_TETHER"], 30)
Ang Li76216d12016-09-20 14:51:57 -07001019 ad.log.debug("Tethering started successfully.")
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001020 except Empty:
1021 msg = "Failed to receive confirmation of wifi tethering starting"
1022 asserts.fail(msg)
1023 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001024 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001025
Bindu Mahadevff295782019-02-08 16:17:48 -08001026
Omar El Ayach8c017902020-10-18 10:26:57 -07001027def save_wifi_soft_ap_config(ad,
1028 wifi_config,
1029 band=None,
1030 hidden=None,
1031 security=None,
1032 password=None,
1033 channel=None,
1034 max_clients=None,
lesl6d30a172020-03-05 15:05:22 +08001035 shutdown_timeout_enable=None,
1036 shutdown_timeout_millis=None,
1037 client_control_enable=None,
Omar El Ayach8c017902020-10-18 10:26:57 -07001038 allowedList=None,
lesl67124362021-05-04 19:33:14 +08001039 blockedList=None,
1040 bands=None,
1041 channel_frequencys=None,
1042 mac_randomization_setting=None,
1043 bridged_opportunistic_shutdown_enabled=None,
1044 ieee80211ax_enabled=None):
lesl6d30a172020-03-05 15:05:22 +08001045 """ Save a soft ap configuration and verified
1046 Args:
1047 ad: android_device to set soft ap configuration.
1048 wifi_config: a soft ap configuration object, at least include SSID.
1049 band: specifies the band for the soft ap.
1050 hidden: specifies the soft ap need to broadcast its SSID or not.
1051 security: specifies the security type for the soft ap.
1052 password: specifies the password for the soft ap.
1053 channel: specifies the channel for the soft ap.
1054 max_clients: specifies the maximum connected client number.
1055 shutdown_timeout_enable: specifies the auto shut down enable or not.
1056 shutdown_timeout_millis: specifies the shut down timeout value.
1057 client_control_enable: specifies the client control enable or not.
1058 allowedList: specifies allowed clients list.
1059 blockedList: specifies blocked clients list.
lesl67124362021-05-04 19:33:14 +08001060 bands: specifies the band list for the soft ap.
1061 channel_frequencys: specifies the channel frequency list for soft ap.
1062 mac_randomization_setting: specifies the mac randomization setting.
1063 bridged_opportunistic_shutdown_enabled: specifies the opportunistic
1064 shutdown enable or not.
1065 ieee80211ax_enabled: specifies the ieee80211ax enable or not.
lesl6d30a172020-03-05 15:05:22 +08001066 """
1067 if security and password:
Omar El Ayach8c017902020-10-18 10:26:57 -07001068 wifi_config[WifiEnums.SECURITY] = security
1069 wifi_config[WifiEnums.PWD_KEY] = password
lesl67124362021-05-04 19:33:14 +08001070 if hidden is not None:
Girish Moturu528b5442018-06-07 10:48:14 -07001071 wifi_config[WifiEnums.HIDDEN_KEY] = hidden
lesl67124362021-05-04 19:33:14 +08001072 if max_clients is not None:
lesl6d30a172020-03-05 15:05:22 +08001073 wifi_config[WifiEnums.AP_MAXCLIENTS_KEY] = max_clients
lesl67124362021-05-04 19:33:14 +08001074 if shutdown_timeout_enable is not None:
lesl6d30a172020-03-05 15:05:22 +08001075 wifi_config[
1076 WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] = shutdown_timeout_enable
lesl67124362021-05-04 19:33:14 +08001077 if shutdown_timeout_millis is not None:
Omar El Ayach8c017902020-10-18 10:26:57 -07001078 wifi_config[WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] = shutdown_timeout_millis
lesl67124362021-05-04 19:33:14 +08001079 if client_control_enable is not None:
lesl6d30a172020-03-05 15:05:22 +08001080 wifi_config[WifiEnums.AP_CLIENTCONTROL_KEY] = client_control_enable
lesl67124362021-05-04 19:33:14 +08001081 if allowedList is not None:
lesl6d30a172020-03-05 15:05:22 +08001082 wifi_config[WifiEnums.AP_ALLOWEDLIST_KEY] = allowedList
lesl67124362021-05-04 19:33:14 +08001083 if blockedList is not None:
lesl6d30a172020-03-05 15:05:22 +08001084 wifi_config[WifiEnums.AP_BLOCKEDLIST_KEY] = blockedList
lesl67124362021-05-04 19:33:14 +08001085 if mac_randomization_setting is not None:
1086 wifi_config[WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY
1087 ] = mac_randomization_setting
1088 if bridged_opportunistic_shutdown_enabled is not None:
1089 wifi_config[WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY
1090 ] = bridged_opportunistic_shutdown_enabled
1091 if ieee80211ax_enabled is not None:
1092 wifi_config[WifiEnums.AP_IEEE80211AX_ENABLED_KEY]= ieee80211ax_enabled
1093 if channel_frequencys is not None:
1094 wifi_config[WifiEnums.AP_CHANNEL_FREQUENCYS_KEY] = channel_frequencys
1095 elif bands is not None:
1096 wifi_config[WifiEnums.AP_BANDS_KEY] = bands
1097 elif band is not None:
1098 if channel is not None:
1099 wifi_config[WifiEnums.AP_BAND_KEY] = band
1100 wifi_config[WifiEnums.AP_CHANNEL_KEY] = channel
1101 else:
1102 wifi_config[WifiEnums.AP_BAND_KEY] = band
lesl6d30a172020-03-05 15:05:22 +08001103
1104 if WifiEnums.AP_CHANNEL_KEY in wifi_config and wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001105 WifiEnums.AP_CHANNEL_KEY] == 0:
lesl6d30a172020-03-05 15:05:22 +08001106 del wifi_config[WifiEnums.AP_CHANNEL_KEY]
1107
1108 if WifiEnums.SECURITY in wifi_config and wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001109 WifiEnums.SECURITY] == WifiEnums.SoftApSecurityType.OPEN:
lesl6d30a172020-03-05 15:05:22 +08001110 del wifi_config[WifiEnums.SECURITY]
1111 del wifi_config[WifiEnums.PWD_KEY]
1112
Girish Moturu528b5442018-06-07 10:48:14 -07001113 asserts.assert_true(ad.droid.wifiSetWifiApConfiguration(wifi_config),
1114 "Failed to set WifiAp Configuration")
1115
1116 wifi_ap = ad.droid.wifiGetApConfiguration()
1117 asserts.assert_true(
1118 wifi_ap[WifiEnums.SSID_KEY] == wifi_config[WifiEnums.SSID_KEY],
lesl6d30a172020-03-05 15:05:22 +08001119 "Hotspot SSID doesn't match")
1120 if WifiEnums.SECURITY in wifi_config:
1121 asserts.assert_true(
1122 wifi_ap[WifiEnums.SECURITY] == wifi_config[WifiEnums.SECURITY],
1123 "Hotspot Security doesn't match")
1124 if WifiEnums.PWD_KEY in wifi_config:
1125 asserts.assert_true(
1126 wifi_ap[WifiEnums.PWD_KEY] == wifi_config[WifiEnums.PWD_KEY],
1127 "Hotspot Password doesn't match")
Girish Moturu528b5442018-06-07 10:48:14 -07001128
lesl6d30a172020-03-05 15:05:22 +08001129 if WifiEnums.HIDDEN_KEY in wifi_config:
1130 asserts.assert_true(
1131 wifi_ap[WifiEnums.HIDDEN_KEY] == wifi_config[WifiEnums.HIDDEN_KEY],
1132 "Hotspot hidden setting doesn't match")
1133
lesl6d30a172020-03-05 15:05:22 +08001134 if WifiEnums.AP_CHANNEL_KEY in wifi_config:
1135 asserts.assert_true(
1136 wifi_ap[WifiEnums.AP_CHANNEL_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001137 WifiEnums.AP_CHANNEL_KEY], "Hotspot Channel doesn't match")
lesl6d30a172020-03-05 15:05:22 +08001138 if WifiEnums.AP_MAXCLIENTS_KEY in wifi_config:
1139 asserts.assert_true(
1140 wifi_ap[WifiEnums.AP_MAXCLIENTS_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001141 WifiEnums.AP_MAXCLIENTS_KEY],
1142 "Hotspot Max Clients doesn't match")
lesl6d30a172020-03-05 15:05:22 +08001143 if WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY in wifi_config:
1144 asserts.assert_true(
1145 wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001146 WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY],
lesl6d30a172020-03-05 15:05:22 +08001147 "Hotspot ShutDown feature flag doesn't match")
1148 if WifiEnums.AP_SHUTDOWNTIMEOUT_KEY in wifi_config:
1149 asserts.assert_true(
1150 wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001151 WifiEnums.AP_SHUTDOWNTIMEOUT_KEY],
lesl6d30a172020-03-05 15:05:22 +08001152 "Hotspot ShutDown timeout setting doesn't match")
1153 if WifiEnums.AP_CLIENTCONTROL_KEY in wifi_config:
1154 asserts.assert_true(
1155 wifi_ap[WifiEnums.AP_CLIENTCONTROL_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001156 WifiEnums.AP_CLIENTCONTROL_KEY],
lesl6d30a172020-03-05 15:05:22 +08001157 "Hotspot Client control flag doesn't match")
1158 if WifiEnums.AP_ALLOWEDLIST_KEY in wifi_config:
1159 asserts.assert_true(
1160 wifi_ap[WifiEnums.AP_ALLOWEDLIST_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001161 WifiEnums.AP_ALLOWEDLIST_KEY],
lesl6d30a172020-03-05 15:05:22 +08001162 "Hotspot Allowed List doesn't match")
1163 if WifiEnums.AP_BLOCKEDLIST_KEY in wifi_config:
1164 asserts.assert_true(
1165 wifi_ap[WifiEnums.AP_BLOCKEDLIST_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001166 WifiEnums.AP_BLOCKEDLIST_KEY],
lesl6d30a172020-03-05 15:05:22 +08001167 "Hotspot Blocked List doesn't match")
Bindu Mahadevff295782019-02-08 16:17:48 -08001168
lesl67124362021-05-04 19:33:14 +08001169 if WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY in wifi_config:
1170 asserts.assert_true(
1171 wifi_ap[WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY] == wifi_config[
1172 WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY],
1173 "Hotspot Mac randomization setting doesn't match")
1174
1175 if WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY in wifi_config:
1176 asserts.assert_true(
1177 wifi_ap[WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY] == wifi_config[
1178 WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY],
1179 "Hotspot bridged shutdown enable setting doesn't match")
1180
1181 if WifiEnums.AP_IEEE80211AX_ENABLED_KEY in wifi_config:
1182 asserts.assert_true(
1183 wifi_ap[WifiEnums.AP_IEEE80211AX_ENABLED_KEY] == wifi_config[
1184 WifiEnums.AP_IEEE80211AX_ENABLED_KEY],
1185 "Hotspot 80211 AX enable setting doesn't match")
1186
1187 if WifiEnums.AP_CHANNEL_FREQUENCYS_KEY in wifi_config:
1188 asserts.assert_true(
1189 wifi_ap[WifiEnums.AP_CHANNEL_FREQUENCYS_KEY] == wifi_config[
1190 WifiEnums.AP_CHANNEL_FREQUENCYS_KEY],
1191 "Hotspot channels setting doesn't match")
Omar El Ayach8c017902020-10-18 10:26:57 -07001192
Girish Moturu528b5442018-06-07 10:48:14 -07001193def start_wifi_tethering_saved_config(ad):
1194 """ Turn on wifi hotspot with a config that is already saved """
1195 ad.droid.wifiStartTrackingTetherStateChange()
1196 ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
1197 try:
1198 ad.ed.pop_event("ConnectivityManagerOnTetheringStarted")
1199 ad.ed.wait_for_event("TetherStateChanged",
1200 lambda x: x["data"]["ACTIVE_TETHER"], 30)
1201 except:
1202 asserts.fail("Didn't receive wifi tethering starting confirmation")
1203 finally:
1204 ad.droid.wifiStopTrackingTetherStateChange()
Betty Zhou3caa0982017-02-22 19:26:20 -08001205
Bindu Mahadevff295782019-02-08 16:17:48 -08001206
Ang Li73697b32015-12-03 00:41:53 +00001207def stop_wifi_tethering(ad):
1208 """Stops wifi tethering on an android_device.
Ang Li73697b32015-12-03 00:41:53 +00001209 Args:
1210 ad: android_device to stop wifi tethering on.
1211 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001212 ad.droid.wifiStartTrackingTetherStateChange()
1213 ad.droid.connectivityStopTethering(tel_defines.TETHERING_WIFI)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001214 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001215 ad.ed.pop_event("WifiManagerApDisabled", 30)
1216 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -08001217 lambda x: not x["data"]["ACTIVE_TETHER"], 30)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001218 except Empty:
1219 msg = "Failed to receive confirmation of wifi tethering stopping"
1220 asserts.fail(msg)
1221 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001222 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li82522812016-06-02 13:57:21 -07001223
Ang Li76216d12016-09-20 14:51:57 -07001224
Roshan Pius58916a32016-06-16 16:26:44 -07001225def toggle_wifi_and_wait_for_reconnection(ad,
1226 network,
1227 num_of_tries=1,
1228 assert_on_fail=True):
1229 """Toggle wifi state and then wait for Android device to reconnect to
1230 the provided wifi network.
1231
1232 This expects the device to be already connected to the provided network.
1233
1234 Logic steps are
1235 1. Ensure that we're connected to the network.
1236 2. Turn wifi off.
1237 3. Wait for 10 seconds.
1238 4. Turn wifi on.
1239 5. Wait for the "connected" event, then confirm the connected ssid is the
1240 one requested.
1241
1242 Args:
1243 ad: android_device object to initiate connection on.
1244 network: A dictionary representing the network to await connection. The
1245 dictionary must have the key "SSID".
1246 num_of_tries: An integer that is the number of times to try before
1247 delaring failure. Default is 1.
1248 assert_on_fail: If True, error checks in this function will raise test
1249 failure signals.
1250
1251 Returns:
1252 If assert_on_fail is False, function returns True if the toggle was
1253 successful, False otherwise. If assert_on_fail is True, no return value.
1254 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001255 return _assert_on_fail_handler(_toggle_wifi_and_wait_for_reconnection,
1256 assert_on_fail,
1257 ad,
1258 network,
1259 num_of_tries=num_of_tries)
Roshan Pius58916a32016-06-16 16:26:44 -07001260
1261
Girish Moturu5d9f4202019-12-03 15:29:21 -08001262def _toggle_wifi_and_wait_for_reconnection(ad, network, num_of_tries=3):
Roshan Pius58916a32016-06-16 16:26:44 -07001263 """Toggle wifi state and then wait for Android device to reconnect to
1264 the provided wifi network.
1265
1266 This expects the device to be already connected to the provided network.
1267
1268 Logic steps are
1269 1. Ensure that we're connected to the network.
1270 2. Turn wifi off.
1271 3. Wait for 10 seconds.
1272 4. Turn wifi on.
1273 5. Wait for the "connected" event, then confirm the connected ssid is the
1274 one requested.
1275
1276 This will directly fail a test if anything goes wrong.
1277
1278 Args:
1279 ad: android_device object to initiate connection on.
1280 network: A dictionary representing the network to await connection. The
1281 dictionary must have the key "SSID".
1282 num_of_tries: An integer that is the number of times to try before
1283 delaring failure. Default is 1.
1284 """
Roshan Pius58916a32016-06-16 16:26:44 -07001285 expected_ssid = network[WifiEnums.SSID_KEY]
1286 # First ensure that we're already connected to the provided network.
1287 verify_con = {WifiEnums.SSID_KEY: expected_ssid}
1288 verify_wifi_connection_info(ad, verify_con)
1289 # Now toggle wifi state and wait for the connection event.
1290 wifi_toggle_state(ad, False)
1291 time.sleep(10)
1292 wifi_toggle_state(ad, True)
1293 ad.droid.wifiStartTrackingStateChange()
1294 try:
1295 connect_result = None
1296 for i in range(num_of_tries):
1297 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -08001298 connect_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
Roshan Pius58916a32016-06-16 16:26:44 -07001299 30)
1300 break
1301 except Empty:
1302 pass
Omar El Ayach8c017902020-10-18 10:26:57 -07001303 asserts.assert_true(
1304 connect_result, "Failed to connect to Wi-Fi network %s on %s" %
1305 (network, ad.serial))
Betty Zhou3caa0982017-02-22 19:26:20 -08001306 logging.debug("Connection result on %s: %s.", ad.serial,
1307 connect_result)
Roshan Pius58916a32016-06-16 16:26:44 -07001308 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001309 asserts.assert_equal(
1310 actual_ssid, expected_ssid, "Connected to the wrong network on %s."
1311 "Expected %s, but got %s." %
1312 (ad.serial, expected_ssid, actual_ssid))
Betty Zhou3caa0982017-02-22 19:26:20 -08001313 logging.info("Connected to Wi-Fi network %s on %s", actual_ssid,
1314 ad.serial)
Roshan Pius58916a32016-06-16 16:26:44 -07001315 finally:
1316 ad.droid.wifiStopTrackingStateChange()
1317
1318
Omar El Ayach8c017902020-10-18 10:26:57 -07001319def wait_for_connect(ad,
1320 expected_ssid=None,
1321 expected_id=None,
1322 tries=2,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001323 assert_on_fail=True):
Roshan Piusd1204442018-11-12 12:20:39 -08001324 """Wait for a connect event.
1325
1326 This will directly fail a test if anything goes wrong.
1327
1328 Args:
1329 ad: An Android device object.
1330 expected_ssid: SSID of the network to connect to.
1331 expected_id: Network Id of the network to connect to.
1332 tries: An integer that is the number of times to try before failing.
1333 assert_on_fail: If True, error checks in this function will raise test
1334 failure signals.
1335
1336 Returns:
1337 Returns a value only if assert_on_fail is false.
1338 Returns True if the connection was successful, False otherwise.
1339 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001340 return _assert_on_fail_handler(_wait_for_connect, assert_on_fail, ad,
1341 expected_ssid, expected_id, tries)
Roshan Piusd1204442018-11-12 12:20:39 -08001342
1343
Oscar Shucb9af9b2019-05-02 20:01:49 +00001344def _wait_for_connect(ad, expected_ssid=None, expected_id=None, tries=2):
Roshan Piusd1204442018-11-12 12:20:39 -08001345 """Wait for a connect event.
1346
1347 Args:
1348 ad: An Android device object.
1349 expected_ssid: SSID of the network to connect to.
1350 expected_id: Network Id of the network to connect to.
1351 tries: An integer that is the number of times to try before failing.
1352 """
1353 ad.droid.wifiStartTrackingStateChange()
1354 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001355 connect_result = _wait_for_connect_event(ad,
1356 ssid=expected_ssid,
1357 id=expected_id,
1358 tries=tries)
1359 asserts.assert_true(
1360 connect_result,
1361 "Failed to connect to Wi-Fi network %s" % expected_ssid)
Roshan Piusd1204442018-11-12 12:20:39 -08001362 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
1363 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1364 if expected_ssid:
1365 asserts.assert_equal(actual_ssid, expected_ssid,
1366 "Connected to the wrong network")
1367 actual_id = connect_result['data'][WifiEnums.NETID_KEY]
1368 if expected_id:
1369 asserts.assert_equal(actual_id, expected_id,
1370 "Connected to the wrong network")
1371 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
1372 except Empty:
1373 asserts.fail("Failed to start connection process to %s" %
1374 expected_ssid)
1375 except Exception as error:
1376 ad.log.error("Failed to connect to %s with error %s", expected_ssid,
1377 error)
1378 raise signals.TestFailure("Failed to connect to %s network" %
1379 expected_ssid)
1380 finally:
1381 ad.droid.wifiStopTrackingStateChange()
1382
1383
Oscar Shucb9af9b2019-05-02 20:01:49 +00001384def _wait_for_connect_event(ad, ssid=None, id=None, tries=1):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001385 """Wait for a connect event on queue and pop when available.
1386
1387 Args:
1388 ad: An Android device object.
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001389 ssid: SSID of the network to connect to.
1390 id: Network Id of the network to connect to.
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001391 tries: An integer that is the number of times to try before failing.
1392
1393 Returns:
1394 A dict with details of the connection data, which looks like this:
1395 {
1396 'time': 1485460337798,
1397 'name': 'WifiNetworkConnected',
1398 'data': {
1399 'rssi': -27,
1400 'is_24ghz': True,
1401 'mac_address': '02:00:00:00:00:00',
1402 'network_id': 1,
1403 'BSSID': '30:b5:c2:33:d3:fc',
1404 'ip_address': 117483712,
1405 'link_speed': 54,
1406 'supplicant_state': 'completed',
1407 'hidden_ssid': False,
1408 'SSID': 'wh_ap1_2g',
1409 'is_5ghz': False}
1410 }
1411
1412 """
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001413 conn_result = None
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001414
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001415 # If ssid and network id is None, just wait for any connect event.
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001416 if id is None and ssid is None:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001417 for i in range(tries):
1418 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001419 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
1420 30)
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001421 break
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001422 except Empty:
1423 pass
1424 else:
Omar El Ayach8c017902020-10-18 10:26:57 -07001425 # If ssid or network id is specified, wait for specific connect event.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001426 for i in range(tries):
1427 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001428 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
1429 30)
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001430 if id and conn_result['data'][WifiEnums.NETID_KEY] == id:
1431 break
1432 elif ssid and conn_result['data'][WifiEnums.SSID_KEY] == ssid:
1433 break
1434 except Empty:
1435 pass
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001436
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001437 return conn_result
1438
Bindu Mahadevff295782019-02-08 16:17:48 -08001439
Roshan Piusffc29912019-01-18 13:39:49 -08001440def wait_for_disconnect(ad, timeout=10):
1441 """Wait for a disconnect event within the specified timeout.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001442
1443 Args:
1444 ad: Android device object.
Roshan Piusffc29912019-01-18 13:39:49 -08001445 timeout: Timeout in seconds.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001446
1447 """
1448 try:
1449 ad.droid.wifiStartTrackingStateChange()
Roshan Piusffc29912019-01-18 13:39:49 -08001450 event = ad.ed.pop_event("WifiNetworkDisconnected", timeout)
Roshan Piusbf7e3982018-02-15 12:37:41 -08001451 except Empty:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001452 raise signals.TestFailure("Device did not disconnect from the network")
Roshan Piusffc29912019-01-18 13:39:49 -08001453 finally:
1454 ad.droid.wifiStopTrackingStateChange()
1455
1456
1457def ensure_no_disconnect(ad, duration=10):
1458 """Ensure that there is no disconnect for the specified duration.
1459
1460 Args:
1461 ad: Android device object.
1462 duration: Duration in seconds.
1463
1464 """
1465 try:
1466 ad.droid.wifiStartTrackingStateChange()
1467 event = ad.ed.pop_event("WifiNetworkDisconnected", duration)
1468 raise signals.TestFailure("Device disconnected from the network")
1469 except Empty:
1470 pass
1471 finally:
1472 ad.droid.wifiStopTrackingStateChange()
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001473
1474
jerrypcchen5cc385d2021-03-11 11:57:21 +00001475def connect_to_wifi_network(ad, network, assert_on_fail=True,
1476 check_connectivity=True, hidden=False,
1477 num_of_scan_tries=3, num_of_connect_tries=3):
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001478 """Connection logic for open and psk wifi networks.
1479
1480 Args:
Jong Wook Kim92356922018-02-06 18:32:49 -08001481 ad: AndroidDevice to use for connection
1482 network: network info of the network to connect to
1483 assert_on_fail: If true, errors from wifi_connect will raise
1484 test failure signals.
Joe Brennan48c3f692019-04-11 08:30:16 -07001485 hidden: Is the Wifi network hidden.
jerrypcchen5cc385d2021-03-11 11:57:21 +00001486 num_of_scan_tries: The number of times to try scan
1487 interface before declaring failure.
1488 num_of_connect_tries: The number of times to try
1489 connect wifi before declaring failure.
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001490 """
Joe Brennan48c3f692019-04-11 08:30:16 -07001491 if hidden:
1492 start_wifi_connection_scan_and_ensure_network_not_found(
jerrypcchen5cc385d2021-03-11 11:57:21 +00001493 ad, network[WifiEnums.SSID_KEY], max_tries=num_of_scan_tries)
Joe Brennan48c3f692019-04-11 08:30:16 -07001494 else:
1495 start_wifi_connection_scan_and_ensure_network_found(
jerrypcchen5cc385d2021-03-11 11:57:21 +00001496 ad, network[WifiEnums.SSID_KEY], max_tries=num_of_scan_tries)
Jong Wook Kim92356922018-02-06 18:32:49 -08001497 wifi_connect(ad,
1498 network,
jerrypcchen5cc385d2021-03-11 11:57:21 +00001499 num_of_tries=num_of_connect_tries,
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001500 assert_on_fail=assert_on_fail,
1501 check_connectivity=check_connectivity)
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001502
1503
1504def connect_to_wifi_network_with_id(ad, network_id, network_ssid):
1505 """Connect to the given network using network id and verify SSID.
1506
1507 Args:
1508 network_id: int Network Id of the network.
1509 network_ssid: string SSID of the network.
1510
1511 Returns: True if connect using network id was successful;
1512 False otherwise.
1513
1514 """
Jong Wook Kim92356922018-02-06 18:32:49 -08001515 start_wifi_connection_scan_and_ensure_network_found(ad, network_ssid)
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001516 wifi_connect_by_id(ad, network_id)
1517 connect_data = ad.droid.wifiGetConnectionInfo()
1518 connect_ssid = connect_data[WifiEnums.SSID_KEY]
1519 ad.log.debug("Expected SSID = %s Connected SSID = %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001520 (network_ssid, connect_ssid))
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001521 if connect_ssid != network_ssid:
1522 return False
1523 return True
1524
1525
Omar El Ayach8c017902020-10-18 10:26:57 -07001526def wifi_connect(ad,
1527 network,
1528 num_of_tries=1,
1529 assert_on_fail=True,
1530 check_connectivity=True):
Ang Li99d8c6d2015-12-09 15:56:13 -08001531 """Connect an Android device to a wifi network.
Ang Li73697b32015-12-03 00:41:53 +00001532
1533 Initiate connection to a wifi network, wait for the "connected" event, then
Ang Li99d8c6d2015-12-09 15:56:13 -08001534 confirm the connected ssid is the one requested.
Ang Li73697b32015-12-03 00:41:53 +00001535
Ang Li82522812016-06-02 13:57:21 -07001536 This will directly fail a test if anything goes wrong.
1537
Ang Li73697b32015-12-03 00:41:53 +00001538 Args:
1539 ad: android_device object to initiate connection on.
Ang Li99d8c6d2015-12-09 15:56:13 -08001540 network: A dictionary representing the network to connect to. The
Ang Li82522812016-06-02 13:57:21 -07001541 dictionary must have the key "SSID".
1542 num_of_tries: An integer that is the number of times to try before
1543 delaring failure. Default is 1.
1544 assert_on_fail: If True, error checks in this function will raise test
1545 failure signals.
1546
1547 Returns:
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001548 Returns a value only if assert_on_fail is false.
1549 Returns True if the connection was successful, False otherwise.
Ang Li73697b32015-12-03 00:41:53 +00001550 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001551 return _assert_on_fail_handler(_wifi_connect,
1552 assert_on_fail,
1553 ad,
1554 network,
1555 num_of_tries=num_of_tries,
1556 check_connectivity=check_connectivity)
Ang Li82522812016-06-02 13:57:21 -07001557
1558
Oscar Shucb9af9b2019-05-02 20:01:49 +00001559def _wifi_connect(ad, network, num_of_tries=1, check_connectivity=True):
Ang Li82522812016-06-02 13:57:21 -07001560 """Connect an Android device to a wifi network.
1561
1562 Initiate connection to a wifi network, wait for the "connected" event, then
1563 confirm the connected ssid is the one requested.
1564
1565 This will directly fail a test if anything goes wrong.
1566
1567 Args:
1568 ad: android_device object to initiate connection on.
1569 network: A dictionary representing the network to connect to. The
1570 dictionary must have the key "SSID".
1571 num_of_tries: An integer that is the number of times to try before
1572 delaring failure. Default is 1.
1573 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001574 asserts.assert_true(
1575 WifiEnums.SSID_KEY in network,
1576 "Key '%s' must be present in network definition." % WifiEnums.SSID_KEY)
Ang Li99d8c6d2015-12-09 15:56:13 -08001577 ad.droid.wifiStartTrackingStateChange()
Betty Zhoud35dab82016-12-06 15:24:23 -08001578 expected_ssid = network[WifiEnums.SSID_KEY]
Bindu Mahadev50374df2017-01-04 11:03:32 -08001579 ad.droid.wifiConnectByConfig(network)
1580 ad.log.info("Starting connection process to %s", expected_ssid)
Ang Li73697b32015-12-03 00:41:53 +00001581 try:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001582 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_CONFIG_SUCCESS, 30)
Omar El Ayach8c017902020-10-18 10:26:57 -07001583 connect_result = _wait_for_connect_event(ad,
1584 ssid=expected_ssid,
1585 tries=num_of_tries)
1586 asserts.assert_true(
1587 connect_result, "Failed to connect to Wi-Fi network %s on %s" %
1588 (network, ad.serial))
Ang Li31b00782016-06-21 13:04:23 -07001589 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
Ang Li99d8c6d2015-12-09 15:56:13 -08001590 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001591 asserts.assert_equal(
1592 actual_ssid, expected_ssid,
1593 "Connected to the wrong network on %s." % ad.serial)
Ang Li31b00782016-06-21 13:04:23 -07001594 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
Bindu Mahadev50374df2017-01-04 11:03:32 -08001595
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001596 if check_connectivity:
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08001597 internet = validate_connection(ad, DEFAULT_PING_ADDR)
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001598 if not internet:
Omar El Ayach8c017902020-10-18 10:26:57 -07001599 raise signals.TestFailure(
1600 "Failed to connect to internet on %s" % expected_ssid)
Bindu Mahadev50374df2017-01-04 11:03:32 -08001601 except Empty:
1602 asserts.fail("Failed to start connection process to %s on %s" %
1603 (network, ad.serial))
Bindu Mahadev4e710362016-11-17 16:17:11 -08001604 except Exception as error:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001605 ad.log.error("Failed to connect to %s with error %s", expected_ssid,
1606 error)
1607 raise signals.TestFailure("Failed to connect to %s network" % network)
1608
Ang Li73697b32015-12-03 00:41:53 +00001609 finally:
Ang Li99d8c6d2015-12-09 15:56:13 -08001610 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001611
Bindu Mahadev50374df2017-01-04 11:03:32 -08001612
Oscar Shucb9af9b2019-05-02 20:01:49 +00001613def wifi_connect_by_id(ad, network_id, num_of_tries=3, assert_on_fail=True):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001614 """Connect an Android device to a wifi network using network Id.
1615
1616 Start connection to the wifi network, with the given network Id, wait for
1617 the "connected" event, then verify the connected network is the one requested.
1618
1619 This will directly fail a test if anything goes wrong.
1620
1621 Args:
1622 ad: android_device object to initiate connection on.
1623 network_id: Integer specifying the network id of the network.
1624 num_of_tries: An integer that is the number of times to try before
1625 delaring failure. Default is 1.
1626 assert_on_fail: If True, error checks in this function will raise test
1627 failure signals.
1628
1629 Returns:
1630 Returns a value only if assert_on_fail is false.
1631 Returns True if the connection was successful, False otherwise.
1632 """
1633 _assert_on_fail_handler(_wifi_connect_by_id, assert_on_fail, ad,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001634 network_id, num_of_tries)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001635
1636
Oscar Shucb9af9b2019-05-02 20:01:49 +00001637def _wifi_connect_by_id(ad, network_id, num_of_tries=1):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001638 """Connect an Android device to a wifi network using it's network id.
1639
1640 Start connection to the wifi network, with the given network id, wait for
1641 the "connected" event, then verify the connected network is the one requested.
1642
1643 Args:
1644 ad: android_device object to initiate connection on.
1645 network_id: Integer specifying the network id of the network.
1646 num_of_tries: An integer that is the number of times to try before
1647 delaring failure. Default is 1.
1648 """
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001649 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001650 # Clear all previous events.
1651 ad.ed.clear_all_events()
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001652 ad.droid.wifiConnectByNetworkId(network_id)
1653 ad.log.info("Starting connection to network with id %d", network_id)
1654 try:
1655 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_NETID_SUCCESS, 60)
Omar El Ayach8c017902020-10-18 10:26:57 -07001656 connect_result = _wait_for_connect_event(ad,
1657 id=network_id,
1658 tries=num_of_tries)
1659 asserts.assert_true(
1660 connect_result,
1661 "Failed to connect to Wi-Fi network using network id")
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001662 ad.log.debug("Wi-Fi connection result: %s", connect_result)
1663 actual_id = connect_result['data'][WifiEnums.NETID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001664 asserts.assert_equal(
1665 actual_id, network_id, "Connected to the wrong network on %s."
1666 "Expected network id = %d, but got %d." %
1667 (ad.serial, network_id, actual_id))
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001668 expected_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1669 ad.log.info("Connected to Wi-Fi network %s with %d network id.",
Omar El Ayach8c017902020-10-18 10:26:57 -07001670 expected_ssid, network_id)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001671
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001672 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1673 if not internet:
1674 raise signals.TestFailure("Failed to connect to internet on %s" %
1675 expected_ssid)
1676 except Empty:
1677 asserts.fail("Failed to connect to network with id %d on %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001678 (network_id, ad.serial))
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001679 except Exception as error:
1680 ad.log.error("Failed to connect to network with id %d with error %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07001681 network_id, error)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001682 raise signals.TestFailure("Failed to connect to network with network"
1683 " id %d" % network_id)
1684 finally:
1685 ad.droid.wifiStopTrackingStateChange()
1686
Oscar Shu0b5ff4d2019-08-07 18:11:56 +00001687
Omar El Ayach8c017902020-10-18 10:26:57 -07001688def wifi_connect_using_network_request(ad,
1689 network,
1690 network_specifier,
Roshan Pius5561d232021-01-22 16:34:39 -08001691 num_of_tries=3):
Roshan Piusc999e5e2018-11-09 10:59:52 -08001692 """Connect an Android device to a wifi network using network request.
1693
1694 Trigger a network request with the provided network specifier,
1695 wait for the "onMatch" event, ensure that the scan results in "onMatch"
1696 event contain the specified network, then simulate the user granting the
1697 request with the specified network selected. Then wait for the "onAvailable"
1698 network callback indicating successful connection to network.
1699
1700 Args:
1701 ad: android_device object to initiate connection on.
1702 network_specifier: A dictionary representing the network specifier to
1703 use.
1704 network: A dictionary representing the network to connect to. The
1705 dictionary must have the key "SSID".
1706 num_of_tries: An integer that is the number of times to try before
1707 delaring failure.
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001708 Returns:
1709 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001710 """
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001711 key = ad.droid.connectivityRequestWifiNetwork(network_specifier, 0)
1712 ad.log.info("Sent network request %s with %s " % (key, network_specifier))
Roshan Piusc999e5e2018-11-09 10:59:52 -08001713 # Need a delay here because UI interaction should only start once wifi
1714 # starts processing the request.
1715 time.sleep(wifi_constants.NETWORK_REQUEST_CB_REGISTER_DELAY_SEC)
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001716 _wait_for_wifi_connect_after_network_request(ad, network, key, num_of_tries)
1717 return key
Roshan Piusc999e5e2018-11-09 10:59:52 -08001718
1719
Omar El Ayach8c017902020-10-18 10:26:57 -07001720def wait_for_wifi_connect_after_network_request(ad,
1721 network,
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001722 key,
Omar El Ayach8c017902020-10-18 10:26:57 -07001723 num_of_tries=3,
Roshan Piusc999e5e2018-11-09 10:59:52 -08001724 assert_on_fail=True):
1725 """
1726 Simulate and verify the connection flow after initiating the network
1727 request.
1728
1729 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1730 event contain the specified network, then simulate the user granting the
1731 request with the specified network selected. Then wait for the "onAvailable"
1732 network callback indicating successful connection to network.
1733
1734 Args:
1735 ad: android_device object to initiate connection on.
1736 network: A dictionary representing the network to connect to. The
1737 dictionary must have the key "SSID".
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001738 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001739 num_of_tries: An integer that is the number of times to try before
1740 delaring failure.
1741 assert_on_fail: If True, error checks in this function will raise test
1742 failure signals.
1743
1744 Returns:
1745 Returns a value only if assert_on_fail is false.
1746 Returns True if the connection was successful, False otherwise.
1747 """
1748 _assert_on_fail_handler(_wait_for_wifi_connect_after_network_request,
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001749 assert_on_fail, ad, network, key, num_of_tries)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001750
1751
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001752def _wait_for_wifi_connect_after_network_request(ad, network, key, num_of_tries=3):
Roshan Piusc999e5e2018-11-09 10:59:52 -08001753 """
1754 Simulate and verify the connection flow after initiating the network
1755 request.
1756
1757 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1758 event contain the specified network, then simulate the user granting the
1759 request with the specified network selected. Then wait for the "onAvailable"
1760 network callback indicating successful connection to network.
1761
1762 Args:
1763 ad: android_device object to initiate connection on.
1764 network: A dictionary representing the network to connect to. The
1765 dictionary must have the key "SSID".
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001766 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001767 num_of_tries: An integer that is the number of times to try before
1768 delaring failure.
1769 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001770 asserts.assert_true(
1771 WifiEnums.SSID_KEY in network,
1772 "Key '%s' must be present in network definition." % WifiEnums.SSID_KEY)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001773 ad.droid.wifiStartTrackingStateChange()
1774 expected_ssid = network[WifiEnums.SSID_KEY]
1775 ad.droid.wifiRegisterNetworkRequestMatchCallback()
1776 # Wait for the platform to scan and return a list of networks
1777 # matching the request
1778 try:
1779 matched_network = None
Omar El Ayach8c017902020-10-18 10:26:57 -07001780 for _ in [0, num_of_tries]:
Roshan Piusc999e5e2018-11-09 10:59:52 -08001781 on_match_event = ad.ed.pop_event(
1782 wifi_constants.WIFI_NETWORK_REQUEST_MATCH_CB_ON_MATCH, 60)
1783 asserts.assert_true(on_match_event,
1784 "Network request on match not received.")
1785 matched_scan_results = on_match_event["data"]
1786 ad.log.debug("Network request on match results %s",
1787 matched_scan_results)
1788 matched_network = match_networks(
1789 {WifiEnums.SSID_KEY: network[WifiEnums.SSID_KEY]},
1790 matched_scan_results)
Roshan Pius6cd4aaf2021-02-09 15:54:30 -08001791 ad.log.debug("Network request on match %s", matched_network)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001792 if matched_network:
Omar El Ayach8c017902020-10-18 10:26:57 -07001793 break
Roshan Piusc999e5e2018-11-09 10:59:52 -08001794
Omar El Ayach8c017902020-10-18 10:26:57 -07001795 asserts.assert_true(matched_network,
1796 "Target network %s not found" % network)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001797
1798 ad.droid.wifiSendUserSelectionForNetworkRequestMatch(network)
1799 ad.log.info("Sent user selection for network request %s",
1800 expected_ssid)
1801
1802 # Wait for the platform to connect to the network.
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001803 autils.wait_for_event_with_keys(
1804 ad, cconsts.EVENT_NETWORK_CALLBACK,
1805 60,
1806 (cconsts.NETWORK_CB_KEY_ID, key),
1807 (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_AVAILABLE))
1808 on_capabilities_changed = autils.wait_for_event_with_keys(
1809 ad, cconsts.EVENT_NETWORK_CALLBACK,
1810 10,
1811 (cconsts.NETWORK_CB_KEY_ID, key),
1812 (cconsts.NETWORK_CB_KEY_EVENT,
1813 cconsts.NETWORK_CB_CAPABILITIES_CHANGED))
Roshan Pius008fe7f2021-03-25 14:18:17 -07001814 connected_network = None
1815 # WifiInfo is attached to TransportInfo only in S.
1816 if ad.droid.isSdkAtLeastS():
1817 connected_network = (
1818 on_capabilities_changed["data"][
1819 cconsts.NETWORK_CB_KEY_TRANSPORT_INFO]
1820 )
1821 else:
1822 connected_network = ad.droid.wifiGetConnectionInfo()
Roshan Piusc999e5e2018-11-09 10:59:52 -08001823 ad.log.info("Connected to network %s", connected_network)
Omar El Ayach8c017902020-10-18 10:26:57 -07001824 asserts.assert_equal(
1825 connected_network[WifiEnums.SSID_KEY], expected_ssid,
1826 "Connected to the wrong network."
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001827 "Expected %s, but got %s."
1828 % (network, connected_network))
Roshan Piusc999e5e2018-11-09 10:59:52 -08001829 except Empty:
1830 asserts.fail("Failed to connect to %s" % expected_ssid)
1831 except Exception as error:
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001832 ad.log.error("Failed to connect to %s with error %s" %
Roshan Piusc999e5e2018-11-09 10:59:52 -08001833 (expected_ssid, error))
1834 raise signals.TestFailure("Failed to connect to %s network" % network)
1835 finally:
1836 ad.droid.wifiStopTrackingStateChange()
1837
1838
Omar El Ayach8c017902020-10-18 10:26:57 -07001839def wifi_passpoint_connect(ad,
1840 passpoint_network,
1841 num_of_tries=1,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001842 assert_on_fail=True):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001843 """Connect an Android device to a wifi network.
1844
1845 Initiate connection to a wifi network, wait for the "connected" event, then
1846 confirm the connected ssid is the one requested.
1847
1848 This will directly fail a test if anything goes wrong.
1849
1850 Args:
1851 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001852 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001853 num_of_tries: An integer that is the number of times to try before
1854 delaring failure. Default is 1.
1855 assert_on_fail: If True, error checks in this function will raise test
1856 failure signals.
1857
1858 Returns:
1859 If assert_on_fail is False, function returns network id, if the connect was
1860 successful, False otherwise. If assert_on_fail is True, no return value.
1861 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001862 _assert_on_fail_handler(_wifi_passpoint_connect,
1863 assert_on_fail,
1864 ad,
1865 passpoint_network,
1866 num_of_tries=num_of_tries)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001867
1868
Oscar Shucb9af9b2019-05-02 20:01:49 +00001869def _wifi_passpoint_connect(ad, passpoint_network, num_of_tries=1):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001870 """Connect an Android device to a wifi network.
1871
1872 Initiate connection to a wifi network, wait for the "connected" event, then
1873 confirm the connected ssid is the one requested.
1874
1875 This will directly fail a test if anything goes wrong.
1876
1877 Args:
1878 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001879 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001880 num_of_tries: An integer that is the number of times to try before
1881 delaring failure. Default is 1.
1882 """
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001883 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001884 expected_ssid = passpoint_network
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001885 ad.log.info("Starting connection process to passpoint %s", expected_ssid)
1886
1887 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001888 connect_result = _wait_for_connect_event(ad, expected_ssid,
1889 num_of_tries)
1890 asserts.assert_true(
1891 connect_result, "Failed to connect to WiFi passpoint network %s on"
1892 " %s" % (expected_ssid, ad.serial))
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001893 ad.log.info("Wi-Fi connection result: %s.", connect_result)
1894 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001895 asserts.assert_equal(
1896 actual_ssid, expected_ssid,
1897 "Connected to the wrong network on %s." % ad.serial)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001898 ad.log.info("Connected to Wi-Fi passpoint network %s.", actual_ssid)
1899
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001900 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1901 if not internet:
1902 raise signals.TestFailure("Failed to connect to internet on %s" %
1903 expected_ssid)
1904 except Exception as error:
1905 ad.log.error("Failed to connect to passpoint network %s with error %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07001906 expected_ssid, error)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001907 raise signals.TestFailure("Failed to connect to %s passpoint network" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001908 expected_ssid)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001909
1910 finally:
1911 ad.droid.wifiStopTrackingStateChange()
1912
1913
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001914def delete_passpoint(ad, fqdn):
1915 """Delete a required Passpoint configuration."""
1916 try:
1917 ad.droid.removePasspointConfig(fqdn)
1918 return True
1919 except Exception as error:
Omar El Ayach8c017902020-10-18 10:26:57 -07001920 ad.log.error(
1921 "Failed to remove passpoint configuration with FQDN=%s "
1922 "and error=%s", fqdn, error)
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001923 return False
1924
1925
Ang Li73697b32015-12-03 00:41:53 +00001926def start_wifi_single_scan(ad, scan_setting):
1927 """Starts wifi single shot scan.
1928
1929 Args:
1930 ad: android_device object to initiate connection on.
1931 scan_setting: A dict representing the settings of the scan.
1932
1933 Returns:
1934 If scan was started successfully, event data of success event is returned.
1935 """
Ang Li82522812016-06-02 13:57:21 -07001936 idx = ad.droid.wifiScannerStartScan(scan_setting)
1937 event = ad.ed.pop_event("WifiScannerScan%sonSuccess" % idx, SHORT_TIMEOUT)
Ang Li31b00782016-06-21 13:04:23 -07001938 ad.log.debug("Got event %s", event)
Ang Li73697b32015-12-03 00:41:53 +00001939 return event['data']
1940
Ang Li82522812016-06-02 13:57:21 -07001941
Ang Li73697b32015-12-03 00:41:53 +00001942def track_connection(ad, network_ssid, check_connection_count):
1943 """Track wifi connection to network changes for given number of counts
1944
1945 Args:
1946 ad: android_device object for forget network.
1947 network_ssid: network ssid to which connection would be tracked
1948 check_connection_count: Integer for maximum number network connection
Ang Li82522812016-06-02 13:57:21 -07001949 check.
Ang Li73697b32015-12-03 00:41:53 +00001950 Returns:
Ang Li73697b32015-12-03 00:41:53 +00001951 True if connection to given network happen, else return False.
1952 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001953 ad.droid.wifiStartTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001954 while check_connection_count > 0:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001955 connect_network = ad.ed.pop_event("WifiNetworkConnected", 120)
Ang Li31b00782016-06-21 13:04:23 -07001956 ad.log.info("Connected to network %s", connect_network)
Ang Li82522812016-06-02 13:57:21 -07001957 if (WifiEnums.SSID_KEY in connect_network['data'] and
1958 connect_network['data'][WifiEnums.SSID_KEY] == network_ssid):
1959 return True
Ang Li8e767182015-12-09 17:29:24 -08001960 check_connection_count -= 1
Girish Moturu40d7dc22016-11-02 12:14:56 -07001961 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001962 return False
1963
Ang Li82522812016-06-02 13:57:21 -07001964
Ang Li73697b32015-12-03 00:41:53 +00001965def get_scan_time_and_channels(wifi_chs, scan_setting, stime_channel):
1966 """Calculate the scan time required based on the band or channels in scan
1967 setting
1968
1969 Args:
1970 wifi_chs: Object of channels supported
1971 scan_setting: scan setting used for start scan
1972 stime_channel: scan time per channel
1973
1974 Returns:
1975 scan_time: time required for completing a scan
1976 scan_channels: channel used for scanning
1977 """
1978 scan_time = 0
1979 scan_channels = []
1980 if "band" in scan_setting and "channels" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001981 scan_channels = wifi_chs.band_to_freq(scan_setting["band"])
Ang Li73697b32015-12-03 00:41:53 +00001982 elif "channels" in scan_setting and "band" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001983 scan_channels = scan_setting["channels"]
Ang Li73697b32015-12-03 00:41:53 +00001984 scan_time = len(scan_channels) * stime_channel
1985 for channel in scan_channels:
Ang Li8e767182015-12-09 17:29:24 -08001986 if channel in WifiEnums.DFS_5G_FREQUENCIES:
Ang Li82522812016-06-02 13:57:21 -07001987 scan_time += 132 #passive scan time on DFS
Ang Li73697b32015-12-03 00:41:53 +00001988 return scan_time, scan_channels
1989
Ang Li82522812016-06-02 13:57:21 -07001990
Ang Li73697b32015-12-03 00:41:53 +00001991def start_wifi_track_bssid(ad, track_setting):
1992 """Start tracking Bssid for the given settings.
1993
1994 Args:
1995 ad: android_device object.
1996 track_setting: Setting for which the bssid tracking should be started
1997
1998 Returns:
1999 If tracking started successfully, event data of success event is returned.
2000 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07002001 idx = ad.droid.wifiScannerStartTrackingBssids(
Ang Li82522812016-06-02 13:57:21 -07002002 track_setting["bssidInfos"], track_setting["apLostThreshold"])
Girish Moturu40d7dc22016-11-02 12:14:56 -07002003 event = ad.ed.pop_event("WifiScannerBssid{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -08002004 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +00002005 return event['data']
2006
Ang Li82522812016-06-02 13:57:21 -07002007
Ang Li73697b32015-12-03 00:41:53 +00002008def convert_pem_key_to_pkcs8(in_file, out_file):
2009 """Converts the key file generated by us to the format required by
2010 Android using openssl.
2011
2012 The input file must have the extension "pem". The output file must
2013 have the extension "der".
2014
2015 Args:
2016 in_file: The original key file.
2017 out_file: The full path to the converted key file, including
2018 filename.
2019 """
Ang Li82522812016-06-02 13:57:21 -07002020 asserts.assert_true(in_file.endswith(".pem"), "Input file has to be .pem.")
Omar El Ayach8c017902020-10-18 10:26:57 -07002021 asserts.assert_true(out_file.endswith(".der"),
2022 "Output file has to be .der.")
Ang Li73697b32015-12-03 00:41:53 +00002023 cmd = ("openssl pkcs8 -inform PEM -in {} -outform DER -out {} -nocrypt"
2024 " -topk8").format(in_file, out_file)
Ang Lifee28402016-07-13 13:43:29 -07002025 utils.exe_cmd(cmd)
Ang Li73697b32015-12-03 00:41:53 +00002026
Ang Li82522812016-06-02 13:57:21 -07002027
Omar El Ayach8c017902020-10-18 10:26:57 -07002028def validate_connection(ad,
2029 ping_addr=DEFAULT_PING_ADDR,
2030 wait_time=15,
Girish Moturu804a3492020-02-17 14:32:02 -08002031 ping_gateway=True):
Ang Li73697b32015-12-03 00:41:53 +00002032 """Validate internet connection by pinging the address provided.
2033
2034 Args:
2035 ad: android_device object.
2036 ping_addr: address on internet for pinging.
Girish Moturua2a5bf22019-08-16 09:52:29 -07002037 wait_time: wait for some time before validating connection
Ang Li73697b32015-12-03 00:41:53 +00002038
2039 Returns:
Bindu Mahadev50374df2017-01-04 11:03:32 -08002040 ping output if successful, NULL otherwise.
Ang Li73697b32015-12-03 00:41:53 +00002041 """
Girish Moturua2a5bf22019-08-16 09:52:29 -07002042 # wait_time to allow for DHCP to complete.
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08002043 for i in range(wait_time):
Girish Moturuacf35002020-11-09 23:37:35 -08002044 if ad.droid.connectivityNetworkIsConnected(
Omar El Ayach8c017902020-10-18 10:26:57 -07002045 ) and ad.droid.connectivityGetIPv4DefaultGateway():
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08002046 break
2047 time.sleep(1)
Girish Moturu804a3492020-02-17 14:32:02 -08002048 ping = False
2049 try:
2050 ping = ad.droid.httpPing(ping_addr)
2051 ad.log.info("Http ping result: %s.", ping)
2052 except:
2053 pass
2054 if not ping and ping_gateway:
2055 ad.log.info("Http ping failed. Pinging default gateway")
2056 gw = ad.droid.connectivityGetIPv4DefaultGateway()
2057 result = ad.adb.shell("ping -c 6 {}".format(gw))
2058 ad.log.info("Default gateway ping result: %s" % result)
2059 ping = False if "100% packet loss" in result else True
Ang Li73697b32015-12-03 00:41:53 +00002060 return ping
2061
Ang Li82522812016-06-02 13:57:21 -07002062
Ang Li73697b32015-12-03 00:41:53 +00002063#TODO(angli): This can only verify if an actual value is exactly the same.
2064# Would be nice to be able to verify an actual value is one of serveral.
2065def verify_wifi_connection_info(ad, expected_con):
2066 """Verifies that the information of the currently connected wifi network is
2067 as expected.
2068
2069 Args:
2070 expected_con: A dict representing expected key-value pairs for wifi
2071 connection. e.g. {"SSID": "test_wifi"}
2072 """
2073 current_con = ad.droid.wifiGetConnectionInfo()
Ang Li374d7602016-02-08 17:27:27 -08002074 case_insensitive = ["BSSID", "supplicant_state"]
Ang Li31b00782016-06-21 13:04:23 -07002075 ad.log.debug("Current connection: %s", current_con)
Ang Li73697b32015-12-03 00:41:53 +00002076 for k, expected_v in expected_con.items():
Ang Li9a66de72016-02-08 15:26:38 -08002077 # Do not verify authentication related fields.
2078 if k == "password":
2079 continue
Ang Li82522812016-06-02 13:57:21 -07002080 msg = "Field %s does not exist in wifi connection info %s." % (
2081 k, current_con)
Ang Li374d7602016-02-08 17:27:27 -08002082 if k not in current_con:
2083 raise signals.TestFailure(msg)
2084 actual_v = current_con[k]
2085 if k in case_insensitive:
2086 actual_v = actual_v.lower()
2087 expected_v = expected_v.lower()
Ang Li73697b32015-12-03 00:41:53 +00002088 msg = "Expected %s to be %s, actual %s is %s." % (k, expected_v, k,
Ang Li82522812016-06-02 13:57:21 -07002089 actual_v)
Ang Li374d7602016-02-08 17:27:27 -08002090 if actual_v != expected_v:
2091 raise signals.TestFailure(msg)
Ang Li73697b32015-12-03 00:41:53 +00002092
Ang Li82522812016-06-02 13:57:21 -07002093
Omar El Ayach8c017902020-10-18 10:26:57 -07002094def check_autoconnect_to_open_network(
2095 ad, conn_timeout=WIFI_CONNECTION_TIMEOUT_DEFAULT):
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08002096 """Connects to any open WiFI AP
2097 Args:
2098 timeout value in sec to wait for UE to connect to a WiFi AP
2099 Returns:
2100 True if UE connects to WiFi AP (supplicant_state = completed)
2101 False if UE fails to complete connection within WIFI_CONNECTION_TIMEOUT time.
2102 """
2103 if ad.droid.wifiCheckState():
2104 return True
2105 ad.droid.wifiToggleState()
2106 wifi_connection_state = None
2107 timeout = time.time() + conn_timeout
2108 while wifi_connection_state != "completed":
Omar El Ayach8c017902020-10-18 10:26:57 -07002109 wifi_connection_state = ad.droid.wifiGetConnectionInfo(
2110 )['supplicant_state']
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08002111 if time.time() > timeout:
2112 ad.log.warning("Failed to connect to WiFi AP")
2113 return False
2114 return True
2115
2116
Ang Li73697b32015-12-03 00:41:53 +00002117def expand_enterprise_config_by_phase2(config):
2118 """Take an enterprise config and generate a list of configs, each with
2119 a different phase2 auth type.
2120
2121 Args:
2122 config: A dict representing enterprise config.
2123
2124 Returns
2125 A list of enterprise configs.
2126 """
2127 results = []
Ang Li0e7e58f2016-02-22 12:15:02 -08002128 phase2_types = WifiEnums.EapPhase2
2129 if config[WifiEnums.Enterprise.EAP] == WifiEnums.Eap.PEAP:
2130 # Skip unsupported phase2 types for PEAP.
2131 phase2_types = [WifiEnums.EapPhase2.GTC, WifiEnums.EapPhase2.MSCHAPV2]
2132 for phase2_type in phase2_types:
Ang Li73697b32015-12-03 00:41:53 +00002133 # Skip a special case for passpoint TTLS.
Omar El Ayach8c017902020-10-18 10:26:57 -07002134 if (WifiEnums.Enterprise.FQDN in config
2135 and phase2_type == WifiEnums.EapPhase2.GTC):
Ang Li73697b32015-12-03 00:41:53 +00002136 continue
2137 c = dict(config)
Girish Moturu150d32f2017-02-14 12:27:07 -08002138 c[WifiEnums.Enterprise.PHASE2] = phase2_type.value
Ang Li73697b32015-12-03 00:41:53 +00002139 results.append(c)
2140 return results
Ang Li2d3fe982016-06-08 10:00:43 -07002141
2142
Girish Moturub48a13c2017-02-27 11:36:42 -08002143def generate_eap_test_name(config, ad=None):
Girish Moturu150d32f2017-02-14 12:27:07 -08002144 """ Generates a test case name based on an EAP configuration.
2145
2146 Args:
2147 config: A dict representing an EAP credential.
Girish Moturub48a13c2017-02-27 11:36:42 -08002148 ad object: Redundant but required as the same param is passed
2149 to test_func in run_generated_tests
Girish Moturu150d32f2017-02-14 12:27:07 -08002150
2151 Returns:
2152 A string representing the name of a generated EAP test case.
2153 """
2154 eap = WifiEnums.Eap
2155 eap_phase2 = WifiEnums.EapPhase2
Girish Moturub48a13c2017-02-27 11:36:42 -08002156 Ent = WifiEnums.Enterprise
Girish Moturu150d32f2017-02-14 12:27:07 -08002157 name = "test_connect-"
2158 eap_name = ""
2159 for e in eap:
2160 if e.value == config[Ent.EAP]:
2161 eap_name = e.name
2162 break
2163 if "peap0" in config[WifiEnums.SSID_KEY].lower():
2164 eap_name = "PEAP0"
2165 if "peap1" in config[WifiEnums.SSID_KEY].lower():
2166 eap_name = "PEAP1"
2167 name += eap_name
2168 if Ent.PHASE2 in config:
2169 for e in eap_phase2:
2170 if e.value == config[Ent.PHASE2]:
2171 name += "-{}".format(e.name)
2172 break
2173 return name
2174
2175
Ang Li2d3fe982016-06-08 10:00:43 -07002176def group_attenuators(attenuators):
2177 """Groups a list of attenuators into attenuator groups for backward
2178 compatibility reasons.
2179
2180 Most legacy Wi-Fi setups have two attenuators each connected to a separate
2181 AP. The new Wi-Fi setup has four attenuators, each connected to one channel
2182 on an AP, so two of them are connected to one AP.
2183
2184 To make the existing scripts work in the new setup, when the script needs
2185 to attenuate one AP, it needs to set attenuation on both attenuators
2186 connected to the same AP.
2187
2188 This function groups attenuators properly so the scripts work in both
2189 legacy and new Wi-Fi setups.
2190
2191 Args:
2192 attenuators: A list of attenuator objects, either two or four in length.
2193
2194 Raises:
2195 signals.TestFailure is raised if the attenuator list does not have two
2196 or four objects.
2197 """
2198 attn0 = attenuator.AttenuatorGroup("AP0")
2199 attn1 = attenuator.AttenuatorGroup("AP1")
2200 # Legacy testbed setup has two attenuation channels.
2201 num_of_attns = len(attenuators)
2202 if num_of_attns == 2:
2203 attn0.add(attenuators[0])
2204 attn1.add(attenuators[1])
2205 elif num_of_attns == 4:
2206 attn0.add(attenuators[0])
2207 attn0.add(attenuators[1])
2208 attn1.add(attenuators[2])
2209 attn1.add(attenuators[3])
2210 else:
2211 asserts.fail(("Either two or four attenuators are required for this "
2212 "test, but found %s") % num_of_attns)
2213 return [attn0, attn1]
Jong Wook Kim92356922018-02-06 18:32:49 -08002214
Bindu Mahadevff295782019-02-08 16:17:48 -08002215
Girish Moturu36348a32019-12-10 08:41:54 -08002216def set_attns(attenuator, attn_val_name, roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002217 """Sets attenuation values on attenuators used in this test.
2218
2219 Args:
2220 attenuator: The attenuator object.
2221 attn_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002222 roaming_attn: Dictionary specifying the attenuation params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002223 """
2224 logging.info("Set attenuation values to %s", roaming_attn[attn_val_name])
2225 try:
2226 attenuator[0].set_atten(roaming_attn[attn_val_name][0])
2227 attenuator[1].set_atten(roaming_attn[attn_val_name][1])
2228 attenuator[2].set_atten(roaming_attn[attn_val_name][2])
2229 attenuator[3].set_atten(roaming_attn[attn_val_name][3])
2230 except:
2231 logging.exception("Failed to set attenuation values %s.",
Omar El Ayach8c017902020-10-18 10:26:57 -07002232 attn_val_name)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002233 raise
2234
Omar El Ayach8c017902020-10-18 10:26:57 -07002235
Girish Moturu36348a32019-12-10 08:41:54 -08002236def set_attns_steps(attenuators,
2237 atten_val_name,
2238 roaming_attn=ROAMING_ATTN,
2239 steps=10,
2240 wait_time=12):
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002241 """Set attenuation values on attenuators used in this test. It will change
2242 the attenuation values linearly from current value to target value step by
2243 step.
2244
2245 Args:
2246 attenuators: The list of attenuator objects that you want to change
2247 their attenuation value.
2248 atten_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002249 roaming_attn: Dictionary specifying the attenuation params.
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002250 steps: Number of attenuator changes to reach the target value.
2251 wait_time: Sleep time for each change of attenuator.
2252 """
2253 logging.info("Set attenuation values to %s in %d step(s)",
Omar El Ayach8c017902020-10-18 10:26:57 -07002254 roaming_attn[atten_val_name], steps)
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002255 start_atten = [attenuator.get_atten() for attenuator in attenuators]
2256 target_atten = roaming_attn[atten_val_name]
2257 for current_step in range(steps):
2258 progress = (current_step + 1) / steps
2259 for i, attenuator in enumerate(attenuators):
2260 amount_since_start = (target_atten[i] - start_atten[i]) * progress
2261 attenuator.set_atten(round(start_atten[i] + amount_since_start))
2262 time.sleep(wait_time)
2263
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002264
Girish Moturu36348a32019-12-10 08:41:54 -08002265def trigger_roaming_and_validate(dut,
2266 attenuator,
2267 attn_val_name,
2268 expected_con,
2269 roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002270 """Sets attenuators to trigger roaming and validate the DUT connected
2271 to the BSSID expected.
2272
2273 Args:
2274 attenuator: The attenuator object.
2275 attn_val_name: Name of the attenuation value pair to use.
2276 expected_con: The network information of the expected network.
Girish Moturu36348a32019-12-10 08:41:54 -08002277 roaming_attn: Dictionary specifying the attenaution params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002278 """
2279 expected_con = {
2280 WifiEnums.SSID_KEY: expected_con[WifiEnums.SSID_KEY],
2281 WifiEnums.BSSID_KEY: expected_con["bssid"],
2282 }
Girish Moturu36348a32019-12-10 08:41:54 -08002283 set_attns_steps(attenuator, attn_val_name, roaming_attn)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002284
Hsiu-Chang Chenef856402018-09-18 12:32:49 +08002285 verify_wifi_connection_info(dut, expected_con)
2286 expected_bssid = expected_con[WifiEnums.BSSID_KEY]
2287 logging.info("Roamed to %s successfully", expected_bssid)
2288 if not validate_connection(dut):
2289 raise signals.TestFailure("Fail to connect to internet on %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07002290 expected_bssid)
2291
Jong Wook Kim92356922018-02-06 18:32:49 -08002292
2293def create_softap_config():
2294 """Create a softap config with random ssid and password."""
2295 ap_ssid = "softap_" + utils.rand_ascii_str(8)
2296 ap_password = utils.rand_ascii_str(8)
2297 logging.info("softap setup: %s %s", ap_ssid, ap_password)
2298 config = {
2299 WifiEnums.SSID_KEY: ap_ssid,
2300 WifiEnums.PWD_KEY: ap_password,
2301 }
2302 return config
Girish Moturucf4dccd2018-08-27 12:22:00 -07002303
Omar El Ayach8c017902020-10-18 10:26:57 -07002304
Bindu Mahadevff295782019-02-08 16:17:48 -08002305def start_softap_and_verify(ad, band):
2306 """Bring-up softap and verify AP mode and in scan results.
2307
2308 Args:
2309 band: The band to use for softAP.
2310
2311 Returns: dict, the softAP config.
2312
2313 """
lesl2f0fb232019-11-05 16:35:28 +08002314 # Register before start the test.
2315 callbackId = ad.dut.droid.registerSoftApCallback()
2316 # Check softap info value is default
2317 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2318 asserts.assert_true(frequency == 0, "Softap frequency is not reset")
2319 asserts.assert_true(bandwdith == 0, "Softap bandwdith is not reset")
2320
Bindu Mahadevff295782019-02-08 16:17:48 -08002321 config = create_softap_config()
2322 start_wifi_tethering(ad.dut,
2323 config[WifiEnums.SSID_KEY],
Omar El Ayach8c017902020-10-18 10:26:57 -07002324 config[WifiEnums.PWD_KEY],
2325 band=band)
Bindu Mahadevff295782019-02-08 16:17:48 -08002326 asserts.assert_true(ad.dut.droid.wifiIsApEnabled(),
Omar El Ayach8c017902020-10-18 10:26:57 -07002327 "SoftAp is not reported as running")
2328 start_wifi_connection_scan_and_ensure_network_found(
2329 ad.dut_client, config[WifiEnums.SSID_KEY])
lesl2f0fb232019-11-05 16:35:28 +08002330
2331 # Check softap info can get from callback succeed and assert value should be
2332 # valid.
2333 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2334 asserts.assert_true(frequency > 0, "Softap frequency is not valid")
2335 asserts.assert_true(bandwdith > 0, "Softap bandwdith is not valid")
2336 # Unregister callback
2337 ad.dut.droid.unregisterSoftApCallback(callbackId)
2338
Bindu Mahadevff295782019-02-08 16:17:48 -08002339 return config
2340
Omar El Ayach8c017902020-10-18 10:26:57 -07002341
lesle8e3c0a2019-02-22 17:06:04 +08002342def wait_for_expected_number_of_softap_clients(ad, callbackId,
Omar El Ayach8c017902020-10-18 10:26:57 -07002343 expected_num_of_softap_clients):
lesle8e3c0a2019-02-22 17:06:04 +08002344 """Wait for the number of softap clients to be updated as expected.
2345 Args:
2346 callbackId: Id of the callback associated with registering.
2347 expected_num_of_softap_clients: expected number of softap clients.
2348 """
2349 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002350 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
James Mattis5a5dd492020-05-14 13:09:43 -07002351 clientData = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data']
2352 clientCount = clientData[wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07002353 clientMacAddresses = clientData[
2354 wifi_constants.SOFTAP_CLIENTS_MACS_CALLBACK_KEY]
2355 asserts.assert_equal(
2356 clientCount, expected_num_of_softap_clients,
2357 "The number of softap clients doesn't match the expected number")
2358 asserts.assert_equal(
2359 len(clientMacAddresses), expected_num_of_softap_clients,
2360 "The number of mac addresses doesn't match the expected number")
James Mattis5a5dd492020-05-14 13:09:43 -07002361 for macAddress in clientMacAddresses:
Omar El Ayach8c017902020-10-18 10:26:57 -07002362 asserts.assert_true(checkMacAddress(macAddress),
2363 "An invalid mac address was returned")
2364
James Mattis5a5dd492020-05-14 13:09:43 -07002365
2366def checkMacAddress(input):
2367 """Validate whether a string is a valid mac address or not.
2368
2369 Args:
2370 input: The string to validate.
2371
2372 Returns: True/False, returns true for a valid mac address and false otherwise.
2373 """
2374 macValidationRegex = "[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$"
2375 if re.match(macValidationRegex, input.lower()):
2376 return True
2377 return False
lesle8e3c0a2019-02-22 17:06:04 +08002378
Omar El Ayach8c017902020-10-18 10:26:57 -07002379
lesle8e3c0a2019-02-22 17:06:04 +08002380def wait_for_expected_softap_state(ad, callbackId, expected_softap_state):
2381 """Wait for the expected softap state change.
2382 Args:
2383 callbackId: Id of the callback associated with registering.
2384 expected_softap_state: The expected softap state.
2385 """
2386 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002387 callbackId) + wifi_constants.SOFTAP_STATE_CHANGED
2388 asserts.assert_equal(
2389 ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data'][
2390 wifi_constants.SOFTAP_STATE_CHANGE_CALLBACK_KEY],
2391 expected_softap_state,
2392 "Softap state doesn't match with expected state")
2393
lesle8e3c0a2019-02-22 17:06:04 +08002394
2395def get_current_number_of_softap_clients(ad, callbackId):
2396 """pop up all of softap client updated event from queue.
2397 Args:
2398 callbackId: Id of the callback associated with registering.
2399
2400 Returns:
2401 If exist aleast callback, returns last updated number_of_softap_clients.
2402 Returns None when no any match callback event in queue.
2403 """
2404 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002405 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
lesle8e3c0a2019-02-22 17:06:04 +08002406 events = ad.ed.pop_all(eventStr)
2407 for event in events:
Omar El Ayach8c017902020-10-18 10:26:57 -07002408 num_of_clients = event['data'][
2409 wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
lesle8e3c0a2019-02-22 17:06:04 +08002410 if len(events) == 0:
2411 return None
2412 return num_of_clients
Bindu Mahadevff295782019-02-08 16:17:48 -08002413
Omar El Ayach8c017902020-10-18 10:26:57 -07002414
lesl67124362021-05-04 19:33:14 +08002415def get_current_softap_info(ad, callbackId, need_to_wait):
lesl2f0fb232019-11-05 16:35:28 +08002416 """pop up all of softap info changed event from queue.
2417 Args:
2418 callbackId: Id of the callback associated with registering.
lesl67124362021-05-04 19:33:14 +08002419 need_to_wait: Wait for the info callback event before pop all.
lesl2f0fb232019-11-05 16:35:28 +08002420 Returns:
2421 Returns last updated information of softap.
2422 """
2423 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002424 callbackId) + wifi_constants.SOFTAP_INFO_CHANGED
lesl67124362021-05-04 19:33:14 +08002425 ad.log.debug("softap info dump from eventStr %s", eventStr)
lesl2f0fb232019-11-05 16:35:28 +08002426 frequency = 0
2427 bandwidth = 0
lesl67124362021-05-04 19:33:14 +08002428 if (need_to_wait):
lesl2f0fb232019-11-05 16:35:28 +08002429 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
Omar El Ayach8c017902020-10-18 10:26:57 -07002430 frequency = event['data'][
2431 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2432 bandwidth = event['data'][
2433 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
lesl2f0fb232019-11-05 16:35:28 +08002434 ad.log.info("softap info updated, frequency is %s, bandwidth is %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07002435 frequency, bandwidth)
lesl2f0fb232019-11-05 16:35:28 +08002436
2437 events = ad.ed.pop_all(eventStr)
2438 for event in events:
Omar El Ayach8c017902020-10-18 10:26:57 -07002439 frequency = event['data'][
2440 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2441 bandwidth = event['data'][
2442 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
2443 ad.log.info("softap info, frequency is %s, bandwidth is %s", frequency,
2444 bandwidth)
lesl2f0fb232019-11-05 16:35:28 +08002445 return frequency, bandwidth
2446
lesl67124362021-05-04 19:33:14 +08002447def get_current_softap_infos(ad, callbackId, need_to_wait):
2448 """pop up all of softap info list changed event from queue.
2449 Args:
2450 callbackId: Id of the callback associated with registering.
2451 need_to_wait: Wait for the info callback event before pop all.
2452 Returns:
2453 Returns last updated informations of softap.
2454 """
2455 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
2456 callbackId) + wifi_constants.SOFTAP_INFOLIST_CHANGED
2457 ad.log.debug("softap info dump from eventStr %s", eventStr)
2458
2459 if (need_to_wait):
2460 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
2461 infos = event['data']
2462
2463 events = ad.ed.pop_all(eventStr)
2464 for event in events:
2465 infos = event['data']
2466
2467 for info in infos:
2468 frequency = info[
2469 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2470 bandwidth = info[
2471 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
2472 wifistandard = info[
2473 wifi_constants.SOFTAP_INFO_WIFISTANDARD_CALLBACK_KEY]
2474 bssid = info[
2475 wifi_constants.SOFTAP_INFO_BSSID_CALLBACK_KEY]
2476 ad.log.info(
2477 "softap info, freq:%s, bw:%s, wifistandard:%s, bssid:%s",
2478 frequency, bandwidth, wifistandard, bssid)
2479
2480 return infos
2481
2482def get_current_softap_capability(ad, callbackId, need_to_wait):
2483 """pop up all of softap info list changed event from queue.
2484 Args:
2485 callbackId: Id of the callback associated with registering.
2486 need_to_wait: Wait for the info callback event before pop all.
2487 Returns:
2488 Returns last updated capability of softap.
2489 """
2490 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
2491 callbackId) + wifi_constants.SOFTAP_CAPABILITY_CHANGED
2492 ad.log.debug("softap capability dump from eventStr %s", eventStr)
2493 if (need_to_wait):
2494 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
2495 capability = event['data']
2496
2497 events = ad.ed.pop_all(eventStr)
2498 for event in events:
2499 capability = event['data']
2500
2501 return capability
lesl2f0fb232019-11-05 16:35:28 +08002502
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002503def get_ssrdumps(ad):
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002504 """Pulls dumps in the ssrdump dir
2505 Args:
2506 ad: android device object.
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002507 """
2508 logs = ad.get_file_names("/data/vendor/ssrdump/")
2509 if logs:
2510 ad.log.info("Pulling ssrdumps %s", logs)
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002511 log_path = os.path.join(ad.device_log_path, "SSRDUMPS_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002512 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002513 ad.pull_files(logs, log_path)
Hsiu-Chang Chen769bef12020-10-10 06:07:52 +00002514 ad.adb.shell("find /data/vendor/ssrdump/ -type f -delete",
Omar El Ayach8c017902020-10-18 10:26:57 -07002515 ignore_status=True)
2516
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002517
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002518def start_pcap(pcap, wifi_band, test_name):
Girish Moturucf4dccd2018-08-27 12:22:00 -07002519 """Start packet capture in monitor mode.
2520
2521 Args:
2522 pcap: packet capture object
2523 wifi_band: '2g' or '5g' or 'dual'
Bindu Mahadev76551c12018-12-13 19:42:14 +00002524 test_name: test name to be used for pcap file name
2525
2526 Returns:
xianyuanjia0431ba32018-12-14 09:56:42 -08002527 Dictionary with wifi band as key and the tuple
2528 (pcap Process object, log directory) as the value
Girish Moturucf4dccd2018-08-27 12:22:00 -07002529 """
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002530 log_dir = os.path.join(
Xianyuan Jia5cd06bb2019-06-10 16:29:57 -07002531 context.get_current_context().get_full_output_path(), 'PacketCapture')
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002532 os.makedirs(log_dir, exist_ok=True)
Girish Moturucf4dccd2018-08-27 12:22:00 -07002533 if wifi_band == 'dual':
2534 bands = [BAND_2G, BAND_5G]
2535 else:
2536 bands = [wifi_band]
xianyuanjia0431ba32018-12-14 09:56:42 -08002537 procs = {}
Girish Moturucf4dccd2018-08-27 12:22:00 -07002538 for band in bands:
xianyuanjia0431ba32018-12-14 09:56:42 -08002539 proc = pcap.start_packet_capture(band, log_dir, test_name)
2540 procs[band] = (proc, os.path.join(log_dir, test_name))
2541 return procs
Girish Moturucf4dccd2018-08-27 12:22:00 -07002542
Bindu Mahadevff295782019-02-08 16:17:48 -08002543
xianyuanjia0431ba32018-12-14 09:56:42 -08002544def stop_pcap(pcap, procs, test_status=None):
Bindu Mahadev76551c12018-12-13 19:42:14 +00002545 """Stop packet capture in monitor mode.
2546
2547 Since, the pcap logs in monitor mode can be very large, we will
2548 delete them if they are not required. 'test_status' if True, will delete
2549 the pcap files. If False, we will keep them.
Girish Moturucf4dccd2018-08-27 12:22:00 -07002550
2551 Args:
2552 pcap: packet capture object
xianyuanjia0431ba32018-12-14 09:56:42 -08002553 procs: dictionary returned by start_pcap
Bindu Mahadev76551c12018-12-13 19:42:14 +00002554 test_status: status of the test case
Girish Moturucf4dccd2018-08-27 12:22:00 -07002555 """
xianyuanjia0431ba32018-12-14 09:56:42 -08002556 for proc, fname in procs.values():
2557 pcap.stop_packet_capture(proc)
Bindu Mahadev76551c12018-12-13 19:42:14 +00002558
2559 if test_status:
xianyuanjia0431ba32018-12-14 09:56:42 -08002560 shutil.rmtree(os.path.dirname(fname))
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002561
Omar El Ayach8c017902020-10-18 10:26:57 -07002562
Jaineel95887fd2019-10-16 16:19:01 -07002563def verify_mac_not_found_in_pcap(ad, mac, packets):
xshuf7267682019-06-03 14:41:56 -07002564 """Verify that a mac address is not found in the captured packets.
2565
2566 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002567 ad: android device object
xshuf7267682019-06-03 14:41:56 -07002568 mac: string representation of the mac address
2569 packets: packets obtained by rdpcap(pcap_fname)
2570 """
2571 for pkt in packets:
2572 logging.debug("Packet Summary = %s", pkt.summary())
2573 if mac in pkt.summary():
Jaineel95887fd2019-10-16 16:19:01 -07002574 asserts.fail("Device %s caught Factory MAC: %s in packet sniffer."
2575 "Packet = %s" % (ad.serial, mac, pkt.show()))
Bindu Mahadevff295782019-02-08 16:17:48 -08002576
Omar El Ayach8c017902020-10-18 10:26:57 -07002577
Jaineel95887fd2019-10-16 16:19:01 -07002578def verify_mac_is_found_in_pcap(ad, mac, packets):
Nate Jiangc2c09c62019-06-05 17:26:08 -07002579 """Verify that a mac address is found in the captured packets.
2580
2581 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002582 ad: android device object
Nate Jiangc2c09c62019-06-05 17:26:08 -07002583 mac: string representation of the mac address
2584 packets: packets obtained by rdpcap(pcap_fname)
2585 """
2586 for pkt in packets:
2587 if mac in pkt.summary():
2588 return
Jaineel95887fd2019-10-16 16:19:01 -07002589 asserts.fail("Did not find MAC = %s in packet sniffer."
2590 "for device %s" % (mac, ad.serial))
Nate Jiangc2c09c62019-06-05 17:26:08 -07002591
Omar El Ayach8c017902020-10-18 10:26:57 -07002592
Girish Moturuddc0d382020-08-24 12:08:41 -07002593def start_cnss_diags(ads, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002594 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002595 start_cnss_diag(ad, cnss_diag_file, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002596
Bindu Mahadevff295782019-02-08 16:17:48 -08002597
Girish Moturuddc0d382020-08-24 12:08:41 -07002598def start_cnss_diag(ad, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002599 """Start cnss_diag to record extra wifi logs
2600
2601 Args:
2602 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002603 cnss_diag_file: cnss diag config file to push to device.
2604 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002605 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002606 if ad.model not in pixel_models:
2607 ad.log.info("Device not supported to collect pixel logger")
2608 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002609 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2610 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2611 else:
2612 prop = wifi_constants.CNSS_DIAG_PROP
2613 if ad.adb.getprop(prop) != 'true':
Omar El Ayach8c017902020-10-18 10:26:57 -07002614 if not int(
2615 ad.adb.shell("ls -l %s%s | wc -l" %
2616 (CNSS_DIAG_CONFIG_PATH, CNSS_DIAG_CONFIG_FILE))):
Girish Moturuddc0d382020-08-24 12:08:41 -07002617 ad.adb.push("%s %s" % (cnss_diag_file, CNSS_DIAG_CONFIG_PATH))
Omar El Ayach8c017902020-10-18 10:26:57 -07002618 ad.adb.shell(
2619 "find /data/vendor/wifi/cnss_diag/wlan_logs/ -type f -delete",
2620 ignore_status=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002621 ad.adb.shell("setprop %s true" % prop, ignore_status=True)
2622
Bindu Mahadevff295782019-02-08 16:17:48 -08002623
Girish Moturuddc0d382020-08-24 12:08:41 -07002624def stop_cnss_diags(ads, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002625 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002626 stop_cnss_diag(ad, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002627
Bindu Mahadevff295782019-02-08 16:17:48 -08002628
Girish Moturuddc0d382020-08-24 12:08:41 -07002629def stop_cnss_diag(ad, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002630 """Stops cnss_diag
2631
2632 Args:
2633 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002634 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002635 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002636 if ad.model not in pixel_models:
2637 ad.log.info("Device not supported to collect pixel logger")
2638 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002639 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2640 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2641 else:
2642 prop = wifi_constants.CNSS_DIAG_PROP
2643 ad.adb.shell("setprop %s false" % prop, ignore_status=True)
2644
Bindu Mahadevff295782019-02-08 16:17:48 -08002645
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002646def get_cnss_diag_log(ad):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002647 """Pulls the cnss_diag logs in the wlan_logs dir
2648 Args:
2649 ad: android device object.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002650 """
2651 logs = ad.get_file_names("/data/vendor/wifi/cnss_diag/wlan_logs/")
2652 if logs:
2653 ad.log.info("Pulling cnss_diag logs %s", logs)
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002654 log_path = os.path.join(ad.device_log_path, "CNSS_DIAG_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002655 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002656 ad.pull_files(logs, log_path)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002657
Bindu Mahadevff295782019-02-08 16:17:48 -08002658
Omar El Ayach8c017902020-10-18 10:26:57 -07002659LinkProbeResult = namedtuple(
2660 'LinkProbeResult',
2661 ('is_success', 'stdout', 'elapsed_time', 'failure_reason'))
David Sue4cd9c22019-03-26 18:07:26 -07002662
2663
2664def send_link_probe(ad):
2665 """Sends a link probe to the currently connected AP, and returns whether the
2666 probe succeeded or not.
2667
2668 Args:
2669 ad: android device object
2670 Returns:
2671 LinkProbeResult namedtuple
2672 """
2673 stdout = ad.adb.shell('cmd wifi send-link-probe')
2674 asserts.assert_false('Error' in stdout or 'Exception' in stdout,
2675 'Exception while sending link probe: ' + stdout)
2676
2677 is_success = False
2678 elapsed_time = None
2679 failure_reason = None
2680 if 'succeeded' in stdout:
2681 is_success = True
2682 elapsed_time = next(
2683 (int(token) for token in stdout.split() if token.isdigit()), None)
2684 elif 'failed with reason' in stdout:
2685 failure_reason = next(
2686 (int(token) for token in stdout.split() if token.isdigit()), None)
2687 else:
2688 asserts.fail('Unexpected link probe result: ' + stdout)
2689
Omar El Ayach8c017902020-10-18 10:26:57 -07002690 return LinkProbeResult(is_success=is_success,
2691 stdout=stdout,
2692 elapsed_time=elapsed_time,
2693 failure_reason=failure_reason)
David Sue4cd9c22019-03-26 18:07:26 -07002694
2695
2696def send_link_probes(ad, num_probes, delay_sec):
2697 """Sends a sequence of link probes to the currently connected AP, and
2698 returns whether the probes succeeded or not.
2699
2700 Args:
2701 ad: android device object
2702 num_probes: number of probes to perform
2703 delay_sec: delay time between probes, in seconds
2704 Returns:
2705 List[LinkProbeResult] one LinkProbeResults for each probe
2706 """
2707 logging.info('Sending link probes')
2708 results = []
2709 for _ in range(num_probes):
2710 # send_link_probe() will also fail the test if it sees an exception
2711 # in the stdout of the adb shell command
2712 result = send_link_probe(ad)
2713 logging.info('link probe results: ' + str(result))
2714 results.append(result)
2715 time.sleep(delay_sec)
2716
2717 return results
2718
2719
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002720def ap_setup(test, index, ap, network, bandwidth=80, channel=6):
Omar El Ayach8c017902020-10-18 10:26:57 -07002721 """Set up the AP with provided network info.
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002722
2723 Args:
2724 test: the calling test class object.
2725 index: int, index of the AP.
2726 ap: access_point object of the AP.
2727 network: dict with information of the network, including ssid,
2728 password and bssid.
2729 bandwidth: the operation bandwidth for the AP, default 80MHz.
2730 channel: the channel number for the AP.
2731 Returns:
2732 brconfigs: the bridge interface configs
2733 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002734 bss_settings = []
2735 ssid = network[WifiEnums.SSID_KEY]
2736 test.access_points[index].close()
2737 time.sleep(5)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002738
Omar El Ayach8c017902020-10-18 10:26:57 -07002739 # Configure AP as required.
2740 if "password" in network.keys():
2741 password = network["password"]
2742 security = hostapd_security.Security(security_mode="wpa",
2743 password=password)
2744 else:
2745 security = hostapd_security.Security(security_mode=None, password=None)
2746 config = hostapd_ap_preset.create_ap_preset(channel=channel,
2747 ssid=ssid,
2748 security=security,
2749 bss_settings=bss_settings,
2750 vht_bandwidth=bandwidth,
2751 profile_name='whirlwind',
2752 iface_wlan_2g=ap.wlan_2g,
2753 iface_wlan_5g=ap.wlan_5g)
2754 ap.start_ap(config)
2755 logging.info("AP started on channel {} with SSID {}".format(channel, ssid))
Bindu Mahadevff295782019-02-08 16:17:48 -08002756
2757
2758def turn_ap_off(test, AP):
2759 """Bring down hostapd on the Access Point.
2760 Args:
2761 test: The test class object.
2762 AP: int, indicating which AP to turn OFF.
2763 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002764 hostapd_2g = test.access_points[AP - 1]._aps['wlan0'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002765 if hostapd_2g.is_alive():
2766 hostapd_2g.stop()
2767 logging.debug('Turned WLAN0 AP%d off' % AP)
Omar El Ayach8c017902020-10-18 10:26:57 -07002768 hostapd_5g = test.access_points[AP - 1]._aps['wlan1'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002769 if hostapd_5g.is_alive():
2770 hostapd_5g.stop()
2771 logging.debug('Turned WLAN1 AP%d off' % AP)
2772
2773
2774def turn_ap_on(test, AP):
2775 """Bring up hostapd on the Access Point.
2776 Args:
2777 test: The test class object.
2778 AP: int, indicating which AP to turn ON.
2779 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002780 hostapd_2g = test.access_points[AP - 1]._aps['wlan0'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002781 if not hostapd_2g.is_alive():
2782 hostapd_2g.start(hostapd_2g.config)
2783 logging.debug('Turned WLAN0 AP%d on' % AP)
Omar El Ayach8c017902020-10-18 10:26:57 -07002784 hostapd_5g = test.access_points[AP - 1]._aps['wlan1'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002785 if not hostapd_5g.is_alive():
2786 hostapd_5g.start(hostapd_5g.config)
2787 logging.debug('Turned WLAN1 AP%d on' % AP)
Joe Brennan48c3f692019-04-11 08:30:16 -07002788
2789
2790def turn_location_off_and_scan_toggle_off(ad):
2791 """Turns off wifi location scans."""
2792 utils.set_location_service(ad, False)
2793 ad.droid.wifiScannerToggleAlwaysAvailable(False)
2794 msg = "Failed to turn off location service's scan."
2795 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
Alfie Chen675be872020-06-04 10:48:14 +08002796
2797
2798def set_softap_channel(dut, ap_iface='wlan1', cs_count=10, channel=2462):
2799 """ Set SoftAP mode channel
2800
2801 Args:
2802 dut: android device object
2803 ap_iface: interface of SoftAP mode.
2804 cs_count: how many beacon frames before switch channel, default = 10
2805 channel: a wifi channel.
2806 """
2807 chan_switch_cmd = 'hostapd_cli -i {} chan_switch {} {}'
Omar El Ayach8c017902020-10-18 10:26:57 -07002808 chan_switch_cmd_show = chan_switch_cmd.format(ap_iface, cs_count, channel)
Alfie Chen675be872020-06-04 10:48:14 +08002809 dut.log.info('adb shell {}'.format(chan_switch_cmd_show))
Omar El Ayach8c017902020-10-18 10:26:57 -07002810 chan_switch_result = dut.adb.shell(
2811 chan_switch_cmd.format(ap_iface, cs_count, channel))
Alfie Chen675be872020-06-04 10:48:14 +08002812 if chan_switch_result == 'OK':
2813 dut.log.info('switch hotspot channel to {}'.format(channel))
2814 return chan_switch_result
2815
2816 asserts.fail("Failed to switch hotspot channel")
Alfie Chen310f7ff2021-01-26 20:36:09 +08002817
2818def get_wlan0_link(dut):
2819 """ get wlan0 interface status"""
2820 get_wlan0 = 'wpa_cli -iwlan0 -g@android:wpa_wlan0 IFNAME=wlan0 status'
2821 out = dut.adb.shell(get_wlan0)
2822 out = dict(re.findall(r'(\S+)=(".*?"|\S+)', out))
2823 asserts.assert_true("ssid" in out,
2824 "Client doesn't connect to any network")
Alfie Chenb3263dd2021-02-04 18:54:34 +08002825 return out
Girish Moturubea6c7e2021-05-07 16:24:27 -07002826
2827def verify_11ax_wifi_connection(ad, wifi6_supported_models, wifi6_ap):
2828 """Verify 11ax for wifi connection.
2829
2830 Args:
2831 ad: adndroid device object
2832 wifi6_supported_models: device supporting 11ax.
2833 wifi6_ap: if the AP supports 11ax.
2834 """
2835 if wifi6_ap and ad.model in wifi6_supported_models:
2836 logging.info("Verifying 11ax. Model: %s" % ad.model)
2837 asserts.assert_true(
2838 ad.droid.wifiGetConnectionStandard() ==
2839 wifi_constants.WIFI_STANDARD_11AX, "DUT did not connect to 11ax.")
2840
2841def verify_11ax_softap(dut, dut_client, wifi6_supported_models):
2842 """Verify 11ax SoftAp if devices support it.
2843
2844 Check if both DUT and DUT client supports 11ax, then SoftAp turns on
2845 with 11ax mode and DUT client can connect to it.
2846
2847 Args:
2848 dut: Softap device.
2849 dut_client: Client connecting to softap.
2850 wifi6_supported_models: List of device models supporting 11ax.
2851 """
2852 if dut.model in wifi6_supported_models and dut_client.model in wifi6_supported_models:
2853 logging.info(
2854 "Verifying 11ax softap. DUT model: %s, DUT Client model: %s",
2855 dut.model, dut_client.model)
2856 asserts.assert_true(
2857 dut_client.droid.wifiGetConnectionStandard() ==
2858 wifi_constants.WIFI_STANDARD_11AX,
2859 "DUT failed to start SoftAp in 11ax.")
“Alfie90ee7cb2021-04-20 23:16:12 +08002860
2861def check_available_channels_in_bands_2_5(dut, country_code):
2862 """Check if DUT is capable of enable BridgedAp.
2863 #TODO: Find a way to make this function flexible by taking an argument.
2864
2865 Args:
2866 country_code: country code, e.g., 'US', 'JP'.
2867 Returns:
2868 True: If DUT is capable of enable BridgedAp.
2869 False: If DUT is not capable of enable BridgedAp.
2870 """
2871 set_wifi_country_code(dut, country_code)
2872 country = dut.droid.wifiGetCountryCode()
2873 dut.log.info("DUT current country code : {}".format(country))
2874 # Wi-Fi ON and OFF to make sure country code take effet.
2875 wifi_toggle_state(dut, True)
2876 wifi_toggle_state(dut, False)
2877
2878 # Register SoftAp Callback and get SoftAp capability.
2879 callbackId = dut.droid.registerSoftApCallback()
2880 capability = get_current_softap_capability(dut, callbackId, True)
2881 dut.droid.unregisterSoftApCallback(callbackId)
2882
2883 if capability[wifi_constants.
2884 SOFTAP_CAPABILITY_24GHZ_SUPPORTED_CHANNEL_LIST] and \
2885 capability[wifi_constants.
2886 SOFTAP_CAPABILITY_5GHZ_SUPPORTED_CHANNEL_LIST]:
2887 return True
2888 return False
2889
2890
2891@retry(tries=5, delay=2)
2892def validate_ping_between_two_clients(dut1, dut2):
2893 """Make 2 DUT ping each other.
2894
2895 Args:
2896 dut1: An AndroidDevice object.
2897 dut2: An AndroidDevice object.
2898 """
2899 # Get DUTs' IPv4 addresses.
2900 dut1_ip = ""
2901 dut2_ip = ""
2902 try:
2903 dut1_ip = dut1.droid.connectivityGetIPv4Addresses('wlan0')[0]
2904 except IndexError as e:
2905 dut1.log.info(
2906 "{} has no Wi-Fi connection, cannot get IPv4 address."
2907 .format(dut1.serial))
2908 try:
2909 dut2_ip = dut2.droid.connectivityGetIPv4Addresses('wlan0')[0]
2910 except IndexError as e:
2911 dut2.log.info(
2912 "{} has no Wi-Fi connection, cannot get IPv4 address."
2913 .format(dut2.serial))
2914 # Test fail if not able to obtain two DUT's IPv4 addresses.
2915 asserts.assert_true(dut1_ip and dut2_ip,
2916 "Ping failed because no DUT's IPv4 address")
2917
2918 dut1.log.info("{} IPv4 addresses : {}".format(dut1.serial, dut1_ip))
2919 dut2.log.info("{} IPv4 addresses : {}".format(dut2.serial, dut2_ip))
2920
2921 # Two clients ping each other
2922 dut1.log.info("{} ping {}".format(dut1_ip, dut2_ip))
2923 asserts.assert_true(
2924 utils.adb_shell_ping(dut1, count=10, dest_ip=dut2_ip,
2925 timeout=20),
2926 "%s ping %s failed" % (dut1.serial, dut2_ip))
2927
2928 dut2.log.info("{} ping {}".format(dut2_ip, dut1_ip))
2929 asserts.assert_true(
2930 utils.adb_shell_ping(dut2, count=10, dest_ip=dut1_ip,
2931 timeout=20),
2932 "%s ping %s failed" % (dut2.serial, dut1_ip))
2933