blob: ed7ed228fe3c4b6ee38dfa304041beb13ef209ce [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
481 def __init__(self, model=None):
Omar El Ayach8c017902020-10-18 10:26:57 -0700482 self.DFS_5G_FREQUENCIES = [
483 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620,
484 5640, 5660, 5680, 5700, 5720
485 ]
Girish Moturu0c567b02017-08-11 16:20:01 -0700486 self.ALL_5G_FREQUENCIES = self.DFS_5G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000487
Bindu Mahadevff295782019-02-08 16:17:48 -0800488
Girish Moturuf02fa1d2017-05-21 09:51:23 +0530489class WifiReferenceNetworks:
490 """ Class to parse and return networks of different band and
491 auth type from reference_networks
492 """
493 def __init__(self, obj):
494 self.reference_networks = obj
495 self.WIFI_2G = "2g"
496 self.WIFI_5G = "5g"
497
498 self.secure_networks_2g = []
499 self.secure_networks_5g = []
500 self.open_networks_2g = []
501 self.open_networks_5g = []
502 self._parse_networks()
503
504 def _parse_networks(self):
505 for network in self.reference_networks:
506 for key in network:
507 if key == self.WIFI_2G:
508 if "password" in network[key]:
509 self.secure_networks_2g.append(network[key])
510 else:
511 self.open_networks_2g.append(network[key])
512 else:
513 if "password" in network[key]:
514 self.secure_networks_5g.append(network[key])
515 else:
516 self.open_networks_5g.append(network[key])
517
518 def return_2g_secure_networks(self):
519 return self.secure_networks_2g
520
521 def return_5g_secure_networks(self):
522 return self.secure_networks_5g
523
524 def return_2g_open_networks(self):
525 return self.open_networks_2g
526
527 def return_5g_open_networks(self):
528 return self.open_networks_5g
529
530 def return_secure_networks(self):
531 return self.secure_networks_2g + self.secure_networks_5g
532
533 def return_open_networks(self):
534 return self.open_networks_2g + self.open_networks_5g
535
Ang Li82522812016-06-02 13:57:21 -0700536
537def _assert_on_fail_handler(func, assert_on_fail, *args, **kwargs):
538 """Wrapper function that handles the bahevior of assert_on_fail.
539
540 When assert_on_fail is True, let all test signals through, which can
541 terminate test cases directly. When assert_on_fail is False, the wrapper
542 raises no test signals and reports operation status by returning True or
543 False.
544
545 Args:
546 func: The function to wrap. This function reports operation status by
547 raising test signals.
548 assert_on_fail: A boolean that specifies if the output of the wrapper
549 is test signal based or return value based.
550 args: Positional args for func.
551 kwargs: Name args for func.
552
553 Returns:
554 If assert_on_fail is True, returns True/False to signal operation
555 status, otherwise return nothing.
556 """
557 try:
558 func(*args, **kwargs)
559 if not assert_on_fail:
560 return True
561 except signals.TestSignal:
562 if assert_on_fail:
563 raise
564 return False
565
566
567def assert_network_in_list(target, network_list):
568 """Makes sure a specified target Wi-Fi network exists in a list of Wi-Fi
569 networks.
570
571 Args:
572 target: A dict representing a Wi-Fi network.
573 E.g. {WifiEnums.SSID_KEY: "SomeNetwork"}
574 network_list: A list of dicts, each representing a Wi-Fi network.
575 """
576 match_results = match_networks(target, network_list)
577 asserts.assert_true(
578 match_results, "Target network %s, does not exist in network list %s" %
579 (target, network_list))
580
581
Ang Li73697b32015-12-03 00:41:53 +0000582def match_networks(target_params, networks):
583 """Finds the WiFi networks that match a given set of parameters in a list
584 of WiFi networks.
585
Girish Moturubc48d9f2016-11-01 13:24:14 -0700586 To be considered a match, the network should contain every key-value pair
587 of target_params
Ang Li73697b32015-12-03 00:41:53 +0000588
589 Args:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700590 target_params: A dict with 1 or more key-value pairs representing a Wi-Fi network.
591 E.g { 'SSID': 'wh_ap1_5g', 'BSSID': '30:b5:c2:33:e4:47' }
Ang Li73697b32015-12-03 00:41:53 +0000592 networks: A list of dict objects representing WiFi networks.
593
594 Returns:
595 The networks that match the target parameters.
596 """
597 results = []
Betty Zhou3caa0982017-02-22 19:26:20 -0800598 asserts.assert_true(target_params,
599 "Expected networks object 'target_params' is empty")
Ang Li73697b32015-12-03 00:41:53 +0000600 for n in networks:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700601 add_network = 1
Ang Li9a66de72016-02-08 15:26:38 -0800602 for k, v in target_params.items():
603 if k not in n:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700604 add_network = 0
605 break
Ang Li9a66de72016-02-08 15:26:38 -0800606 if n[k] != v:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700607 add_network = 0
608 break
609 if add_network:
Ang Li73697b32015-12-03 00:41:53 +0000610 results.append(n)
611 return results
612
Bindu Mahadevff295782019-02-08 16:17:48 -0800613
Roshan Pius93b519c2018-05-09 12:07:11 -0700614def wait_for_wifi_state(ad, state, assert_on_fail=True):
615 """Waits for the device to transition to the specified wifi state
616
617 Args:
618 ad: An AndroidDevice object.
619 state: Wifi state to wait for.
620 assert_on_fail: If True, error checks in this function will raise test
621 failure signals.
622
623 Returns:
624 If assert_on_fail is False, function returns True if the device transitions
625 to the specified state, False otherwise. If assert_on_fail is True, no return value.
626 """
Omar El Ayach8c017902020-10-18 10:26:57 -0700627 return _assert_on_fail_handler(_wait_for_wifi_state,
628 assert_on_fail,
629 ad,
630 state=state)
Roshan Pius93b519c2018-05-09 12:07:11 -0700631
632
633def _wait_for_wifi_state(ad, state):
634 """Toggles the state of wifi.
635
636 TestFailure signals are raised when something goes wrong.
637
638 Args:
639 ad: An AndroidDevice object.
640 state: Wifi state to wait for.
641 """
642 if state == ad.droid.wifiCheckState():
643 # Check if the state is already achieved, so we don't wait for the
644 # state change event by mistake.
645 return
646 ad.droid.wifiStartTrackingStateChange()
Omar El Ayach8c017902020-10-18 10:26:57 -0700647 fail_msg = "Device did not transition to Wi-Fi state to %s on %s." % (
648 state, ad.serial)
Roshan Pius93b519c2018-05-09 12:07:11 -0700649 try:
650 ad.ed.wait_for_event(wifi_constants.WIFI_STATE_CHANGED,
651 lambda x: x["data"]["enabled"] == state,
652 SHORT_TIMEOUT)
653 except Empty:
654 asserts.assert_equal(state, ad.droid.wifiCheckState(), fail_msg)
655 finally:
656 ad.droid.wifiStopTrackingStateChange()
Ang Li82522812016-06-02 13:57:21 -0700657
Bindu Mahadevff295782019-02-08 16:17:48 -0800658
Ang Li82522812016-06-02 13:57:21 -0700659def wifi_toggle_state(ad, new_state=None, assert_on_fail=True):
Ang Li6b557182015-11-11 17:19:17 -0800660 """Toggles the state of wifi.
Ang Li73697b32015-12-03 00:41:53 +0000661
Ang Li6b557182015-11-11 17:19:17 -0800662 Args:
663 ad: An AndroidDevice object.
664 new_state: Wifi state to set to. If None, opposite of the current state.
Ang Li82522812016-06-02 13:57:21 -0700665 assert_on_fail: If True, error checks in this function will raise test
666 failure signals.
Ang Li73697b32015-12-03 00:41:53 +0000667
Ang Li6b557182015-11-11 17:19:17 -0800668 Returns:
Ang Li82522812016-06-02 13:57:21 -0700669 If assert_on_fail is False, function returns True if the toggle was
670 successful, False otherwise. If assert_on_fail is True, no return value.
671 """
Omar El Ayach8c017902020-10-18 10:26:57 -0700672 return _assert_on_fail_handler(_wifi_toggle_state,
673 assert_on_fail,
674 ad,
675 new_state=new_state)
Ang Li82522812016-06-02 13:57:21 -0700676
677
678def _wifi_toggle_state(ad, new_state=None):
679 """Toggles the state of wifi.
680
681 TestFailure signals are raised when something goes wrong.
682
683 Args:
684 ad: An AndroidDevice object.
685 new_state: The state to set Wi-Fi to. If None, opposite of the current
686 state will be set.
Ang Li6b557182015-11-11 17:19:17 -0800687 """
Ang Li31b00782016-06-21 13:04:23 -0700688 if new_state is None:
689 new_state = not ad.droid.wifiCheckState()
Ang Lie5c85c92016-07-27 15:38:09 -0700690 elif new_state == ad.droid.wifiCheckState():
691 # Check if the new_state is already achieved, so we don't wait for the
692 # state change event by mistake.
693 return
694 ad.droid.wifiStartTrackingStateChange()
Ang Li31b00782016-06-21 13:04:23 -0700695 ad.log.info("Setting Wi-Fi state to %s.", new_state)
Roshan Pius5a027fa2018-05-04 13:59:38 -0700696 ad.ed.clear_all_events()
Ang Li31b00782016-06-21 13:04:23 -0700697 # Setting wifi state.
Ang Li6b557182015-11-11 17:19:17 -0800698 ad.droid.wifiToggleState(new_state)
Jaineel3bd9bea2019-12-13 12:44:17 -0800699 time.sleep(2)
Ang Lie2e93a22016-06-22 16:43:28 -0700700 fail_msg = "Failed to set Wi-Fi state to %s on %s." % (new_state,
701 ad.serial)
Ang Li73697b32015-12-03 00:41:53 +0000702 try:
Roshan Pius5a027fa2018-05-04 13:59:38 -0700703 ad.ed.wait_for_event(wifi_constants.WIFI_STATE_CHANGED,
704 lambda x: x["data"]["enabled"] == new_state,
705 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +0000706 except Empty:
Ang Li82522812016-06-02 13:57:21 -0700707 asserts.assert_equal(new_state, ad.droid.wifiCheckState(), fail_msg)
Ang Li6b557182015-11-11 17:19:17 -0800708 finally:
709 ad.droid.wifiStopTrackingStateChange()
710
Ang Li82522812016-06-02 13:57:21 -0700711
Ang Li6b557182015-11-11 17:19:17 -0800712def reset_wifi(ad):
Ang Li1179fa72016-06-16 09:44:06 -0700713 """Clears all saved Wi-Fi networks on a device.
714
715 This will turn Wi-Fi on.
Ang Li6b557182015-11-11 17:19:17 -0800716
717 Args:
718 ad: An AndroidDevice object.
719
Ang Li6b557182015-11-11 17:19:17 -0800720 """
Ang Li6b557182015-11-11 17:19:17 -0800721 networks = ad.droid.wifiGetConfiguredNetworks()
722 if not networks:
723 return
724 for n in networks:
725 ad.droid.wifiForgetNetwork(n['networkId'])
726 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800727 event = ad.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS,
Ang Li82522812016-06-02 13:57:21 -0700728 SHORT_TIMEOUT)
Ang Li6b557182015-11-11 17:19:17 -0800729 except Empty:
Ang Li1179fa72016-06-16 09:44:06 -0700730 logging.warning("Could not confirm the removal of network %s.", n)
731 # Check again to see if there's any network left.
Betty Zhou3caa0982017-02-22 19:26:20 -0800732 asserts.assert_true(
733 not ad.droid.wifiGetConfiguredNetworks(),
734 "Failed to remove these configured Wi-Fi networks: %s" % networks)
Ang Li82522812016-06-02 13:57:21 -0700735
Ang Li73697b32015-12-03 00:41:53 +0000736
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700737def toggle_airplane_mode_on_and_off(ad):
738 """Turn ON and OFF Airplane mode.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800739
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700740 ad: An AndroidDevice object.
741 Returns: Assert if turning on/off Airplane mode fails.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800742
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700743 """
744 ad.log.debug("Toggling Airplane mode ON.")
Omar El Ayach8c017902020-10-18 10:26:57 -0700745 asserts.assert_true(utils.force_airplane_mode(ad, True),
746 "Can not turn on airplane mode on: %s" % ad.serial)
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700747 time.sleep(DEFAULT_TIMEOUT)
748 ad.log.debug("Toggling Airplane mode OFF.")
Omar El Ayach8c017902020-10-18 10:26:57 -0700749 asserts.assert_true(utils.force_airplane_mode(ad, False),
750 "Can not turn on airplane mode on: %s" % ad.serial)
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700751 time.sleep(DEFAULT_TIMEOUT)
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800752
753
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700754def toggle_wifi_off_and_on(ad):
755 """Turn OFF and ON WiFi.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800756
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700757 ad: An AndroidDevice object.
758 Returns: Assert if turning off/on WiFi fails.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800759
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700760 """
761 ad.log.debug("Toggling wifi OFF.")
762 wifi_toggle_state(ad, False)
763 time.sleep(DEFAULT_TIMEOUT)
764 ad.log.debug("Toggling wifi ON.")
765 wifi_toggle_state(ad, True)
766 time.sleep(DEFAULT_TIMEOUT)
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800767
768
Ang Li73697b32015-12-03 00:41:53 +0000769def wifi_forget_network(ad, net_ssid):
Ang Li8e767182015-12-09 17:29:24 -0800770 """Remove configured Wifi network on an android device.
Ang Li73697b32015-12-03 00:41:53 +0000771
Ang Li8e767182015-12-09 17:29:24 -0800772 Args:
773 ad: android_device object for forget network.
774 net_ssid: ssid of network to be forget
Ang Li73697b32015-12-03 00:41:53 +0000775
Ang Li8e767182015-12-09 17:29:24 -0800776 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700777 networks = ad.droid.wifiGetConfiguredNetworks()
Ang Li8e767182015-12-09 17:29:24 -0800778 if not networks:
779 return
780 for n in networks:
781 if net_ssid in n[WifiEnums.SSID_KEY]:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700782 ad.droid.wifiForgetNetwork(n['networkId'])
Ang Li8e767182015-12-09 17:29:24 -0800783 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800784 event = ad.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS,
Betty Zhou3caa0982017-02-22 19:26:20 -0800785 SHORT_TIMEOUT)
Ang Li8e767182015-12-09 17:29:24 -0800786 except Empty:
Girish Moturu1bf82302016-11-01 13:27:00 -0700787 asserts.fail("Failed to remove network %s." % n)
Jimmy Chen8e40e152021-05-06 14:37:18 +0800788 break
Ang Li73697b32015-12-03 00:41:53 +0000789
Ang Li82522812016-06-02 13:57:21 -0700790
Ang Li73697b32015-12-03 00:41:53 +0000791def wifi_test_device_init(ad):
792 """Initializes an android device for wifi testing.
793
794 0. Make sure SL4A connection is established on the android device.
795 1. Disable location service's WiFi scan.
796 2. Turn WiFi on.
797 3. Clear all saved networks.
798 4. Set country code to US.
799 5. Enable WiFi verbose logging.
800 6. Sync device time with computer time.
801 7. Turn off cellular data.
Ang Lifee28402016-07-13 13:43:29 -0700802 8. Turn off ambient display.
Ang Li73697b32015-12-03 00:41:53 +0000803 """
Ang Lifee28402016-07-13 13:43:29 -0700804 utils.require_sl4a((ad, ))
Ang Li73697b32015-12-03 00:41:53 +0000805 ad.droid.wifiScannerToggleAlwaysAvailable(False)
806 msg = "Failed to turn off location service's scan."
Ang Li82522812016-06-02 13:57:21 -0700807 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
808 wifi_toggle_state(ad, True)
Ang Li6b557182015-11-11 17:19:17 -0800809 reset_wifi(ad)
Ang Li73697b32015-12-03 00:41:53 +0000810 ad.droid.wifiEnableVerboseLogging(1)
Ang Li8e767182015-12-09 17:29:24 -0800811 msg = "Failed to enable WiFi verbose logging."
Ang Li82522812016-06-02 13:57:21 -0700812 asserts.assert_equal(ad.droid.wifiGetVerboseLoggingLevel(), 1, msg)
Ang Li73697b32015-12-03 00:41:53 +0000813 # We don't verify the following settings since they are not critical.
Ang Lie2e93a22016-06-22 16:43:28 -0700814 # Set wpa_supplicant log level to EXCESSIVE.
Omar El Ayach8c017902020-10-18 10:26:57 -0700815 output = ad.adb.shell(
816 "wpa_cli -i wlan0 -p -g@android:wpa_wlan0 IFNAME="
817 "wlan0 log_level EXCESSIVE",
818 ignore_status=True)
Ang Lie2e93a22016-06-22 16:43:28 -0700819 ad.log.info("wpa_supplicant log change status: %s", output)
Ang Lifee28402016-07-13 13:43:29 -0700820 utils.sync_device_time(ad)
Ang Li0bf8e022016-01-04 17:34:48 -0800821 ad.droid.telephonyToggleDataConnection(False)
Roshan Pius48df08c2019-09-13 08:07:30 -0700822 set_wifi_country_code(ad, WifiEnums.CountryCode.US)
Ang Lifee28402016-07-13 13:43:29 -0700823 utils.set_ambient_display(ad, False)
Ang Li73697b32015-12-03 00:41:53 +0000824
Omar El Ayach8c017902020-10-18 10:26:57 -0700825
Roshan Pius48df08c2019-09-13 08:07:30 -0700826def set_wifi_country_code(ad, country_code):
827 """Sets the wifi country code on the device.
828
829 Args:
830 ad: An AndroidDevice object.
831 country_code: 2 letter ISO country code
codycaldwell35b87182020-01-16 14:08:01 -0800832
833 Raises:
834 An RpcException if unable to set the country code.
Roshan Pius48df08c2019-09-13 08:07:30 -0700835 """
Jaineelc5b56a62019-10-10 17:12:02 -0700836 try:
codycaldwell35b87182020-01-16 14:08:01 -0800837 ad.adb.shell("cmd wifi force-country-code enabled %s" % country_code)
Jaineel Mehtacbad5cc2020-11-19 21:38:18 +0000838 except Exception as e:
Jaineelc5b56a62019-10-10 17:12:02 -0700839 ad.droid.wifiSetCountryCode(WifiEnums.CountryCode.US)
Roshan Pius48df08c2019-09-13 08:07:30 -0700840
Ang Li82522812016-06-02 13:57:21 -0700841
Ang Li6b557182015-11-11 17:19:17 -0800842def start_wifi_connection_scan(ad):
Ang Li73697b32015-12-03 00:41:53 +0000843 """Starts a wifi connection scan and wait for results to become available.
844
845 Args:
Ang Li6b557182015-11-11 17:19:17 -0800846 ad: An AndroidDevice object.
Ang Li73697b32015-12-03 00:41:53 +0000847 """
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800848 ad.ed.clear_all_events()
Ang Li6b557182015-11-11 17:19:17 -0800849 ad.droid.wifiStartScan()
Ang Li82522812016-06-02 13:57:21 -0700850 try:
851 ad.ed.pop_event("WifiManagerScanResultsAvailable", 60)
852 except Empty:
853 asserts.fail("Wi-Fi results did not become available within 60s.")
854
Ang Li73697b32015-12-03 00:41:53 +0000855
Roshan Piuscb9bc482018-02-01 14:27:09 -0800856def start_wifi_connection_scan_and_return_status(ad):
857 """
858 Starts a wifi connection scan and wait for results to become available
859 or a scan failure to be reported.
860
861 Args:
862 ad: An AndroidDevice object.
863 Returns:
864 True: if scan succeeded & results are available
865 False: if scan failed
866 """
867 ad.ed.clear_all_events()
868 ad.droid.wifiStartScan()
869 try:
Omar El Ayach8c017902020-10-18 10:26:57 -0700870 events = ad.ed.pop_events("WifiManagerScan(ResultsAvailable|Failure)",
871 60)
Roshan Piuscb9bc482018-02-01 14:27:09 -0800872 except Empty:
873 asserts.fail(
874 "Wi-Fi scan results/failure did not become available within 60s.")
875 # If there are multiple matches, we check for atleast one success.
876 for event in events:
877 if event["name"] == "WifiManagerScanResultsAvailable":
878 return True
879 elif event["name"] == "WifiManagerScanFailure":
880 ad.log.debug("Scan failure received")
881 return False
882
883
Omar El Ayach8c017902020-10-18 10:26:57 -0700884def start_wifi_connection_scan_and_check_for_network(ad,
885 network_ssid,
Roshan Piuscb9bc482018-02-01 14:27:09 -0800886 max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800887 """
888 Start connectivity scans & checks if the |network_ssid| is seen in
889 scan results. The method performs a max of |max_tries| connectivity scans
890 to find the network.
891
892 Args:
893 ad: An AndroidDevice object.
894 network_ssid: SSID of the network we are looking for.
895 max_tries: Number of scans to try.
896 Returns:
897 True: if network_ssid is found in scan results.
898 False: if network_ssid is not found in scan results.
899 """
900 for num_tries in range(max_tries):
Roshan Piuscb9bc482018-02-01 14:27:09 -0800901 if start_wifi_connection_scan_and_return_status(ad):
902 scan_results = ad.droid.wifiGetScanResults()
Omar El Ayach8c017902020-10-18 10:26:57 -0700903 match_results = match_networks({WifiEnums.SSID_KEY: network_ssid},
904 scan_results)
Roshan Piuscb9bc482018-02-01 14:27:09 -0800905 if len(match_results) > 0:
906 return True
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800907 return False
908
909
Omar El Ayach8c017902020-10-18 10:26:57 -0700910def start_wifi_connection_scan_and_ensure_network_found(
911 ad, network_ssid, max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800912 """
913 Start connectivity scans & ensure the |network_ssid| is seen in
914 scan results. The method performs a max of |max_tries| connectivity scans
915 to find the network.
916 This method asserts on failure!
917
918 Args:
919 ad: An AndroidDevice object.
920 network_ssid: SSID of the network we are looking for.
921 max_tries: Number of scans to try.
922 """
923 ad.log.info("Starting scans to ensure %s is present", network_ssid)
924 assert_msg = "Failed to find " + network_ssid + " in scan results" \
925 " after " + str(max_tries) + " tries"
Omar El Ayach8c017902020-10-18 10:26:57 -0700926 asserts.assert_true(
927 start_wifi_connection_scan_and_check_for_network(
928 ad, network_ssid, max_tries), assert_msg)
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800929
930
Omar El Ayach8c017902020-10-18 10:26:57 -0700931def start_wifi_connection_scan_and_ensure_network_not_found(
932 ad, network_ssid, max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800933 """
934 Start connectivity scans & ensure the |network_ssid| is not seen in
935 scan results. The method performs a max of |max_tries| connectivity scans
936 to find the network.
937 This method asserts on failure!
938
939 Args:
940 ad: An AndroidDevice object.
941 network_ssid: SSID of the network we are looking for.
942 max_tries: Number of scans to try.
943 """
944 ad.log.info("Starting scans to ensure %s is not present", network_ssid)
945 assert_msg = "Found " + network_ssid + " in scan results" \
946 " after " + str(max_tries) + " tries"
Omar El Ayach8c017902020-10-18 10:26:57 -0700947 asserts.assert_false(
948 start_wifi_connection_scan_and_check_for_network(
949 ad, network_ssid, max_tries), assert_msg)
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800950
951
Ang Li73697b32015-12-03 00:41:53 +0000952def start_wifi_background_scan(ad, scan_setting):
953 """Starts wifi background scan.
954
955 Args:
956 ad: android_device object to initiate connection on.
957 scan_setting: A dict representing the settings of the scan.
958
959 Returns:
960 If scan was started successfully, event data of success event is returned.
961 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700962 idx = ad.droid.wifiScannerStartBackgroundScan(scan_setting)
963 event = ad.ed.pop_event("WifiScannerScan{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -0800964 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +0000965 return event['data']
966
Ang Li82522812016-06-02 13:57:21 -0700967
Girish Moturu38b993c2021-03-25 13:03:50 -0700968def start_wifi_tethering(ad, ssid, password, band=None, hidden=None,
969 security=None):
Ang Li73697b32015-12-03 00:41:53 +0000970 """Starts wifi tethering on an android_device.
971
972 Args:
973 ad: android_device to start wifi tethering on.
974 ssid: The SSID the soft AP should broadcast.
975 password: The password the soft AP should use.
976 band: The band the soft AP should be set on. It should be either
977 WifiEnums.WIFI_CONFIG_APBAND_2G or WifiEnums.WIFI_CONFIG_APBAND_5G.
Roshan Piusce821342018-01-10 11:03:04 -0800978 hidden: boolean to indicate if the AP needs to be hidden or not.
Girish Moturu38b993c2021-03-25 13:03:50 -0700979 security: security type of softap.
Ang Li73697b32015-12-03 00:41:53 +0000980
981 Returns:
Girish Moturu3581d612016-11-02 15:08:51 -0700982 No return value. Error checks in this function will raise test failure signals
Ang Li73697b32015-12-03 00:41:53 +0000983 """
Ang Li82522812016-06-02 13:57:21 -0700984 config = {WifiEnums.SSID_KEY: ssid}
Ang Li73697b32015-12-03 00:41:53 +0000985 if password:
986 config[WifiEnums.PWD_KEY] = password
987 if band:
lesl6d30a172020-03-05 15:05:22 +0800988 config[WifiEnums.AP_BAND_KEY] = band
Roshan Piusce821342018-01-10 11:03:04 -0800989 if hidden:
Omar El Ayach8c017902020-10-18 10:26:57 -0700990 config[WifiEnums.HIDDEN_KEY] = hidden
Girish Moturu38b993c2021-03-25 13:03:50 -0700991 if security:
992 config[WifiEnums.SECURITY] = security
Omar El Ayach8c017902020-10-18 10:26:57 -0700993 asserts.assert_true(ad.droid.wifiSetWifiApConfiguration(config),
994 "Failed to update WifiAp Configuration")
Girish Moturu40d7dc22016-11-02 12:14:56 -0700995 ad.droid.wifiStartTrackingTetherStateChange()
996 ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
Rebecca Silbersteina2889852016-08-11 00:48:53 -0700997 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700998 ad.ed.pop_event("ConnectivityManagerOnTetheringStarted")
999 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -08001000 lambda x: x["data"]["ACTIVE_TETHER"], 30)
Ang Li76216d12016-09-20 14:51:57 -07001001 ad.log.debug("Tethering started successfully.")
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001002 except Empty:
1003 msg = "Failed to receive confirmation of wifi tethering starting"
1004 asserts.fail(msg)
1005 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001006 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001007
Bindu Mahadevff295782019-02-08 16:17:48 -08001008
Omar El Ayach8c017902020-10-18 10:26:57 -07001009def save_wifi_soft_ap_config(ad,
1010 wifi_config,
1011 band=None,
1012 hidden=None,
1013 security=None,
1014 password=None,
1015 channel=None,
1016 max_clients=None,
lesl6d30a172020-03-05 15:05:22 +08001017 shutdown_timeout_enable=None,
1018 shutdown_timeout_millis=None,
1019 client_control_enable=None,
Omar El Ayach8c017902020-10-18 10:26:57 -07001020 allowedList=None,
lesl67124362021-05-04 19:33:14 +08001021 blockedList=None,
1022 bands=None,
1023 channel_frequencys=None,
1024 mac_randomization_setting=None,
1025 bridged_opportunistic_shutdown_enabled=None,
1026 ieee80211ax_enabled=None):
lesl6d30a172020-03-05 15:05:22 +08001027 """ Save a soft ap configuration and verified
1028 Args:
1029 ad: android_device to set soft ap configuration.
1030 wifi_config: a soft ap configuration object, at least include SSID.
1031 band: specifies the band for the soft ap.
1032 hidden: specifies the soft ap need to broadcast its SSID or not.
1033 security: specifies the security type for the soft ap.
1034 password: specifies the password for the soft ap.
1035 channel: specifies the channel for the soft ap.
1036 max_clients: specifies the maximum connected client number.
1037 shutdown_timeout_enable: specifies the auto shut down enable or not.
1038 shutdown_timeout_millis: specifies the shut down timeout value.
1039 client_control_enable: specifies the client control enable or not.
1040 allowedList: specifies allowed clients list.
1041 blockedList: specifies blocked clients list.
lesl67124362021-05-04 19:33:14 +08001042 bands: specifies the band list for the soft ap.
1043 channel_frequencys: specifies the channel frequency list for soft ap.
1044 mac_randomization_setting: specifies the mac randomization setting.
1045 bridged_opportunistic_shutdown_enabled: specifies the opportunistic
1046 shutdown enable or not.
1047 ieee80211ax_enabled: specifies the ieee80211ax enable or not.
lesl6d30a172020-03-05 15:05:22 +08001048 """
1049 if security and password:
Omar El Ayach8c017902020-10-18 10:26:57 -07001050 wifi_config[WifiEnums.SECURITY] = security
1051 wifi_config[WifiEnums.PWD_KEY] = password
lesl67124362021-05-04 19:33:14 +08001052 if hidden is not None:
Girish Moturu528b5442018-06-07 10:48:14 -07001053 wifi_config[WifiEnums.HIDDEN_KEY] = hidden
lesl67124362021-05-04 19:33:14 +08001054 if max_clients is not None:
lesl6d30a172020-03-05 15:05:22 +08001055 wifi_config[WifiEnums.AP_MAXCLIENTS_KEY] = max_clients
lesl67124362021-05-04 19:33:14 +08001056 if shutdown_timeout_enable is not None:
lesl6d30a172020-03-05 15:05:22 +08001057 wifi_config[
1058 WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] = shutdown_timeout_enable
lesl67124362021-05-04 19:33:14 +08001059 if shutdown_timeout_millis is not None:
Omar El Ayach8c017902020-10-18 10:26:57 -07001060 wifi_config[WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] = shutdown_timeout_millis
lesl67124362021-05-04 19:33:14 +08001061 if client_control_enable is not None:
lesl6d30a172020-03-05 15:05:22 +08001062 wifi_config[WifiEnums.AP_CLIENTCONTROL_KEY] = client_control_enable
lesl67124362021-05-04 19:33:14 +08001063 if allowedList is not None:
lesl6d30a172020-03-05 15:05:22 +08001064 wifi_config[WifiEnums.AP_ALLOWEDLIST_KEY] = allowedList
lesl67124362021-05-04 19:33:14 +08001065 if blockedList is not None:
lesl6d30a172020-03-05 15:05:22 +08001066 wifi_config[WifiEnums.AP_BLOCKEDLIST_KEY] = blockedList
lesl67124362021-05-04 19:33:14 +08001067 if mac_randomization_setting is not None:
1068 wifi_config[WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY
1069 ] = mac_randomization_setting
1070 if bridged_opportunistic_shutdown_enabled is not None:
1071 wifi_config[WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY
1072 ] = bridged_opportunistic_shutdown_enabled
1073 if ieee80211ax_enabled is not None:
1074 wifi_config[WifiEnums.AP_IEEE80211AX_ENABLED_KEY]= ieee80211ax_enabled
1075 if channel_frequencys is not None:
1076 wifi_config[WifiEnums.AP_CHANNEL_FREQUENCYS_KEY] = channel_frequencys
1077 elif bands is not None:
1078 wifi_config[WifiEnums.AP_BANDS_KEY] = bands
1079 elif band is not None:
1080 if channel is not None:
1081 wifi_config[WifiEnums.AP_BAND_KEY] = band
1082 wifi_config[WifiEnums.AP_CHANNEL_KEY] = channel
1083 else:
1084 wifi_config[WifiEnums.AP_BAND_KEY] = band
lesl6d30a172020-03-05 15:05:22 +08001085
1086 if WifiEnums.AP_CHANNEL_KEY in wifi_config and wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001087 WifiEnums.AP_CHANNEL_KEY] == 0:
lesl6d30a172020-03-05 15:05:22 +08001088 del wifi_config[WifiEnums.AP_CHANNEL_KEY]
1089
1090 if WifiEnums.SECURITY in wifi_config and wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001091 WifiEnums.SECURITY] == WifiEnums.SoftApSecurityType.OPEN:
lesl6d30a172020-03-05 15:05:22 +08001092 del wifi_config[WifiEnums.SECURITY]
1093 del wifi_config[WifiEnums.PWD_KEY]
1094
Girish Moturu528b5442018-06-07 10:48:14 -07001095 asserts.assert_true(ad.droid.wifiSetWifiApConfiguration(wifi_config),
1096 "Failed to set WifiAp Configuration")
1097
1098 wifi_ap = ad.droid.wifiGetApConfiguration()
1099 asserts.assert_true(
1100 wifi_ap[WifiEnums.SSID_KEY] == wifi_config[WifiEnums.SSID_KEY],
lesl6d30a172020-03-05 15:05:22 +08001101 "Hotspot SSID doesn't match")
1102 if WifiEnums.SECURITY in wifi_config:
1103 asserts.assert_true(
1104 wifi_ap[WifiEnums.SECURITY] == wifi_config[WifiEnums.SECURITY],
1105 "Hotspot Security doesn't match")
1106 if WifiEnums.PWD_KEY in wifi_config:
1107 asserts.assert_true(
1108 wifi_ap[WifiEnums.PWD_KEY] == wifi_config[WifiEnums.PWD_KEY],
1109 "Hotspot Password doesn't match")
Girish Moturu528b5442018-06-07 10:48:14 -07001110
lesl6d30a172020-03-05 15:05:22 +08001111 if WifiEnums.HIDDEN_KEY in wifi_config:
1112 asserts.assert_true(
1113 wifi_ap[WifiEnums.HIDDEN_KEY] == wifi_config[WifiEnums.HIDDEN_KEY],
1114 "Hotspot hidden setting doesn't match")
1115
lesl6d30a172020-03-05 15:05:22 +08001116 if WifiEnums.AP_CHANNEL_KEY in wifi_config:
1117 asserts.assert_true(
1118 wifi_ap[WifiEnums.AP_CHANNEL_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001119 WifiEnums.AP_CHANNEL_KEY], "Hotspot Channel doesn't match")
lesl6d30a172020-03-05 15:05:22 +08001120 if WifiEnums.AP_MAXCLIENTS_KEY in wifi_config:
1121 asserts.assert_true(
1122 wifi_ap[WifiEnums.AP_MAXCLIENTS_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001123 WifiEnums.AP_MAXCLIENTS_KEY],
1124 "Hotspot Max Clients doesn't match")
lesl6d30a172020-03-05 15:05:22 +08001125 if WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY in wifi_config:
1126 asserts.assert_true(
1127 wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001128 WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY],
lesl6d30a172020-03-05 15:05:22 +08001129 "Hotspot ShutDown feature flag doesn't match")
1130 if WifiEnums.AP_SHUTDOWNTIMEOUT_KEY in wifi_config:
1131 asserts.assert_true(
1132 wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001133 WifiEnums.AP_SHUTDOWNTIMEOUT_KEY],
lesl6d30a172020-03-05 15:05:22 +08001134 "Hotspot ShutDown timeout setting doesn't match")
1135 if WifiEnums.AP_CLIENTCONTROL_KEY in wifi_config:
1136 asserts.assert_true(
1137 wifi_ap[WifiEnums.AP_CLIENTCONTROL_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001138 WifiEnums.AP_CLIENTCONTROL_KEY],
lesl6d30a172020-03-05 15:05:22 +08001139 "Hotspot Client control flag doesn't match")
1140 if WifiEnums.AP_ALLOWEDLIST_KEY in wifi_config:
1141 asserts.assert_true(
1142 wifi_ap[WifiEnums.AP_ALLOWEDLIST_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001143 WifiEnums.AP_ALLOWEDLIST_KEY],
lesl6d30a172020-03-05 15:05:22 +08001144 "Hotspot Allowed List doesn't match")
1145 if WifiEnums.AP_BLOCKEDLIST_KEY in wifi_config:
1146 asserts.assert_true(
1147 wifi_ap[WifiEnums.AP_BLOCKEDLIST_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001148 WifiEnums.AP_BLOCKEDLIST_KEY],
lesl6d30a172020-03-05 15:05:22 +08001149 "Hotspot Blocked List doesn't match")
Bindu Mahadevff295782019-02-08 16:17:48 -08001150
lesl67124362021-05-04 19:33:14 +08001151 if WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY in wifi_config:
1152 asserts.assert_true(
1153 wifi_ap[WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY] == wifi_config[
1154 WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY],
1155 "Hotspot Mac randomization setting doesn't match")
1156
1157 if WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY in wifi_config:
1158 asserts.assert_true(
1159 wifi_ap[WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY] == wifi_config[
1160 WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY],
1161 "Hotspot bridged shutdown enable setting doesn't match")
1162
1163 if WifiEnums.AP_IEEE80211AX_ENABLED_KEY in wifi_config:
1164 asserts.assert_true(
1165 wifi_ap[WifiEnums.AP_IEEE80211AX_ENABLED_KEY] == wifi_config[
1166 WifiEnums.AP_IEEE80211AX_ENABLED_KEY],
1167 "Hotspot 80211 AX enable setting doesn't match")
1168
1169 if WifiEnums.AP_CHANNEL_FREQUENCYS_KEY in wifi_config:
1170 asserts.assert_true(
1171 wifi_ap[WifiEnums.AP_CHANNEL_FREQUENCYS_KEY] == wifi_config[
1172 WifiEnums.AP_CHANNEL_FREQUENCYS_KEY],
1173 "Hotspot channels setting doesn't match")
Omar El Ayach8c017902020-10-18 10:26:57 -07001174
Girish Moturu528b5442018-06-07 10:48:14 -07001175def start_wifi_tethering_saved_config(ad):
1176 """ Turn on wifi hotspot with a config that is already saved """
1177 ad.droid.wifiStartTrackingTetherStateChange()
1178 ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
1179 try:
1180 ad.ed.pop_event("ConnectivityManagerOnTetheringStarted")
1181 ad.ed.wait_for_event("TetherStateChanged",
1182 lambda x: x["data"]["ACTIVE_TETHER"], 30)
1183 except:
1184 asserts.fail("Didn't receive wifi tethering starting confirmation")
1185 finally:
1186 ad.droid.wifiStopTrackingTetherStateChange()
Betty Zhou3caa0982017-02-22 19:26:20 -08001187
Bindu Mahadevff295782019-02-08 16:17:48 -08001188
Ang Li73697b32015-12-03 00:41:53 +00001189def stop_wifi_tethering(ad):
1190 """Stops wifi tethering on an android_device.
Ang Li73697b32015-12-03 00:41:53 +00001191 Args:
1192 ad: android_device to stop wifi tethering on.
1193 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001194 ad.droid.wifiStartTrackingTetherStateChange()
1195 ad.droid.connectivityStopTethering(tel_defines.TETHERING_WIFI)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001196 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001197 ad.ed.pop_event("WifiManagerApDisabled", 30)
1198 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -08001199 lambda x: not x["data"]["ACTIVE_TETHER"], 30)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001200 except Empty:
1201 msg = "Failed to receive confirmation of wifi tethering stopping"
1202 asserts.fail(msg)
1203 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001204 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li82522812016-06-02 13:57:21 -07001205
Ang Li76216d12016-09-20 14:51:57 -07001206
Roshan Pius58916a32016-06-16 16:26:44 -07001207def toggle_wifi_and_wait_for_reconnection(ad,
1208 network,
1209 num_of_tries=1,
1210 assert_on_fail=True):
1211 """Toggle wifi state and then wait for Android device to reconnect to
1212 the provided wifi network.
1213
1214 This expects the device to be already connected to the provided network.
1215
1216 Logic steps are
1217 1. Ensure that we're connected to the network.
1218 2. Turn wifi off.
1219 3. Wait for 10 seconds.
1220 4. Turn wifi on.
1221 5. Wait for the "connected" event, then confirm the connected ssid is the
1222 one requested.
1223
1224 Args:
1225 ad: android_device object to initiate connection on.
1226 network: A dictionary representing the network to await connection. The
1227 dictionary must have the key "SSID".
1228 num_of_tries: An integer that is the number of times to try before
1229 delaring failure. Default is 1.
1230 assert_on_fail: If True, error checks in this function will raise test
1231 failure signals.
1232
1233 Returns:
1234 If assert_on_fail is False, function returns True if the toggle was
1235 successful, False otherwise. If assert_on_fail is True, no return value.
1236 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001237 return _assert_on_fail_handler(_toggle_wifi_and_wait_for_reconnection,
1238 assert_on_fail,
1239 ad,
1240 network,
1241 num_of_tries=num_of_tries)
Roshan Pius58916a32016-06-16 16:26:44 -07001242
1243
Girish Moturu5d9f4202019-12-03 15:29:21 -08001244def _toggle_wifi_and_wait_for_reconnection(ad, network, num_of_tries=3):
Roshan Pius58916a32016-06-16 16:26:44 -07001245 """Toggle wifi state and then wait for Android device to reconnect to
1246 the provided wifi network.
1247
1248 This expects the device to be already connected to the provided network.
1249
1250 Logic steps are
1251 1. Ensure that we're connected to the network.
1252 2. Turn wifi off.
1253 3. Wait for 10 seconds.
1254 4. Turn wifi on.
1255 5. Wait for the "connected" event, then confirm the connected ssid is the
1256 one requested.
1257
1258 This will directly fail a test if anything goes wrong.
1259
1260 Args:
1261 ad: android_device object to initiate connection on.
1262 network: A dictionary representing the network to await connection. The
1263 dictionary must have the key "SSID".
1264 num_of_tries: An integer that is the number of times to try before
1265 delaring failure. Default is 1.
1266 """
Roshan Pius58916a32016-06-16 16:26:44 -07001267 expected_ssid = network[WifiEnums.SSID_KEY]
1268 # First ensure that we're already connected to the provided network.
1269 verify_con = {WifiEnums.SSID_KEY: expected_ssid}
1270 verify_wifi_connection_info(ad, verify_con)
1271 # Now toggle wifi state and wait for the connection event.
1272 wifi_toggle_state(ad, False)
1273 time.sleep(10)
1274 wifi_toggle_state(ad, True)
1275 ad.droid.wifiStartTrackingStateChange()
1276 try:
1277 connect_result = None
1278 for i in range(num_of_tries):
1279 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -08001280 connect_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
Roshan Pius58916a32016-06-16 16:26:44 -07001281 30)
1282 break
1283 except Empty:
1284 pass
Omar El Ayach8c017902020-10-18 10:26:57 -07001285 asserts.assert_true(
1286 connect_result, "Failed to connect to Wi-Fi network %s on %s" %
1287 (network, ad.serial))
Betty Zhou3caa0982017-02-22 19:26:20 -08001288 logging.debug("Connection result on %s: %s.", ad.serial,
1289 connect_result)
Roshan Pius58916a32016-06-16 16:26:44 -07001290 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001291 asserts.assert_equal(
1292 actual_ssid, expected_ssid, "Connected to the wrong network on %s."
1293 "Expected %s, but got %s." %
1294 (ad.serial, expected_ssid, actual_ssid))
Betty Zhou3caa0982017-02-22 19:26:20 -08001295 logging.info("Connected to Wi-Fi network %s on %s", actual_ssid,
1296 ad.serial)
Roshan Pius58916a32016-06-16 16:26:44 -07001297 finally:
1298 ad.droid.wifiStopTrackingStateChange()
1299
1300
Omar El Ayach8c017902020-10-18 10:26:57 -07001301def wait_for_connect(ad,
1302 expected_ssid=None,
1303 expected_id=None,
1304 tries=2,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001305 assert_on_fail=True):
Roshan Piusd1204442018-11-12 12:20:39 -08001306 """Wait for a connect event.
1307
1308 This will directly fail a test if anything goes wrong.
1309
1310 Args:
1311 ad: An Android device object.
1312 expected_ssid: SSID of the network to connect to.
1313 expected_id: Network Id of the network to connect to.
1314 tries: An integer that is the number of times to try before failing.
1315 assert_on_fail: If True, error checks in this function will raise test
1316 failure signals.
1317
1318 Returns:
1319 Returns a value only if assert_on_fail is false.
1320 Returns True if the connection was successful, False otherwise.
1321 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001322 return _assert_on_fail_handler(_wait_for_connect, assert_on_fail, ad,
1323 expected_ssid, expected_id, tries)
Roshan Piusd1204442018-11-12 12:20:39 -08001324
1325
Oscar Shucb9af9b2019-05-02 20:01:49 +00001326def _wait_for_connect(ad, expected_ssid=None, expected_id=None, tries=2):
Roshan Piusd1204442018-11-12 12:20:39 -08001327 """Wait for a connect event.
1328
1329 Args:
1330 ad: An Android device object.
1331 expected_ssid: SSID of the network to connect to.
1332 expected_id: Network Id of the network to connect to.
1333 tries: An integer that is the number of times to try before failing.
1334 """
1335 ad.droid.wifiStartTrackingStateChange()
1336 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001337 connect_result = _wait_for_connect_event(ad,
1338 ssid=expected_ssid,
1339 id=expected_id,
1340 tries=tries)
1341 asserts.assert_true(
1342 connect_result,
1343 "Failed to connect to Wi-Fi network %s" % expected_ssid)
Roshan Piusd1204442018-11-12 12:20:39 -08001344 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
1345 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1346 if expected_ssid:
1347 asserts.assert_equal(actual_ssid, expected_ssid,
1348 "Connected to the wrong network")
1349 actual_id = connect_result['data'][WifiEnums.NETID_KEY]
1350 if expected_id:
1351 asserts.assert_equal(actual_id, expected_id,
1352 "Connected to the wrong network")
1353 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
1354 except Empty:
1355 asserts.fail("Failed to start connection process to %s" %
1356 expected_ssid)
1357 except Exception as error:
1358 ad.log.error("Failed to connect to %s with error %s", expected_ssid,
1359 error)
1360 raise signals.TestFailure("Failed to connect to %s network" %
1361 expected_ssid)
1362 finally:
1363 ad.droid.wifiStopTrackingStateChange()
1364
1365
Oscar Shucb9af9b2019-05-02 20:01:49 +00001366def _wait_for_connect_event(ad, ssid=None, id=None, tries=1):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001367 """Wait for a connect event on queue and pop when available.
1368
1369 Args:
1370 ad: An Android device object.
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001371 ssid: SSID of the network to connect to.
1372 id: Network Id of the network to connect to.
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001373 tries: An integer that is the number of times to try before failing.
1374
1375 Returns:
1376 A dict with details of the connection data, which looks like this:
1377 {
1378 'time': 1485460337798,
1379 'name': 'WifiNetworkConnected',
1380 'data': {
1381 'rssi': -27,
1382 'is_24ghz': True,
1383 'mac_address': '02:00:00:00:00:00',
1384 'network_id': 1,
1385 'BSSID': '30:b5:c2:33:d3:fc',
1386 'ip_address': 117483712,
1387 'link_speed': 54,
1388 'supplicant_state': 'completed',
1389 'hidden_ssid': False,
1390 'SSID': 'wh_ap1_2g',
1391 'is_5ghz': False}
1392 }
1393
1394 """
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001395 conn_result = None
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001396
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001397 # If ssid and network id is None, just wait for any connect event.
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001398 if id is None and ssid is None:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001399 for i in range(tries):
1400 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001401 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
1402 30)
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001403 break
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001404 except Empty:
1405 pass
1406 else:
Omar El Ayach8c017902020-10-18 10:26:57 -07001407 # If ssid or network id is specified, wait for specific connect event.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001408 for i in range(tries):
1409 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001410 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
1411 30)
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001412 if id and conn_result['data'][WifiEnums.NETID_KEY] == id:
1413 break
1414 elif ssid and conn_result['data'][WifiEnums.SSID_KEY] == ssid:
1415 break
1416 except Empty:
1417 pass
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001418
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001419 return conn_result
1420
Bindu Mahadevff295782019-02-08 16:17:48 -08001421
Roshan Piusffc29912019-01-18 13:39:49 -08001422def wait_for_disconnect(ad, timeout=10):
1423 """Wait for a disconnect event within the specified timeout.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001424
1425 Args:
1426 ad: Android device object.
Roshan Piusffc29912019-01-18 13:39:49 -08001427 timeout: Timeout in seconds.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001428
1429 """
1430 try:
1431 ad.droid.wifiStartTrackingStateChange()
Roshan Piusffc29912019-01-18 13:39:49 -08001432 event = ad.ed.pop_event("WifiNetworkDisconnected", timeout)
Roshan Piusbf7e3982018-02-15 12:37:41 -08001433 except Empty:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001434 raise signals.TestFailure("Device did not disconnect from the network")
Roshan Piusffc29912019-01-18 13:39:49 -08001435 finally:
1436 ad.droid.wifiStopTrackingStateChange()
1437
1438
1439def ensure_no_disconnect(ad, duration=10):
1440 """Ensure that there is no disconnect for the specified duration.
1441
1442 Args:
1443 ad: Android device object.
1444 duration: Duration in seconds.
1445
1446 """
1447 try:
1448 ad.droid.wifiStartTrackingStateChange()
1449 event = ad.ed.pop_event("WifiNetworkDisconnected", duration)
1450 raise signals.TestFailure("Device disconnected from the network")
1451 except Empty:
1452 pass
1453 finally:
1454 ad.droid.wifiStopTrackingStateChange()
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001455
1456
Omar El Ayach8c017902020-10-18 10:26:57 -07001457def connect_to_wifi_network(ad,
1458 network,
1459 assert_on_fail=True,
1460 check_connectivity=True,
1461 hidden=False):
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001462 """Connection logic for open and psk wifi networks.
1463
1464 Args:
Jong Wook Kim92356922018-02-06 18:32:49 -08001465 ad: AndroidDevice to use for connection
1466 network: network info of the network to connect to
1467 assert_on_fail: If true, errors from wifi_connect will raise
1468 test failure signals.
Joe Brennan48c3f692019-04-11 08:30:16 -07001469 hidden: Is the Wifi network hidden.
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001470 """
Joe Brennan48c3f692019-04-11 08:30:16 -07001471 if hidden:
1472 start_wifi_connection_scan_and_ensure_network_not_found(
1473 ad, network[WifiEnums.SSID_KEY])
1474 else:
1475 start_wifi_connection_scan_and_ensure_network_found(
1476 ad, network[WifiEnums.SSID_KEY])
Jong Wook Kim92356922018-02-06 18:32:49 -08001477 wifi_connect(ad,
1478 network,
1479 num_of_tries=3,
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001480 assert_on_fail=assert_on_fail,
1481 check_connectivity=check_connectivity)
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001482
1483
1484def connect_to_wifi_network_with_id(ad, network_id, network_ssid):
1485 """Connect to the given network using network id and verify SSID.
1486
1487 Args:
1488 network_id: int Network Id of the network.
1489 network_ssid: string SSID of the network.
1490
1491 Returns: True if connect using network id was successful;
1492 False otherwise.
1493
1494 """
Jong Wook Kim92356922018-02-06 18:32:49 -08001495 start_wifi_connection_scan_and_ensure_network_found(ad, network_ssid)
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001496 wifi_connect_by_id(ad, network_id)
1497 connect_data = ad.droid.wifiGetConnectionInfo()
1498 connect_ssid = connect_data[WifiEnums.SSID_KEY]
1499 ad.log.debug("Expected SSID = %s Connected SSID = %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001500 (network_ssid, connect_ssid))
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001501 if connect_ssid != network_ssid:
1502 return False
1503 return True
1504
1505
Omar El Ayach8c017902020-10-18 10:26:57 -07001506def wifi_connect(ad,
1507 network,
1508 num_of_tries=1,
1509 assert_on_fail=True,
1510 check_connectivity=True):
Ang Li99d8c6d2015-12-09 15:56:13 -08001511 """Connect an Android device to a wifi network.
Ang Li73697b32015-12-03 00:41:53 +00001512
1513 Initiate connection to a wifi network, wait for the "connected" event, then
Ang Li99d8c6d2015-12-09 15:56:13 -08001514 confirm the connected ssid is the one requested.
Ang Li73697b32015-12-03 00:41:53 +00001515
Ang Li82522812016-06-02 13:57:21 -07001516 This will directly fail a test if anything goes wrong.
1517
Ang Li73697b32015-12-03 00:41:53 +00001518 Args:
1519 ad: android_device object to initiate connection on.
Ang Li99d8c6d2015-12-09 15:56:13 -08001520 network: A dictionary representing the network to connect to. The
Ang Li82522812016-06-02 13:57:21 -07001521 dictionary must have the key "SSID".
1522 num_of_tries: An integer that is the number of times to try before
1523 delaring failure. Default is 1.
1524 assert_on_fail: If True, error checks in this function will raise test
1525 failure signals.
1526
1527 Returns:
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001528 Returns a value only if assert_on_fail is false.
1529 Returns True if the connection was successful, False otherwise.
Ang Li73697b32015-12-03 00:41:53 +00001530 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001531 return _assert_on_fail_handler(_wifi_connect,
1532 assert_on_fail,
1533 ad,
1534 network,
1535 num_of_tries=num_of_tries,
1536 check_connectivity=check_connectivity)
Ang Li82522812016-06-02 13:57:21 -07001537
1538
Oscar Shucb9af9b2019-05-02 20:01:49 +00001539def _wifi_connect(ad, network, num_of_tries=1, check_connectivity=True):
Ang Li82522812016-06-02 13:57:21 -07001540 """Connect an Android device to a wifi network.
1541
1542 Initiate connection to a wifi network, wait for the "connected" event, then
1543 confirm the connected ssid is the one requested.
1544
1545 This will directly fail a test if anything goes wrong.
1546
1547 Args:
1548 ad: android_device object to initiate connection on.
1549 network: A dictionary representing the network to connect to. The
1550 dictionary must have the key "SSID".
1551 num_of_tries: An integer that is the number of times to try before
1552 delaring failure. Default is 1.
1553 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001554 asserts.assert_true(
1555 WifiEnums.SSID_KEY in network,
1556 "Key '%s' must be present in network definition." % WifiEnums.SSID_KEY)
Ang Li99d8c6d2015-12-09 15:56:13 -08001557 ad.droid.wifiStartTrackingStateChange()
Betty Zhoud35dab82016-12-06 15:24:23 -08001558 expected_ssid = network[WifiEnums.SSID_KEY]
Bindu Mahadev50374df2017-01-04 11:03:32 -08001559 ad.droid.wifiConnectByConfig(network)
1560 ad.log.info("Starting connection process to %s", expected_ssid)
Ang Li73697b32015-12-03 00:41:53 +00001561 try:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001562 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_CONFIG_SUCCESS, 30)
Omar El Ayach8c017902020-10-18 10:26:57 -07001563 connect_result = _wait_for_connect_event(ad,
1564 ssid=expected_ssid,
1565 tries=num_of_tries)
1566 asserts.assert_true(
1567 connect_result, "Failed to connect to Wi-Fi network %s on %s" %
1568 (network, ad.serial))
Ang Li31b00782016-06-21 13:04:23 -07001569 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
Ang Li99d8c6d2015-12-09 15:56:13 -08001570 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001571 asserts.assert_equal(
1572 actual_ssid, expected_ssid,
1573 "Connected to the wrong network on %s." % ad.serial)
Ang Li31b00782016-06-21 13:04:23 -07001574 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
Bindu Mahadev50374df2017-01-04 11:03:32 -08001575
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001576 if check_connectivity:
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08001577 internet = validate_connection(ad, DEFAULT_PING_ADDR)
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001578 if not internet:
Omar El Ayach8c017902020-10-18 10:26:57 -07001579 raise signals.TestFailure(
1580 "Failed to connect to internet on %s" % expected_ssid)
Bindu Mahadev50374df2017-01-04 11:03:32 -08001581 except Empty:
1582 asserts.fail("Failed to start connection process to %s on %s" %
1583 (network, ad.serial))
Bindu Mahadev4e710362016-11-17 16:17:11 -08001584 except Exception as error:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001585 ad.log.error("Failed to connect to %s with error %s", expected_ssid,
1586 error)
1587 raise signals.TestFailure("Failed to connect to %s network" % network)
1588
Ang Li73697b32015-12-03 00:41:53 +00001589 finally:
Ang Li99d8c6d2015-12-09 15:56:13 -08001590 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001591
Bindu Mahadev50374df2017-01-04 11:03:32 -08001592
Oscar Shucb9af9b2019-05-02 20:01:49 +00001593def wifi_connect_by_id(ad, network_id, num_of_tries=3, assert_on_fail=True):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001594 """Connect an Android device to a wifi network using network Id.
1595
1596 Start connection to the wifi network, with the given network Id, wait for
1597 the "connected" event, then verify the connected network is the one requested.
1598
1599 This will directly fail a test if anything goes wrong.
1600
1601 Args:
1602 ad: android_device object to initiate connection on.
1603 network_id: Integer specifying the network id of the network.
1604 num_of_tries: An integer that is the number of times to try before
1605 delaring failure. Default is 1.
1606 assert_on_fail: If True, error checks in this function will raise test
1607 failure signals.
1608
1609 Returns:
1610 Returns a value only if assert_on_fail is false.
1611 Returns True if the connection was successful, False otherwise.
1612 """
1613 _assert_on_fail_handler(_wifi_connect_by_id, assert_on_fail, ad,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001614 network_id, num_of_tries)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001615
1616
Oscar Shucb9af9b2019-05-02 20:01:49 +00001617def _wifi_connect_by_id(ad, network_id, num_of_tries=1):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001618 """Connect an Android device to a wifi network using it's network id.
1619
1620 Start connection to the wifi network, with the given network id, wait for
1621 the "connected" event, then verify the connected network is the one requested.
1622
1623 Args:
1624 ad: android_device object to initiate connection on.
1625 network_id: Integer specifying the network id of the network.
1626 num_of_tries: An integer that is the number of times to try before
1627 delaring failure. Default is 1.
1628 """
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001629 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001630 # Clear all previous events.
1631 ad.ed.clear_all_events()
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001632 ad.droid.wifiConnectByNetworkId(network_id)
1633 ad.log.info("Starting connection to network with id %d", network_id)
1634 try:
1635 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_NETID_SUCCESS, 60)
Omar El Ayach8c017902020-10-18 10:26:57 -07001636 connect_result = _wait_for_connect_event(ad,
1637 id=network_id,
1638 tries=num_of_tries)
1639 asserts.assert_true(
1640 connect_result,
1641 "Failed to connect to Wi-Fi network using network id")
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001642 ad.log.debug("Wi-Fi connection result: %s", connect_result)
1643 actual_id = connect_result['data'][WifiEnums.NETID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001644 asserts.assert_equal(
1645 actual_id, network_id, "Connected to the wrong network on %s."
1646 "Expected network id = %d, but got %d." %
1647 (ad.serial, network_id, actual_id))
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001648 expected_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1649 ad.log.info("Connected to Wi-Fi network %s with %d network id.",
Omar El Ayach8c017902020-10-18 10:26:57 -07001650 expected_ssid, network_id)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001651
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001652 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1653 if not internet:
1654 raise signals.TestFailure("Failed to connect to internet on %s" %
1655 expected_ssid)
1656 except Empty:
1657 asserts.fail("Failed to connect to network with id %d on %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001658 (network_id, ad.serial))
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001659 except Exception as error:
1660 ad.log.error("Failed to connect to network with id %d with error %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07001661 network_id, error)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001662 raise signals.TestFailure("Failed to connect to network with network"
1663 " id %d" % network_id)
1664 finally:
1665 ad.droid.wifiStopTrackingStateChange()
1666
Oscar Shu0b5ff4d2019-08-07 18:11:56 +00001667
Omar El Ayach8c017902020-10-18 10:26:57 -07001668def wifi_connect_using_network_request(ad,
1669 network,
1670 network_specifier,
Roshan Pius5561d232021-01-22 16:34:39 -08001671 num_of_tries=3):
Roshan Piusc999e5e2018-11-09 10:59:52 -08001672 """Connect an Android device to a wifi network using network request.
1673
1674 Trigger a network request with the provided network specifier,
1675 wait for the "onMatch" event, ensure that the scan results in "onMatch"
1676 event contain the specified network, then simulate the user granting the
1677 request with the specified network selected. Then wait for the "onAvailable"
1678 network callback indicating successful connection to network.
1679
1680 Args:
1681 ad: android_device object to initiate connection on.
1682 network_specifier: A dictionary representing the network specifier to
1683 use.
1684 network: A dictionary representing the network to connect to. The
1685 dictionary must have the key "SSID".
1686 num_of_tries: An integer that is the number of times to try before
1687 delaring failure.
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001688 Returns:
1689 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001690 """
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001691 key = ad.droid.connectivityRequestWifiNetwork(network_specifier, 0)
1692 ad.log.info("Sent network request %s with %s " % (key, network_specifier))
Roshan Piusc999e5e2018-11-09 10:59:52 -08001693 # Need a delay here because UI interaction should only start once wifi
1694 # starts processing the request.
1695 time.sleep(wifi_constants.NETWORK_REQUEST_CB_REGISTER_DELAY_SEC)
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001696 _wait_for_wifi_connect_after_network_request(ad, network, key, num_of_tries)
1697 return key
Roshan Piusc999e5e2018-11-09 10:59:52 -08001698
1699
Omar El Ayach8c017902020-10-18 10:26:57 -07001700def wait_for_wifi_connect_after_network_request(ad,
1701 network,
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001702 key,
Omar El Ayach8c017902020-10-18 10:26:57 -07001703 num_of_tries=3,
Roshan Piusc999e5e2018-11-09 10:59:52 -08001704 assert_on_fail=True):
1705 """
1706 Simulate and verify the connection flow after initiating the network
1707 request.
1708
1709 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1710 event contain the specified network, then simulate the user granting the
1711 request with the specified network selected. Then wait for the "onAvailable"
1712 network callback indicating successful connection to network.
1713
1714 Args:
1715 ad: android_device object to initiate connection on.
1716 network: A dictionary representing the network to connect to. The
1717 dictionary must have the key "SSID".
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001718 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001719 num_of_tries: An integer that is the number of times to try before
1720 delaring failure.
1721 assert_on_fail: If True, error checks in this function will raise test
1722 failure signals.
1723
1724 Returns:
1725 Returns a value only if assert_on_fail is false.
1726 Returns True if the connection was successful, False otherwise.
1727 """
1728 _assert_on_fail_handler(_wait_for_wifi_connect_after_network_request,
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001729 assert_on_fail, ad, network, key, num_of_tries)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001730
1731
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001732def _wait_for_wifi_connect_after_network_request(ad, network, key, num_of_tries=3):
Roshan Piusc999e5e2018-11-09 10:59:52 -08001733 """
1734 Simulate and verify the connection flow after initiating the network
1735 request.
1736
1737 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1738 event contain the specified network, then simulate the user granting the
1739 request with the specified network selected. Then wait for the "onAvailable"
1740 network callback indicating successful connection to network.
1741
1742 Args:
1743 ad: android_device object to initiate connection on.
1744 network: A dictionary representing the network to connect to. The
1745 dictionary must have the key "SSID".
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001746 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001747 num_of_tries: An integer that is the number of times to try before
1748 delaring failure.
1749 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001750 asserts.assert_true(
1751 WifiEnums.SSID_KEY in network,
1752 "Key '%s' must be present in network definition." % WifiEnums.SSID_KEY)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001753 ad.droid.wifiStartTrackingStateChange()
1754 expected_ssid = network[WifiEnums.SSID_KEY]
1755 ad.droid.wifiRegisterNetworkRequestMatchCallback()
1756 # Wait for the platform to scan and return a list of networks
1757 # matching the request
1758 try:
1759 matched_network = None
Omar El Ayach8c017902020-10-18 10:26:57 -07001760 for _ in [0, num_of_tries]:
Roshan Piusc999e5e2018-11-09 10:59:52 -08001761 on_match_event = ad.ed.pop_event(
1762 wifi_constants.WIFI_NETWORK_REQUEST_MATCH_CB_ON_MATCH, 60)
1763 asserts.assert_true(on_match_event,
1764 "Network request on match not received.")
1765 matched_scan_results = on_match_event["data"]
1766 ad.log.debug("Network request on match results %s",
1767 matched_scan_results)
1768 matched_network = match_networks(
1769 {WifiEnums.SSID_KEY: network[WifiEnums.SSID_KEY]},
1770 matched_scan_results)
Roshan Pius6cd4aaf2021-02-09 15:54:30 -08001771 ad.log.debug("Network request on match %s", matched_network)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001772 if matched_network:
Omar El Ayach8c017902020-10-18 10:26:57 -07001773 break
Roshan Piusc999e5e2018-11-09 10:59:52 -08001774
Omar El Ayach8c017902020-10-18 10:26:57 -07001775 asserts.assert_true(matched_network,
1776 "Target network %s not found" % network)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001777
1778 ad.droid.wifiSendUserSelectionForNetworkRequestMatch(network)
1779 ad.log.info("Sent user selection for network request %s",
1780 expected_ssid)
1781
1782 # Wait for the platform to connect to the network.
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001783 autils.wait_for_event_with_keys(
1784 ad, cconsts.EVENT_NETWORK_CALLBACK,
1785 60,
1786 (cconsts.NETWORK_CB_KEY_ID, key),
1787 (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_AVAILABLE))
1788 on_capabilities_changed = autils.wait_for_event_with_keys(
1789 ad, cconsts.EVENT_NETWORK_CALLBACK,
1790 10,
1791 (cconsts.NETWORK_CB_KEY_ID, key),
1792 (cconsts.NETWORK_CB_KEY_EVENT,
1793 cconsts.NETWORK_CB_CAPABILITIES_CHANGED))
Roshan Pius008fe7f2021-03-25 14:18:17 -07001794 connected_network = None
1795 # WifiInfo is attached to TransportInfo only in S.
1796 if ad.droid.isSdkAtLeastS():
1797 connected_network = (
1798 on_capabilities_changed["data"][
1799 cconsts.NETWORK_CB_KEY_TRANSPORT_INFO]
1800 )
1801 else:
1802 connected_network = ad.droid.wifiGetConnectionInfo()
Roshan Piusc999e5e2018-11-09 10:59:52 -08001803 ad.log.info("Connected to network %s", connected_network)
Omar El Ayach8c017902020-10-18 10:26:57 -07001804 asserts.assert_equal(
1805 connected_network[WifiEnums.SSID_KEY], expected_ssid,
1806 "Connected to the wrong network."
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001807 "Expected %s, but got %s."
1808 % (network, connected_network))
Roshan Piusc999e5e2018-11-09 10:59:52 -08001809 except Empty:
1810 asserts.fail("Failed to connect to %s" % expected_ssid)
1811 except Exception as error:
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001812 ad.log.error("Failed to connect to %s with error %s" %
Roshan Piusc999e5e2018-11-09 10:59:52 -08001813 (expected_ssid, error))
1814 raise signals.TestFailure("Failed to connect to %s network" % network)
1815 finally:
1816 ad.droid.wifiStopTrackingStateChange()
1817
1818
Omar El Ayach8c017902020-10-18 10:26:57 -07001819def wifi_passpoint_connect(ad,
1820 passpoint_network,
1821 num_of_tries=1,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001822 assert_on_fail=True):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001823 """Connect an Android device to a wifi network.
1824
1825 Initiate connection to a wifi network, wait for the "connected" event, then
1826 confirm the connected ssid is the one requested.
1827
1828 This will directly fail a test if anything goes wrong.
1829
1830 Args:
1831 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001832 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001833 num_of_tries: An integer that is the number of times to try before
1834 delaring failure. Default is 1.
1835 assert_on_fail: If True, error checks in this function will raise test
1836 failure signals.
1837
1838 Returns:
1839 If assert_on_fail is False, function returns network id, if the connect was
1840 successful, False otherwise. If assert_on_fail is True, no return value.
1841 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001842 _assert_on_fail_handler(_wifi_passpoint_connect,
1843 assert_on_fail,
1844 ad,
1845 passpoint_network,
1846 num_of_tries=num_of_tries)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001847
1848
Oscar Shucb9af9b2019-05-02 20:01:49 +00001849def _wifi_passpoint_connect(ad, passpoint_network, num_of_tries=1):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001850 """Connect an Android device to a wifi network.
1851
1852 Initiate connection to a wifi network, wait for the "connected" event, then
1853 confirm the connected ssid is the one requested.
1854
1855 This will directly fail a test if anything goes wrong.
1856
1857 Args:
1858 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001859 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001860 num_of_tries: An integer that is the number of times to try before
1861 delaring failure. Default is 1.
1862 """
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001863 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001864 expected_ssid = passpoint_network
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001865 ad.log.info("Starting connection process to passpoint %s", expected_ssid)
1866
1867 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001868 connect_result = _wait_for_connect_event(ad, expected_ssid,
1869 num_of_tries)
1870 asserts.assert_true(
1871 connect_result, "Failed to connect to WiFi passpoint network %s on"
1872 " %s" % (expected_ssid, ad.serial))
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001873 ad.log.info("Wi-Fi connection result: %s.", connect_result)
1874 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001875 asserts.assert_equal(
1876 actual_ssid, expected_ssid,
1877 "Connected to the wrong network on %s." % ad.serial)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001878 ad.log.info("Connected to Wi-Fi passpoint network %s.", actual_ssid)
1879
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001880 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1881 if not internet:
1882 raise signals.TestFailure("Failed to connect to internet on %s" %
1883 expected_ssid)
1884 except Exception as error:
1885 ad.log.error("Failed to connect to passpoint network %s with error %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07001886 expected_ssid, error)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001887 raise signals.TestFailure("Failed to connect to %s passpoint network" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001888 expected_ssid)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001889
1890 finally:
1891 ad.droid.wifiStopTrackingStateChange()
1892
1893
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001894def delete_passpoint(ad, fqdn):
1895 """Delete a required Passpoint configuration."""
1896 try:
1897 ad.droid.removePasspointConfig(fqdn)
1898 return True
1899 except Exception as error:
Omar El Ayach8c017902020-10-18 10:26:57 -07001900 ad.log.error(
1901 "Failed to remove passpoint configuration with FQDN=%s "
1902 "and error=%s", fqdn, error)
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001903 return False
1904
1905
Ang Li73697b32015-12-03 00:41:53 +00001906def start_wifi_single_scan(ad, scan_setting):
1907 """Starts wifi single shot scan.
1908
1909 Args:
1910 ad: android_device object to initiate connection on.
1911 scan_setting: A dict representing the settings of the scan.
1912
1913 Returns:
1914 If scan was started successfully, event data of success event is returned.
1915 """
Ang Li82522812016-06-02 13:57:21 -07001916 idx = ad.droid.wifiScannerStartScan(scan_setting)
1917 event = ad.ed.pop_event("WifiScannerScan%sonSuccess" % idx, SHORT_TIMEOUT)
Ang Li31b00782016-06-21 13:04:23 -07001918 ad.log.debug("Got event %s", event)
Ang Li73697b32015-12-03 00:41:53 +00001919 return event['data']
1920
Ang Li82522812016-06-02 13:57:21 -07001921
Ang Li73697b32015-12-03 00:41:53 +00001922def track_connection(ad, network_ssid, check_connection_count):
1923 """Track wifi connection to network changes for given number of counts
1924
1925 Args:
1926 ad: android_device object for forget network.
1927 network_ssid: network ssid to which connection would be tracked
1928 check_connection_count: Integer for maximum number network connection
Ang Li82522812016-06-02 13:57:21 -07001929 check.
Ang Li73697b32015-12-03 00:41:53 +00001930 Returns:
Ang Li73697b32015-12-03 00:41:53 +00001931 True if connection to given network happen, else return False.
1932 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001933 ad.droid.wifiStartTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001934 while check_connection_count > 0:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001935 connect_network = ad.ed.pop_event("WifiNetworkConnected", 120)
Ang Li31b00782016-06-21 13:04:23 -07001936 ad.log.info("Connected to network %s", connect_network)
Ang Li82522812016-06-02 13:57:21 -07001937 if (WifiEnums.SSID_KEY in connect_network['data'] and
1938 connect_network['data'][WifiEnums.SSID_KEY] == network_ssid):
1939 return True
Ang Li8e767182015-12-09 17:29:24 -08001940 check_connection_count -= 1
Girish Moturu40d7dc22016-11-02 12:14:56 -07001941 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001942 return False
1943
Ang Li82522812016-06-02 13:57:21 -07001944
Ang Li73697b32015-12-03 00:41:53 +00001945def get_scan_time_and_channels(wifi_chs, scan_setting, stime_channel):
1946 """Calculate the scan time required based on the band or channels in scan
1947 setting
1948
1949 Args:
1950 wifi_chs: Object of channels supported
1951 scan_setting: scan setting used for start scan
1952 stime_channel: scan time per channel
1953
1954 Returns:
1955 scan_time: time required for completing a scan
1956 scan_channels: channel used for scanning
1957 """
1958 scan_time = 0
1959 scan_channels = []
1960 if "band" in scan_setting and "channels" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001961 scan_channels = wifi_chs.band_to_freq(scan_setting["band"])
Ang Li73697b32015-12-03 00:41:53 +00001962 elif "channels" in scan_setting and "band" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001963 scan_channels = scan_setting["channels"]
Ang Li73697b32015-12-03 00:41:53 +00001964 scan_time = len(scan_channels) * stime_channel
1965 for channel in scan_channels:
Ang Li8e767182015-12-09 17:29:24 -08001966 if channel in WifiEnums.DFS_5G_FREQUENCIES:
Ang Li82522812016-06-02 13:57:21 -07001967 scan_time += 132 #passive scan time on DFS
Ang Li73697b32015-12-03 00:41:53 +00001968 return scan_time, scan_channels
1969
Ang Li82522812016-06-02 13:57:21 -07001970
Ang Li73697b32015-12-03 00:41:53 +00001971def start_wifi_track_bssid(ad, track_setting):
1972 """Start tracking Bssid for the given settings.
1973
1974 Args:
1975 ad: android_device object.
1976 track_setting: Setting for which the bssid tracking should be started
1977
1978 Returns:
1979 If tracking started successfully, event data of success event is returned.
1980 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001981 idx = ad.droid.wifiScannerStartTrackingBssids(
Ang Li82522812016-06-02 13:57:21 -07001982 track_setting["bssidInfos"], track_setting["apLostThreshold"])
Girish Moturu40d7dc22016-11-02 12:14:56 -07001983 event = ad.ed.pop_event("WifiScannerBssid{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -08001984 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +00001985 return event['data']
1986
Ang Li82522812016-06-02 13:57:21 -07001987
Ang Li73697b32015-12-03 00:41:53 +00001988def convert_pem_key_to_pkcs8(in_file, out_file):
1989 """Converts the key file generated by us to the format required by
1990 Android using openssl.
1991
1992 The input file must have the extension "pem". The output file must
1993 have the extension "der".
1994
1995 Args:
1996 in_file: The original key file.
1997 out_file: The full path to the converted key file, including
1998 filename.
1999 """
Ang Li82522812016-06-02 13:57:21 -07002000 asserts.assert_true(in_file.endswith(".pem"), "Input file has to be .pem.")
Omar El Ayach8c017902020-10-18 10:26:57 -07002001 asserts.assert_true(out_file.endswith(".der"),
2002 "Output file has to be .der.")
Ang Li73697b32015-12-03 00:41:53 +00002003 cmd = ("openssl pkcs8 -inform PEM -in {} -outform DER -out {} -nocrypt"
2004 " -topk8").format(in_file, out_file)
Ang Lifee28402016-07-13 13:43:29 -07002005 utils.exe_cmd(cmd)
Ang Li73697b32015-12-03 00:41:53 +00002006
Ang Li82522812016-06-02 13:57:21 -07002007
Omar El Ayach8c017902020-10-18 10:26:57 -07002008def validate_connection(ad,
2009 ping_addr=DEFAULT_PING_ADDR,
2010 wait_time=15,
Girish Moturu804a3492020-02-17 14:32:02 -08002011 ping_gateway=True):
Ang Li73697b32015-12-03 00:41:53 +00002012 """Validate internet connection by pinging the address provided.
2013
2014 Args:
2015 ad: android_device object.
2016 ping_addr: address on internet for pinging.
Girish Moturua2a5bf22019-08-16 09:52:29 -07002017 wait_time: wait for some time before validating connection
Ang Li73697b32015-12-03 00:41:53 +00002018
2019 Returns:
Bindu Mahadev50374df2017-01-04 11:03:32 -08002020 ping output if successful, NULL otherwise.
Ang Li73697b32015-12-03 00:41:53 +00002021 """
Girish Moturua2a5bf22019-08-16 09:52:29 -07002022 # wait_time to allow for DHCP to complete.
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08002023 for i in range(wait_time):
Girish Moturuacf35002020-11-09 23:37:35 -08002024 if ad.droid.connectivityNetworkIsConnected(
Omar El Ayach8c017902020-10-18 10:26:57 -07002025 ) and ad.droid.connectivityGetIPv4DefaultGateway():
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08002026 break
2027 time.sleep(1)
Girish Moturu804a3492020-02-17 14:32:02 -08002028 ping = False
2029 try:
2030 ping = ad.droid.httpPing(ping_addr)
2031 ad.log.info("Http ping result: %s.", ping)
2032 except:
2033 pass
2034 if not ping and ping_gateway:
2035 ad.log.info("Http ping failed. Pinging default gateway")
2036 gw = ad.droid.connectivityGetIPv4DefaultGateway()
2037 result = ad.adb.shell("ping -c 6 {}".format(gw))
2038 ad.log.info("Default gateway ping result: %s" % result)
2039 ping = False if "100% packet loss" in result else True
Ang Li73697b32015-12-03 00:41:53 +00002040 return ping
2041
Ang Li82522812016-06-02 13:57:21 -07002042
Ang Li73697b32015-12-03 00:41:53 +00002043#TODO(angli): This can only verify if an actual value is exactly the same.
2044# Would be nice to be able to verify an actual value is one of serveral.
2045def verify_wifi_connection_info(ad, expected_con):
2046 """Verifies that the information of the currently connected wifi network is
2047 as expected.
2048
2049 Args:
2050 expected_con: A dict representing expected key-value pairs for wifi
2051 connection. e.g. {"SSID": "test_wifi"}
2052 """
2053 current_con = ad.droid.wifiGetConnectionInfo()
Ang Li374d7602016-02-08 17:27:27 -08002054 case_insensitive = ["BSSID", "supplicant_state"]
Ang Li31b00782016-06-21 13:04:23 -07002055 ad.log.debug("Current connection: %s", current_con)
Ang Li73697b32015-12-03 00:41:53 +00002056 for k, expected_v in expected_con.items():
Ang Li9a66de72016-02-08 15:26:38 -08002057 # Do not verify authentication related fields.
2058 if k == "password":
2059 continue
Ang Li82522812016-06-02 13:57:21 -07002060 msg = "Field %s does not exist in wifi connection info %s." % (
2061 k, current_con)
Ang Li374d7602016-02-08 17:27:27 -08002062 if k not in current_con:
2063 raise signals.TestFailure(msg)
2064 actual_v = current_con[k]
2065 if k in case_insensitive:
2066 actual_v = actual_v.lower()
2067 expected_v = expected_v.lower()
Ang Li73697b32015-12-03 00:41:53 +00002068 msg = "Expected %s to be %s, actual %s is %s." % (k, expected_v, k,
Ang Li82522812016-06-02 13:57:21 -07002069 actual_v)
Ang Li374d7602016-02-08 17:27:27 -08002070 if actual_v != expected_v:
2071 raise signals.TestFailure(msg)
Ang Li73697b32015-12-03 00:41:53 +00002072
Ang Li82522812016-06-02 13:57:21 -07002073
Omar El Ayach8c017902020-10-18 10:26:57 -07002074def check_autoconnect_to_open_network(
2075 ad, conn_timeout=WIFI_CONNECTION_TIMEOUT_DEFAULT):
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08002076 """Connects to any open WiFI AP
2077 Args:
2078 timeout value in sec to wait for UE to connect to a WiFi AP
2079 Returns:
2080 True if UE connects to WiFi AP (supplicant_state = completed)
2081 False if UE fails to complete connection within WIFI_CONNECTION_TIMEOUT time.
2082 """
2083 if ad.droid.wifiCheckState():
2084 return True
2085 ad.droid.wifiToggleState()
2086 wifi_connection_state = None
2087 timeout = time.time() + conn_timeout
2088 while wifi_connection_state != "completed":
Omar El Ayach8c017902020-10-18 10:26:57 -07002089 wifi_connection_state = ad.droid.wifiGetConnectionInfo(
2090 )['supplicant_state']
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08002091 if time.time() > timeout:
2092 ad.log.warning("Failed to connect to WiFi AP")
2093 return False
2094 return True
2095
2096
Ang Li73697b32015-12-03 00:41:53 +00002097def expand_enterprise_config_by_phase2(config):
2098 """Take an enterprise config and generate a list of configs, each with
2099 a different phase2 auth type.
2100
2101 Args:
2102 config: A dict representing enterprise config.
2103
2104 Returns
2105 A list of enterprise configs.
2106 """
2107 results = []
Ang Li0e7e58f2016-02-22 12:15:02 -08002108 phase2_types = WifiEnums.EapPhase2
2109 if config[WifiEnums.Enterprise.EAP] == WifiEnums.Eap.PEAP:
2110 # Skip unsupported phase2 types for PEAP.
2111 phase2_types = [WifiEnums.EapPhase2.GTC, WifiEnums.EapPhase2.MSCHAPV2]
2112 for phase2_type in phase2_types:
Ang Li73697b32015-12-03 00:41:53 +00002113 # Skip a special case for passpoint TTLS.
Omar El Ayach8c017902020-10-18 10:26:57 -07002114 if (WifiEnums.Enterprise.FQDN in config
2115 and phase2_type == WifiEnums.EapPhase2.GTC):
Ang Li73697b32015-12-03 00:41:53 +00002116 continue
2117 c = dict(config)
Girish Moturu150d32f2017-02-14 12:27:07 -08002118 c[WifiEnums.Enterprise.PHASE2] = phase2_type.value
Ang Li73697b32015-12-03 00:41:53 +00002119 results.append(c)
2120 return results
Ang Li2d3fe982016-06-08 10:00:43 -07002121
2122
Girish Moturub48a13c2017-02-27 11:36:42 -08002123def generate_eap_test_name(config, ad=None):
Girish Moturu150d32f2017-02-14 12:27:07 -08002124 """ Generates a test case name based on an EAP configuration.
2125
2126 Args:
2127 config: A dict representing an EAP credential.
Girish Moturub48a13c2017-02-27 11:36:42 -08002128 ad object: Redundant but required as the same param is passed
2129 to test_func in run_generated_tests
Girish Moturu150d32f2017-02-14 12:27:07 -08002130
2131 Returns:
2132 A string representing the name of a generated EAP test case.
2133 """
2134 eap = WifiEnums.Eap
2135 eap_phase2 = WifiEnums.EapPhase2
Girish Moturub48a13c2017-02-27 11:36:42 -08002136 Ent = WifiEnums.Enterprise
Girish Moturu150d32f2017-02-14 12:27:07 -08002137 name = "test_connect-"
2138 eap_name = ""
2139 for e in eap:
2140 if e.value == config[Ent.EAP]:
2141 eap_name = e.name
2142 break
2143 if "peap0" in config[WifiEnums.SSID_KEY].lower():
2144 eap_name = "PEAP0"
2145 if "peap1" in config[WifiEnums.SSID_KEY].lower():
2146 eap_name = "PEAP1"
2147 name += eap_name
2148 if Ent.PHASE2 in config:
2149 for e in eap_phase2:
2150 if e.value == config[Ent.PHASE2]:
2151 name += "-{}".format(e.name)
2152 break
2153 return name
2154
2155
Ang Li2d3fe982016-06-08 10:00:43 -07002156def group_attenuators(attenuators):
2157 """Groups a list of attenuators into attenuator groups for backward
2158 compatibility reasons.
2159
2160 Most legacy Wi-Fi setups have two attenuators each connected to a separate
2161 AP. The new Wi-Fi setup has four attenuators, each connected to one channel
2162 on an AP, so two of them are connected to one AP.
2163
2164 To make the existing scripts work in the new setup, when the script needs
2165 to attenuate one AP, it needs to set attenuation on both attenuators
2166 connected to the same AP.
2167
2168 This function groups attenuators properly so the scripts work in both
2169 legacy and new Wi-Fi setups.
2170
2171 Args:
2172 attenuators: A list of attenuator objects, either two or four in length.
2173
2174 Raises:
2175 signals.TestFailure is raised if the attenuator list does not have two
2176 or four objects.
2177 """
2178 attn0 = attenuator.AttenuatorGroup("AP0")
2179 attn1 = attenuator.AttenuatorGroup("AP1")
2180 # Legacy testbed setup has two attenuation channels.
2181 num_of_attns = len(attenuators)
2182 if num_of_attns == 2:
2183 attn0.add(attenuators[0])
2184 attn1.add(attenuators[1])
2185 elif num_of_attns == 4:
2186 attn0.add(attenuators[0])
2187 attn0.add(attenuators[1])
2188 attn1.add(attenuators[2])
2189 attn1.add(attenuators[3])
2190 else:
2191 asserts.fail(("Either two or four attenuators are required for this "
2192 "test, but found %s") % num_of_attns)
2193 return [attn0, attn1]
Jong Wook Kim92356922018-02-06 18:32:49 -08002194
Bindu Mahadevff295782019-02-08 16:17:48 -08002195
Girish Moturu36348a32019-12-10 08:41:54 -08002196def set_attns(attenuator, attn_val_name, roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002197 """Sets attenuation values on attenuators used in this test.
2198
2199 Args:
2200 attenuator: The attenuator object.
2201 attn_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002202 roaming_attn: Dictionary specifying the attenuation params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002203 """
2204 logging.info("Set attenuation values to %s", roaming_attn[attn_val_name])
2205 try:
2206 attenuator[0].set_atten(roaming_attn[attn_val_name][0])
2207 attenuator[1].set_atten(roaming_attn[attn_val_name][1])
2208 attenuator[2].set_atten(roaming_attn[attn_val_name][2])
2209 attenuator[3].set_atten(roaming_attn[attn_val_name][3])
2210 except:
2211 logging.exception("Failed to set attenuation values %s.",
Omar El Ayach8c017902020-10-18 10:26:57 -07002212 attn_val_name)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002213 raise
2214
Omar El Ayach8c017902020-10-18 10:26:57 -07002215
Girish Moturu36348a32019-12-10 08:41:54 -08002216def set_attns_steps(attenuators,
2217 atten_val_name,
2218 roaming_attn=ROAMING_ATTN,
2219 steps=10,
2220 wait_time=12):
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002221 """Set attenuation values on attenuators used in this test. It will change
2222 the attenuation values linearly from current value to target value step by
2223 step.
2224
2225 Args:
2226 attenuators: The list of attenuator objects that you want to change
2227 their attenuation value.
2228 atten_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002229 roaming_attn: Dictionary specifying the attenuation params.
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002230 steps: Number of attenuator changes to reach the target value.
2231 wait_time: Sleep time for each change of attenuator.
2232 """
2233 logging.info("Set attenuation values to %s in %d step(s)",
Omar El Ayach8c017902020-10-18 10:26:57 -07002234 roaming_attn[atten_val_name], steps)
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002235 start_atten = [attenuator.get_atten() for attenuator in attenuators]
2236 target_atten = roaming_attn[atten_val_name]
2237 for current_step in range(steps):
2238 progress = (current_step + 1) / steps
2239 for i, attenuator in enumerate(attenuators):
2240 amount_since_start = (target_atten[i] - start_atten[i]) * progress
2241 attenuator.set_atten(round(start_atten[i] + amount_since_start))
2242 time.sleep(wait_time)
2243
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002244
Girish Moturu36348a32019-12-10 08:41:54 -08002245def trigger_roaming_and_validate(dut,
2246 attenuator,
2247 attn_val_name,
2248 expected_con,
2249 roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002250 """Sets attenuators to trigger roaming and validate the DUT connected
2251 to the BSSID expected.
2252
2253 Args:
2254 attenuator: The attenuator object.
2255 attn_val_name: Name of the attenuation value pair to use.
2256 expected_con: The network information of the expected network.
Girish Moturu36348a32019-12-10 08:41:54 -08002257 roaming_attn: Dictionary specifying the attenaution params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002258 """
2259 expected_con = {
2260 WifiEnums.SSID_KEY: expected_con[WifiEnums.SSID_KEY],
2261 WifiEnums.BSSID_KEY: expected_con["bssid"],
2262 }
Girish Moturu36348a32019-12-10 08:41:54 -08002263 set_attns_steps(attenuator, attn_val_name, roaming_attn)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002264
Hsiu-Chang Chenef856402018-09-18 12:32:49 +08002265 verify_wifi_connection_info(dut, expected_con)
2266 expected_bssid = expected_con[WifiEnums.BSSID_KEY]
2267 logging.info("Roamed to %s successfully", expected_bssid)
2268 if not validate_connection(dut):
2269 raise signals.TestFailure("Fail to connect to internet on %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07002270 expected_bssid)
2271
Jong Wook Kim92356922018-02-06 18:32:49 -08002272
2273def create_softap_config():
2274 """Create a softap config with random ssid and password."""
2275 ap_ssid = "softap_" + utils.rand_ascii_str(8)
2276 ap_password = utils.rand_ascii_str(8)
2277 logging.info("softap setup: %s %s", ap_ssid, ap_password)
2278 config = {
2279 WifiEnums.SSID_KEY: ap_ssid,
2280 WifiEnums.PWD_KEY: ap_password,
2281 }
2282 return config
Girish Moturucf4dccd2018-08-27 12:22:00 -07002283
Omar El Ayach8c017902020-10-18 10:26:57 -07002284
Bindu Mahadevff295782019-02-08 16:17:48 -08002285def start_softap_and_verify(ad, band):
2286 """Bring-up softap and verify AP mode and in scan results.
2287
2288 Args:
2289 band: The band to use for softAP.
2290
2291 Returns: dict, the softAP config.
2292
2293 """
lesl2f0fb232019-11-05 16:35:28 +08002294 # Register before start the test.
2295 callbackId = ad.dut.droid.registerSoftApCallback()
2296 # Check softap info value is default
2297 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2298 asserts.assert_true(frequency == 0, "Softap frequency is not reset")
2299 asserts.assert_true(bandwdith == 0, "Softap bandwdith is not reset")
2300
Bindu Mahadevff295782019-02-08 16:17:48 -08002301 config = create_softap_config()
2302 start_wifi_tethering(ad.dut,
2303 config[WifiEnums.SSID_KEY],
Omar El Ayach8c017902020-10-18 10:26:57 -07002304 config[WifiEnums.PWD_KEY],
2305 band=band)
Bindu Mahadevff295782019-02-08 16:17:48 -08002306 asserts.assert_true(ad.dut.droid.wifiIsApEnabled(),
Omar El Ayach8c017902020-10-18 10:26:57 -07002307 "SoftAp is not reported as running")
2308 start_wifi_connection_scan_and_ensure_network_found(
2309 ad.dut_client, config[WifiEnums.SSID_KEY])
lesl2f0fb232019-11-05 16:35:28 +08002310
2311 # Check softap info can get from callback succeed and assert value should be
2312 # valid.
2313 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2314 asserts.assert_true(frequency > 0, "Softap frequency is not valid")
2315 asserts.assert_true(bandwdith > 0, "Softap bandwdith is not valid")
2316 # Unregister callback
2317 ad.dut.droid.unregisterSoftApCallback(callbackId)
2318
Bindu Mahadevff295782019-02-08 16:17:48 -08002319 return config
2320
Omar El Ayach8c017902020-10-18 10:26:57 -07002321
lesle8e3c0a2019-02-22 17:06:04 +08002322def wait_for_expected_number_of_softap_clients(ad, callbackId,
Omar El Ayach8c017902020-10-18 10:26:57 -07002323 expected_num_of_softap_clients):
lesle8e3c0a2019-02-22 17:06:04 +08002324 """Wait for the number of softap clients to be updated as expected.
2325 Args:
2326 callbackId: Id of the callback associated with registering.
2327 expected_num_of_softap_clients: expected number of softap clients.
2328 """
2329 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002330 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
James Mattis5a5dd492020-05-14 13:09:43 -07002331 clientData = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data']
2332 clientCount = clientData[wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07002333 clientMacAddresses = clientData[
2334 wifi_constants.SOFTAP_CLIENTS_MACS_CALLBACK_KEY]
2335 asserts.assert_equal(
2336 clientCount, expected_num_of_softap_clients,
2337 "The number of softap clients doesn't match the expected number")
2338 asserts.assert_equal(
2339 len(clientMacAddresses), expected_num_of_softap_clients,
2340 "The number of mac addresses doesn't match the expected number")
James Mattis5a5dd492020-05-14 13:09:43 -07002341 for macAddress in clientMacAddresses:
Omar El Ayach8c017902020-10-18 10:26:57 -07002342 asserts.assert_true(checkMacAddress(macAddress),
2343 "An invalid mac address was returned")
2344
James Mattis5a5dd492020-05-14 13:09:43 -07002345
2346def checkMacAddress(input):
2347 """Validate whether a string is a valid mac address or not.
2348
2349 Args:
2350 input: The string to validate.
2351
2352 Returns: True/False, returns true for a valid mac address and false otherwise.
2353 """
2354 macValidationRegex = "[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$"
2355 if re.match(macValidationRegex, input.lower()):
2356 return True
2357 return False
lesle8e3c0a2019-02-22 17:06:04 +08002358
Omar El Ayach8c017902020-10-18 10:26:57 -07002359
lesle8e3c0a2019-02-22 17:06:04 +08002360def wait_for_expected_softap_state(ad, callbackId, expected_softap_state):
2361 """Wait for the expected softap state change.
2362 Args:
2363 callbackId: Id of the callback associated with registering.
2364 expected_softap_state: The expected softap state.
2365 """
2366 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002367 callbackId) + wifi_constants.SOFTAP_STATE_CHANGED
2368 asserts.assert_equal(
2369 ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data'][
2370 wifi_constants.SOFTAP_STATE_CHANGE_CALLBACK_KEY],
2371 expected_softap_state,
2372 "Softap state doesn't match with expected state")
2373
lesle8e3c0a2019-02-22 17:06:04 +08002374
2375def get_current_number_of_softap_clients(ad, callbackId):
2376 """pop up all of softap client updated event from queue.
2377 Args:
2378 callbackId: Id of the callback associated with registering.
2379
2380 Returns:
2381 If exist aleast callback, returns last updated number_of_softap_clients.
2382 Returns None when no any match callback event in queue.
2383 """
2384 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002385 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
lesle8e3c0a2019-02-22 17:06:04 +08002386 events = ad.ed.pop_all(eventStr)
2387 for event in events:
Omar El Ayach8c017902020-10-18 10:26:57 -07002388 num_of_clients = event['data'][
2389 wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
lesle8e3c0a2019-02-22 17:06:04 +08002390 if len(events) == 0:
2391 return None
2392 return num_of_clients
Bindu Mahadevff295782019-02-08 16:17:48 -08002393
Omar El Ayach8c017902020-10-18 10:26:57 -07002394
lesl67124362021-05-04 19:33:14 +08002395def get_current_softap_info(ad, callbackId, need_to_wait):
lesl2f0fb232019-11-05 16:35:28 +08002396 """pop up all of softap info changed event from queue.
2397 Args:
2398 callbackId: Id of the callback associated with registering.
lesl67124362021-05-04 19:33:14 +08002399 need_to_wait: Wait for the info callback event before pop all.
lesl2f0fb232019-11-05 16:35:28 +08002400 Returns:
2401 Returns last updated information of softap.
2402 """
2403 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002404 callbackId) + wifi_constants.SOFTAP_INFO_CHANGED
lesl67124362021-05-04 19:33:14 +08002405 ad.log.debug("softap info dump from eventStr %s", eventStr)
lesl2f0fb232019-11-05 16:35:28 +08002406 frequency = 0
2407 bandwidth = 0
lesl67124362021-05-04 19:33:14 +08002408 if (need_to_wait):
lesl2f0fb232019-11-05 16:35:28 +08002409 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
Omar El Ayach8c017902020-10-18 10:26:57 -07002410 frequency = event['data'][
2411 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2412 bandwidth = event['data'][
2413 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
lesl2f0fb232019-11-05 16:35:28 +08002414 ad.log.info("softap info updated, frequency is %s, bandwidth is %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07002415 frequency, bandwidth)
lesl2f0fb232019-11-05 16:35:28 +08002416
2417 events = ad.ed.pop_all(eventStr)
2418 for event in events:
Omar El Ayach8c017902020-10-18 10:26:57 -07002419 frequency = event['data'][
2420 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2421 bandwidth = event['data'][
2422 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
2423 ad.log.info("softap info, frequency is %s, bandwidth is %s", frequency,
2424 bandwidth)
lesl2f0fb232019-11-05 16:35:28 +08002425 return frequency, bandwidth
2426
lesl67124362021-05-04 19:33:14 +08002427def get_current_softap_infos(ad, callbackId, need_to_wait):
2428 """pop up all of softap info list changed event from queue.
2429 Args:
2430 callbackId: Id of the callback associated with registering.
2431 need_to_wait: Wait for the info callback event before pop all.
2432 Returns:
2433 Returns last updated informations of softap.
2434 """
2435 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
2436 callbackId) + wifi_constants.SOFTAP_INFOLIST_CHANGED
2437 ad.log.debug("softap info dump from eventStr %s", eventStr)
2438
2439 if (need_to_wait):
2440 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
2441 infos = event['data']
2442
2443 events = ad.ed.pop_all(eventStr)
2444 for event in events:
2445 infos = event['data']
2446
2447 for info in infos:
2448 frequency = info[
2449 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2450 bandwidth = info[
2451 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
2452 wifistandard = info[
2453 wifi_constants.SOFTAP_INFO_WIFISTANDARD_CALLBACK_KEY]
2454 bssid = info[
2455 wifi_constants.SOFTAP_INFO_BSSID_CALLBACK_KEY]
2456 ad.log.info(
2457 "softap info, freq:%s, bw:%s, wifistandard:%s, bssid:%s",
2458 frequency, bandwidth, wifistandard, bssid)
2459
2460 return infos
2461
2462def get_current_softap_capability(ad, callbackId, need_to_wait):
2463 """pop up all of softap info list changed event from queue.
2464 Args:
2465 callbackId: Id of the callback associated with registering.
2466 need_to_wait: Wait for the info callback event before pop all.
2467 Returns:
2468 Returns last updated capability of softap.
2469 """
2470 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
2471 callbackId) + wifi_constants.SOFTAP_CAPABILITY_CHANGED
2472 ad.log.debug("softap capability dump from eventStr %s", eventStr)
2473 if (need_to_wait):
2474 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
2475 capability = event['data']
2476
2477 events = ad.ed.pop_all(eventStr)
2478 for event in events:
2479 capability = event['data']
2480
2481 return capability
lesl2f0fb232019-11-05 16:35:28 +08002482
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002483def get_ssrdumps(ad):
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002484 """Pulls dumps in the ssrdump dir
2485 Args:
2486 ad: android device object.
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002487 """
2488 logs = ad.get_file_names("/data/vendor/ssrdump/")
2489 if logs:
2490 ad.log.info("Pulling ssrdumps %s", logs)
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002491 log_path = os.path.join(ad.device_log_path, "SSRDUMPS_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002492 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002493 ad.pull_files(logs, log_path)
Hsiu-Chang Chen769bef12020-10-10 06:07:52 +00002494 ad.adb.shell("find /data/vendor/ssrdump/ -type f -delete",
Omar El Ayach8c017902020-10-18 10:26:57 -07002495 ignore_status=True)
2496
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002497
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002498def start_pcap(pcap, wifi_band, test_name):
Girish Moturucf4dccd2018-08-27 12:22:00 -07002499 """Start packet capture in monitor mode.
2500
2501 Args:
2502 pcap: packet capture object
2503 wifi_band: '2g' or '5g' or 'dual'
Bindu Mahadev76551c12018-12-13 19:42:14 +00002504 test_name: test name to be used for pcap file name
2505
2506 Returns:
xianyuanjia0431ba32018-12-14 09:56:42 -08002507 Dictionary with wifi band as key and the tuple
2508 (pcap Process object, log directory) as the value
Girish Moturucf4dccd2018-08-27 12:22:00 -07002509 """
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002510 log_dir = os.path.join(
Xianyuan Jia5cd06bb2019-06-10 16:29:57 -07002511 context.get_current_context().get_full_output_path(), 'PacketCapture')
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002512 os.makedirs(log_dir, exist_ok=True)
Girish Moturucf4dccd2018-08-27 12:22:00 -07002513 if wifi_band == 'dual':
2514 bands = [BAND_2G, BAND_5G]
2515 else:
2516 bands = [wifi_band]
xianyuanjia0431ba32018-12-14 09:56:42 -08002517 procs = {}
Girish Moturucf4dccd2018-08-27 12:22:00 -07002518 for band in bands:
xianyuanjia0431ba32018-12-14 09:56:42 -08002519 proc = pcap.start_packet_capture(band, log_dir, test_name)
2520 procs[band] = (proc, os.path.join(log_dir, test_name))
2521 return procs
Girish Moturucf4dccd2018-08-27 12:22:00 -07002522
Bindu Mahadevff295782019-02-08 16:17:48 -08002523
xianyuanjia0431ba32018-12-14 09:56:42 -08002524def stop_pcap(pcap, procs, test_status=None):
Bindu Mahadev76551c12018-12-13 19:42:14 +00002525 """Stop packet capture in monitor mode.
2526
2527 Since, the pcap logs in monitor mode can be very large, we will
2528 delete them if they are not required. 'test_status' if True, will delete
2529 the pcap files. If False, we will keep them.
Girish Moturucf4dccd2018-08-27 12:22:00 -07002530
2531 Args:
2532 pcap: packet capture object
xianyuanjia0431ba32018-12-14 09:56:42 -08002533 procs: dictionary returned by start_pcap
Bindu Mahadev76551c12018-12-13 19:42:14 +00002534 test_status: status of the test case
Girish Moturucf4dccd2018-08-27 12:22:00 -07002535 """
xianyuanjia0431ba32018-12-14 09:56:42 -08002536 for proc, fname in procs.values():
2537 pcap.stop_packet_capture(proc)
Bindu Mahadev76551c12018-12-13 19:42:14 +00002538
2539 if test_status:
xianyuanjia0431ba32018-12-14 09:56:42 -08002540 shutil.rmtree(os.path.dirname(fname))
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002541
Omar El Ayach8c017902020-10-18 10:26:57 -07002542
Jaineel95887fd2019-10-16 16:19:01 -07002543def verify_mac_not_found_in_pcap(ad, mac, packets):
xshuf7267682019-06-03 14:41:56 -07002544 """Verify that a mac address is not found in the captured packets.
2545
2546 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002547 ad: android device object
xshuf7267682019-06-03 14:41:56 -07002548 mac: string representation of the mac address
2549 packets: packets obtained by rdpcap(pcap_fname)
2550 """
2551 for pkt in packets:
2552 logging.debug("Packet Summary = %s", pkt.summary())
2553 if mac in pkt.summary():
Jaineel95887fd2019-10-16 16:19:01 -07002554 asserts.fail("Device %s caught Factory MAC: %s in packet sniffer."
2555 "Packet = %s" % (ad.serial, mac, pkt.show()))
Bindu Mahadevff295782019-02-08 16:17:48 -08002556
Omar El Ayach8c017902020-10-18 10:26:57 -07002557
Jaineel95887fd2019-10-16 16:19:01 -07002558def verify_mac_is_found_in_pcap(ad, mac, packets):
Nate Jiangc2c09c62019-06-05 17:26:08 -07002559 """Verify that a mac address is found in the captured packets.
2560
2561 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002562 ad: android device object
Nate Jiangc2c09c62019-06-05 17:26:08 -07002563 mac: string representation of the mac address
2564 packets: packets obtained by rdpcap(pcap_fname)
2565 """
2566 for pkt in packets:
2567 if mac in pkt.summary():
2568 return
Jaineel95887fd2019-10-16 16:19:01 -07002569 asserts.fail("Did not find MAC = %s in packet sniffer."
2570 "for device %s" % (mac, ad.serial))
Nate Jiangc2c09c62019-06-05 17:26:08 -07002571
Omar El Ayach8c017902020-10-18 10:26:57 -07002572
Girish Moturuddc0d382020-08-24 12:08:41 -07002573def start_cnss_diags(ads, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002574 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002575 start_cnss_diag(ad, cnss_diag_file, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002576
Bindu Mahadevff295782019-02-08 16:17:48 -08002577
Girish Moturuddc0d382020-08-24 12:08:41 -07002578def start_cnss_diag(ad, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002579 """Start cnss_diag to record extra wifi logs
2580
2581 Args:
2582 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002583 cnss_diag_file: cnss diag config file to push to device.
2584 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002585 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002586 if ad.model not in pixel_models:
2587 ad.log.info("Device not supported to collect pixel logger")
2588 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002589 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2590 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2591 else:
2592 prop = wifi_constants.CNSS_DIAG_PROP
2593 if ad.adb.getprop(prop) != 'true':
Omar El Ayach8c017902020-10-18 10:26:57 -07002594 if not int(
2595 ad.adb.shell("ls -l %s%s | wc -l" %
2596 (CNSS_DIAG_CONFIG_PATH, CNSS_DIAG_CONFIG_FILE))):
Girish Moturuddc0d382020-08-24 12:08:41 -07002597 ad.adb.push("%s %s" % (cnss_diag_file, CNSS_DIAG_CONFIG_PATH))
Omar El Ayach8c017902020-10-18 10:26:57 -07002598 ad.adb.shell(
2599 "find /data/vendor/wifi/cnss_diag/wlan_logs/ -type f -delete",
2600 ignore_status=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002601 ad.adb.shell("setprop %s true" % prop, ignore_status=True)
2602
Bindu Mahadevff295782019-02-08 16:17:48 -08002603
Girish Moturuddc0d382020-08-24 12:08:41 -07002604def stop_cnss_diags(ads, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002605 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002606 stop_cnss_diag(ad, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002607
Bindu Mahadevff295782019-02-08 16:17:48 -08002608
Girish Moturuddc0d382020-08-24 12:08:41 -07002609def stop_cnss_diag(ad, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002610 """Stops cnss_diag
2611
2612 Args:
2613 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002614 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002615 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002616 if ad.model not in pixel_models:
2617 ad.log.info("Device not supported to collect pixel logger")
2618 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002619 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2620 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2621 else:
2622 prop = wifi_constants.CNSS_DIAG_PROP
2623 ad.adb.shell("setprop %s false" % prop, ignore_status=True)
2624
Bindu Mahadevff295782019-02-08 16:17:48 -08002625
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002626def get_cnss_diag_log(ad):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002627 """Pulls the cnss_diag logs in the wlan_logs dir
2628 Args:
2629 ad: android device object.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002630 """
2631 logs = ad.get_file_names("/data/vendor/wifi/cnss_diag/wlan_logs/")
2632 if logs:
2633 ad.log.info("Pulling cnss_diag logs %s", logs)
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002634 log_path = os.path.join(ad.device_log_path, "CNSS_DIAG_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002635 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002636 ad.pull_files(logs, log_path)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002637
Bindu Mahadevff295782019-02-08 16:17:48 -08002638
Omar El Ayach8c017902020-10-18 10:26:57 -07002639LinkProbeResult = namedtuple(
2640 'LinkProbeResult',
2641 ('is_success', 'stdout', 'elapsed_time', 'failure_reason'))
David Sue4cd9c22019-03-26 18:07:26 -07002642
2643
2644def send_link_probe(ad):
2645 """Sends a link probe to the currently connected AP, and returns whether the
2646 probe succeeded or not.
2647
2648 Args:
2649 ad: android device object
2650 Returns:
2651 LinkProbeResult namedtuple
2652 """
2653 stdout = ad.adb.shell('cmd wifi send-link-probe')
2654 asserts.assert_false('Error' in stdout or 'Exception' in stdout,
2655 'Exception while sending link probe: ' + stdout)
2656
2657 is_success = False
2658 elapsed_time = None
2659 failure_reason = None
2660 if 'succeeded' in stdout:
2661 is_success = True
2662 elapsed_time = next(
2663 (int(token) for token in stdout.split() if token.isdigit()), None)
2664 elif 'failed with reason' in stdout:
2665 failure_reason = next(
2666 (int(token) for token in stdout.split() if token.isdigit()), None)
2667 else:
2668 asserts.fail('Unexpected link probe result: ' + stdout)
2669
Omar El Ayach8c017902020-10-18 10:26:57 -07002670 return LinkProbeResult(is_success=is_success,
2671 stdout=stdout,
2672 elapsed_time=elapsed_time,
2673 failure_reason=failure_reason)
David Sue4cd9c22019-03-26 18:07:26 -07002674
2675
2676def send_link_probes(ad, num_probes, delay_sec):
2677 """Sends a sequence of link probes to the currently connected AP, and
2678 returns whether the probes succeeded or not.
2679
2680 Args:
2681 ad: android device object
2682 num_probes: number of probes to perform
2683 delay_sec: delay time between probes, in seconds
2684 Returns:
2685 List[LinkProbeResult] one LinkProbeResults for each probe
2686 """
2687 logging.info('Sending link probes')
2688 results = []
2689 for _ in range(num_probes):
2690 # send_link_probe() will also fail the test if it sees an exception
2691 # in the stdout of the adb shell command
2692 result = send_link_probe(ad)
2693 logging.info('link probe results: ' + str(result))
2694 results.append(result)
2695 time.sleep(delay_sec)
2696
2697 return results
2698
2699
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002700def ap_setup(test, index, ap, network, bandwidth=80, channel=6):
Omar El Ayach8c017902020-10-18 10:26:57 -07002701 """Set up the AP with provided network info.
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002702
2703 Args:
2704 test: the calling test class object.
2705 index: int, index of the AP.
2706 ap: access_point object of the AP.
2707 network: dict with information of the network, including ssid,
2708 password and bssid.
2709 bandwidth: the operation bandwidth for the AP, default 80MHz.
2710 channel: the channel number for the AP.
2711 Returns:
2712 brconfigs: the bridge interface configs
2713 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002714 bss_settings = []
2715 ssid = network[WifiEnums.SSID_KEY]
2716 test.access_points[index].close()
2717 time.sleep(5)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002718
Omar El Ayach8c017902020-10-18 10:26:57 -07002719 # Configure AP as required.
2720 if "password" in network.keys():
2721 password = network["password"]
2722 security = hostapd_security.Security(security_mode="wpa",
2723 password=password)
2724 else:
2725 security = hostapd_security.Security(security_mode=None, password=None)
2726 config = hostapd_ap_preset.create_ap_preset(channel=channel,
2727 ssid=ssid,
2728 security=security,
2729 bss_settings=bss_settings,
2730 vht_bandwidth=bandwidth,
2731 profile_name='whirlwind',
2732 iface_wlan_2g=ap.wlan_2g,
2733 iface_wlan_5g=ap.wlan_5g)
2734 ap.start_ap(config)
2735 logging.info("AP started on channel {} with SSID {}".format(channel, ssid))
Bindu Mahadevff295782019-02-08 16:17:48 -08002736
2737
2738def turn_ap_off(test, AP):
2739 """Bring down hostapd on the Access Point.
2740 Args:
2741 test: The test class object.
2742 AP: int, indicating which AP to turn OFF.
2743 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002744 hostapd_2g = test.access_points[AP - 1]._aps['wlan0'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002745 if hostapd_2g.is_alive():
2746 hostapd_2g.stop()
2747 logging.debug('Turned WLAN0 AP%d off' % AP)
Omar El Ayach8c017902020-10-18 10:26:57 -07002748 hostapd_5g = test.access_points[AP - 1]._aps['wlan1'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002749 if hostapd_5g.is_alive():
2750 hostapd_5g.stop()
2751 logging.debug('Turned WLAN1 AP%d off' % AP)
2752
2753
2754def turn_ap_on(test, AP):
2755 """Bring up hostapd on the Access Point.
2756 Args:
2757 test: The test class object.
2758 AP: int, indicating which AP to turn ON.
2759 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002760 hostapd_2g = test.access_points[AP - 1]._aps['wlan0'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002761 if not hostapd_2g.is_alive():
2762 hostapd_2g.start(hostapd_2g.config)
2763 logging.debug('Turned WLAN0 AP%d on' % AP)
Omar El Ayach8c017902020-10-18 10:26:57 -07002764 hostapd_5g = test.access_points[AP - 1]._aps['wlan1'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002765 if not hostapd_5g.is_alive():
2766 hostapd_5g.start(hostapd_5g.config)
2767 logging.debug('Turned WLAN1 AP%d on' % AP)
Joe Brennan48c3f692019-04-11 08:30:16 -07002768
2769
2770def turn_location_off_and_scan_toggle_off(ad):
2771 """Turns off wifi location scans."""
2772 utils.set_location_service(ad, False)
2773 ad.droid.wifiScannerToggleAlwaysAvailable(False)
2774 msg = "Failed to turn off location service's scan."
2775 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
Alfie Chen675be872020-06-04 10:48:14 +08002776
2777
2778def set_softap_channel(dut, ap_iface='wlan1', cs_count=10, channel=2462):
2779 """ Set SoftAP mode channel
2780
2781 Args:
2782 dut: android device object
2783 ap_iface: interface of SoftAP mode.
2784 cs_count: how many beacon frames before switch channel, default = 10
2785 channel: a wifi channel.
2786 """
2787 chan_switch_cmd = 'hostapd_cli -i {} chan_switch {} {}'
Omar El Ayach8c017902020-10-18 10:26:57 -07002788 chan_switch_cmd_show = chan_switch_cmd.format(ap_iface, cs_count, channel)
Alfie Chen675be872020-06-04 10:48:14 +08002789 dut.log.info('adb shell {}'.format(chan_switch_cmd_show))
Omar El Ayach8c017902020-10-18 10:26:57 -07002790 chan_switch_result = dut.adb.shell(
2791 chan_switch_cmd.format(ap_iface, cs_count, channel))
Alfie Chen675be872020-06-04 10:48:14 +08002792 if chan_switch_result == 'OK':
2793 dut.log.info('switch hotspot channel to {}'.format(channel))
2794 return chan_switch_result
2795
2796 asserts.fail("Failed to switch hotspot channel")
Alfie Chen310f7ff2021-01-26 20:36:09 +08002797
2798def get_wlan0_link(dut):
2799 """ get wlan0 interface status"""
2800 get_wlan0 = 'wpa_cli -iwlan0 -g@android:wpa_wlan0 IFNAME=wlan0 status'
2801 out = dut.adb.shell(get_wlan0)
2802 out = dict(re.findall(r'(\S+)=(".*?"|\S+)', out))
2803 asserts.assert_true("ssid" in out,
2804 "Client doesn't connect to any network")
Alfie Chenb3263dd2021-02-04 18:54:34 +08002805 return out
Girish Moturubea6c7e2021-05-07 16:24:27 -07002806
2807def verify_11ax_wifi_connection(ad, wifi6_supported_models, wifi6_ap):
2808 """Verify 11ax for wifi connection.
2809
2810 Args:
2811 ad: adndroid device object
2812 wifi6_supported_models: device supporting 11ax.
2813 wifi6_ap: if the AP supports 11ax.
2814 """
2815 if wifi6_ap and ad.model in wifi6_supported_models:
2816 logging.info("Verifying 11ax. Model: %s" % ad.model)
2817 asserts.assert_true(
2818 ad.droid.wifiGetConnectionStandard() ==
2819 wifi_constants.WIFI_STANDARD_11AX, "DUT did not connect to 11ax.")
2820
2821def verify_11ax_softap(dut, dut_client, wifi6_supported_models):
2822 """Verify 11ax SoftAp if devices support it.
2823
2824 Check if both DUT and DUT client supports 11ax, then SoftAp turns on
2825 with 11ax mode and DUT client can connect to it.
2826
2827 Args:
2828 dut: Softap device.
2829 dut_client: Client connecting to softap.
2830 wifi6_supported_models: List of device models supporting 11ax.
2831 """
2832 if dut.model in wifi6_supported_models and dut_client.model in wifi6_supported_models:
2833 logging.info(
2834 "Verifying 11ax softap. DUT model: %s, DUT Client model: %s",
2835 dut.model, dut_client.model)
2836 asserts.assert_true(
2837 dut_client.droid.wifiGetConnectionStandard() ==
2838 wifi_constants.WIFI_STANDARD_11AX,
2839 "DUT failed to start SoftAp in 11ax.")
“Alfie90ee7cb2021-04-20 23:16:12 +08002840
2841def check_available_channels_in_bands_2_5(dut, country_code):
2842 """Check if DUT is capable of enable BridgedAp.
2843 #TODO: Find a way to make this function flexible by taking an argument.
2844
2845 Args:
2846 country_code: country code, e.g., 'US', 'JP'.
2847 Returns:
2848 True: If DUT is capable of enable BridgedAp.
2849 False: If DUT is not capable of enable BridgedAp.
2850 """
2851 set_wifi_country_code(dut, country_code)
2852 country = dut.droid.wifiGetCountryCode()
2853 dut.log.info("DUT current country code : {}".format(country))
2854 # Wi-Fi ON and OFF to make sure country code take effet.
2855 wifi_toggle_state(dut, True)
2856 wifi_toggle_state(dut, False)
2857
2858 # Register SoftAp Callback and get SoftAp capability.
2859 callbackId = dut.droid.registerSoftApCallback()
2860 capability = get_current_softap_capability(dut, callbackId, True)
2861 dut.droid.unregisterSoftApCallback(callbackId)
2862
2863 if capability[wifi_constants.
2864 SOFTAP_CAPABILITY_24GHZ_SUPPORTED_CHANNEL_LIST] and \
2865 capability[wifi_constants.
2866 SOFTAP_CAPABILITY_5GHZ_SUPPORTED_CHANNEL_LIST]:
2867 return True
2868 return False
2869
2870
2871@retry(tries=5, delay=2)
2872def validate_ping_between_two_clients(dut1, dut2):
2873 """Make 2 DUT ping each other.
2874
2875 Args:
2876 dut1: An AndroidDevice object.
2877 dut2: An AndroidDevice object.
2878 """
2879 # Get DUTs' IPv4 addresses.
2880 dut1_ip = ""
2881 dut2_ip = ""
2882 try:
2883 dut1_ip = dut1.droid.connectivityGetIPv4Addresses('wlan0')[0]
2884 except IndexError as e:
2885 dut1.log.info(
2886 "{} has no Wi-Fi connection, cannot get IPv4 address."
2887 .format(dut1.serial))
2888 try:
2889 dut2_ip = dut2.droid.connectivityGetIPv4Addresses('wlan0')[0]
2890 except IndexError as e:
2891 dut2.log.info(
2892 "{} has no Wi-Fi connection, cannot get IPv4 address."
2893 .format(dut2.serial))
2894 # Test fail if not able to obtain two DUT's IPv4 addresses.
2895 asserts.assert_true(dut1_ip and dut2_ip,
2896 "Ping failed because no DUT's IPv4 address")
2897
2898 dut1.log.info("{} IPv4 addresses : {}".format(dut1.serial, dut1_ip))
2899 dut2.log.info("{} IPv4 addresses : {}".format(dut2.serial, dut2_ip))
2900
2901 # Two clients ping each other
2902 dut1.log.info("{} ping {}".format(dut1_ip, dut2_ip))
2903 asserts.assert_true(
2904 utils.adb_shell_ping(dut1, count=10, dest_ip=dut2_ip,
2905 timeout=20),
2906 "%s ping %s failed" % (dut1.serial, dut2_ip))
2907
2908 dut2.log.info("{} ping {}".format(dut2_ip, dut1_ip))
2909 asserts.assert_true(
2910 utils.adb_shell_ping(dut2, count=10, dest_ip=dut1_ip,
2911 timeout=20),
2912 "%s ping %s failed" % (dut2.serial, dut1_ip))
2913