blob: 670adf00ae2af01ae39b845c685607bf34047260 [file] [log] [blame]
Mark De Ruyter1a7ae572018-03-02 15:35:36 -08001#!/usr/bin/env python3
Ang Li73697b32015-12-03 00:41:53 +00002#
tturney1bdf77d2015-12-28 17:46:13 -08003# Copyright 2016 Google, Inc.
Ang Li73697b32015-12-03 00:41:53 +00004#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
Ang Li5bd83f32016-05-23 14:39:38 -070017import logging
Girish Moturucf4dccd2018-08-27 12:22:00 -070018import os
James Mattis5a5dd492020-05-14 13:09:43 -070019import re
xianyuanjia0431ba32018-12-14 09:56:42 -080020import shutil
Girish Moturucf4dccd2018-08-27 12:22:00 -070021import time
Ang Li73697b32015-12-03 00:41:53 +000022
David Sue4cd9c22019-03-26 18:07:26 -070023from collections import namedtuple
Ang Li73697b32015-12-03 00:41:53 +000024from enum import IntEnum
25from queue import Empty
26
Ang Li82522812016-06-02 13:57:21 -070027from acts import asserts
Xianyuan Jia0e39e552019-01-24 17:17:47 -080028from acts import context
Ang Li374d7602016-02-08 17:27:27 -080029from acts import signals
Ang Lifee28402016-07-13 13:43:29 -070030from acts import utils
Ang Li2d3fe982016-06-08 10:00:43 -070031from acts.controllers import attenuator
Bindu Mahadev7e5dc682019-02-01 16:53:34 -080032from acts.controllers.ap_lib import hostapd_security
33from acts.controllers.ap_lib import hostapd_ap_preset
Girish Moturucf4dccd2018-08-27 12:22:00 -070034from acts.controllers.ap_lib.hostapd_constants import BAND_2G
35from acts.controllers.ap_lib.hostapd_constants import BAND_5G
Roshan Pius5fd42eb2021-01-21 12:26:31 -080036from acts_contrib.test_utils.net import connectivity_const as cconsts
Xianyuan Jia63751fb2020-11-17 00:07:40 +000037from acts_contrib.test_utils.tel import tel_defines
Roshan Pius5fd42eb2021-01-21 12:26:31 -080038from acts_contrib.test_utils.wifi import wifi_constants
39from acts_contrib.test_utils.wifi.aware import aware_test_utils as autils
Ang Li73697b32015-12-03 00:41:53 +000040
Bindu Mahadev1d3991e2017-03-20 18:06:54 -070041# Default timeout used for reboot, toggle WiFi and Airplane mode,
42# for the system to settle down after the operation.
43DEFAULT_TIMEOUT = 10
Ang Li73697b32015-12-03 00:41:53 +000044# Number of seconds to wait for events that are supposed to happen quickly.
45# Like onSuccess for start background scan and confirmation on wifi state
46# change.
47SHORT_TIMEOUT = 30
Bindu Mahadev7060a9f2018-05-04 13:48:12 -070048ROAMING_TIMEOUT = 30
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -080049WIFI_CONNECTION_TIMEOUT_DEFAULT = 30
Ang Li73697b32015-12-03 00:41:53 +000050# Speed of light in m/s.
51SPEED_OF_LIGHT = 299792458
52
Qi Jiang8b443672018-03-16 14:46:50 -070053DEFAULT_PING_ADDR = "https://www.google.com/robots.txt"
Ang Li73697b32015-12-03 00:41:53 +000054
Girish Moturuddc0d382020-08-24 12:08:41 -070055CNSS_DIAG_CONFIG_PATH = "/data/vendor/wifi/cnss_diag/"
56CNSS_DIAG_CONFIG_FILE = "cnss_diag.conf"
57
Girish Moturu36348a32019-12-10 08:41:54 -080058ROAMING_ATTN = {
Omar El Ayach8c017902020-10-18 10:26:57 -070059 "AP1_on_AP2_off": [0, 0, 95, 95],
60 "AP1_off_AP2_on": [95, 95, 0, 0],
61 "default": [0, 0, 0, 0]
62}
Ang Li82522812016-06-02 13:57:21 -070063
Xianyuan Jia0e39e552019-01-24 17:17:47 -080064
Ang Li73697b32015-12-03 00:41:53 +000065class WifiEnums():
66
Omar El Ayach8c017902020-10-18 10:26:57 -070067 SSID_KEY = "SSID" # Used for Wifi & SoftAp
Roshan Piusc999e5e2018-11-09 10:59:52 -080068 SSID_PATTERN_KEY = "ssidPattern"
Bindu Mahadev4c94b532019-01-09 12:20:10 -080069 NETID_KEY = "network_id"
Omar El Ayach8c017902020-10-18 10:26:57 -070070 BSSID_KEY = "BSSID" # Used for Wifi & SoftAp
Roshan Piusc999e5e2018-11-09 10:59:52 -080071 BSSID_PATTERN_KEY = "bssidPattern"
Omar El Ayach8c017902020-10-18 10:26:57 -070072 PWD_KEY = "password" # Used for Wifi & SoftAp
Ang Li73697b32015-12-03 00:41:53 +000073 frequency_key = "frequency"
Omar El Ayach8c017902020-10-18 10:26:57 -070074 HIDDEN_KEY = "hiddenSSID" # Used for Wifi & SoftAp
Roshan Piusd1204442018-11-12 12:20:39 -080075 IS_APP_INTERACTION_REQUIRED = "isAppInteractionRequired"
76 IS_USER_INTERACTION_REQUIRED = "isUserInteractionRequired"
Roshan Pius55fb7c42020-04-03 14:47:18 -070077 IS_SUGGESTION_METERED = "isMetered"
Roshan Piusd1204442018-11-12 12:20:39 -080078 PRIORITY = "priority"
Omar El Ayach8c017902020-10-18 10:26:57 -070079 SECURITY = "security" # Used for Wifi & SoftAp
Ang Li73697b32015-12-03 00:41:53 +000080
leslce9cf6d2020-02-19 16:37:07 +080081 # Used for SoftAp
lesl6d30a172020-03-05 15:05:22 +080082 AP_BAND_KEY = "apBand"
83 AP_CHANNEL_KEY = "apChannel"
lesl67124362021-05-04 19:33:14 +080084 AP_BANDS_KEY = "apBands"
85 AP_CHANNEL_FREQUENCYS_KEY = "apChannelFrequencies"
86 AP_MAC_RANDOMIZATION_SETTING_KEY = "MacRandomizationSetting"
87 AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY = "BridgedModeOpportunisticShutdownEnabled"
88 AP_IEEE80211AX_ENABLED_KEY = "Ieee80211axEnabled"
lesl6d30a172020-03-05 15:05:22 +080089 AP_MAXCLIENTS_KEY = "MaxNumberOfClients"
90 AP_SHUTDOWNTIMEOUT_KEY = "ShutdownTimeoutMillis"
91 AP_SHUTDOWNTIMEOUTENABLE_KEY = "AutoShutdownEnabled"
92 AP_CLIENTCONTROL_KEY = "ClientControlByUserEnabled"
93 AP_ALLOWEDLIST_KEY = "AllowedClientList"
94 AP_BLOCKEDLIST_KEY = "BlockedClientList"
95
leslce9cf6d2020-02-19 16:37:07 +080096 WIFI_CONFIG_SOFTAP_BAND_2G = 1
97 WIFI_CONFIG_SOFTAP_BAND_5G = 2
98 WIFI_CONFIG_SOFTAP_BAND_2G_5G = 3
99 WIFI_CONFIG_SOFTAP_BAND_6G = 4
100 WIFI_CONFIG_SOFTAP_BAND_2G_6G = 5
101 WIFI_CONFIG_SOFTAP_BAND_5G_6G = 6
102 WIFI_CONFIG_SOFTAP_BAND_ANY = 7
103
104 # DO NOT USE IT for new test case! Replaced by WIFI_CONFIG_SOFTAP_BAND_
105 WIFI_CONFIG_APBAND_2G = WIFI_CONFIG_SOFTAP_BAND_2G
106 WIFI_CONFIG_APBAND_5G = WIFI_CONFIG_SOFTAP_BAND_5G
107 WIFI_CONFIG_APBAND_AUTO = WIFI_CONFIG_SOFTAP_BAND_2G_5G
108
109 WIFI_CONFIG_APBAND_2G_OLD = 0
110 WIFI_CONFIG_APBAND_5G_OLD = 1
111 WIFI_CONFIG_APBAND_AUTO_OLD = -1
Ang Li73697b32015-12-03 00:41:53 +0000112
Ang Li82522812016-06-02 13:57:21 -0700113 WIFI_WPS_INFO_PBC = 0
114 WIFI_WPS_INFO_DISPLAY = 1
115 WIFI_WPS_INFO_KEYPAD = 2
116 WIFI_WPS_INFO_LABEL = 3
117 WIFI_WPS_INFO_INVALID = 4
Ang Li73697b32015-12-03 00:41:53 +0000118
lesl6d30a172020-03-05 15:05:22 +0800119 class SoftApSecurityType():
120 OPEN = "NONE"
121 WPA2 = "WPA2_PSK"
122 WPA3_SAE_TRANSITION = "WPA3_SAE_TRANSITION"
123 WPA3_SAE = "WPA3_SAE"
124
Ang Li73697b32015-12-03 00:41:53 +0000125 class CountryCode():
Girish Moturue648b6a2021-03-04 13:52:15 -0800126 AUSTRALIA = "AU"
Ang Li73697b32015-12-03 00:41:53 +0000127 CHINA = "CN"
Girish Moturua5ef35d2020-10-19 14:58:01 -0700128 GERMANY = "DE"
Ang Li73697b32015-12-03 00:41:53 +0000129 JAPAN = "JP"
130 UK = "GB"
131 US = "US"
132 UNKNOWN = "UNKNOWN"
133
134 # Start of Macros for EAP
135 # EAP types
136 class Eap(IntEnum):
137 NONE = -1
138 PEAP = 0
Ang Li82522812016-06-02 13:57:21 -0700139 TLS = 1
Ang Li73697b32015-12-03 00:41:53 +0000140 TTLS = 2
Ang Li82522812016-06-02 13:57:21 -0700141 PWD = 3
142 SIM = 4
143 AKA = 5
144 AKA_PRIME = 6
145 UNAUTH_TLS = 7
Ang Li73697b32015-12-03 00:41:53 +0000146
147 # EAP Phase2 types
148 class EapPhase2(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700149 NONE = 0
150 PAP = 1
151 MSCHAP = 2
152 MSCHAPV2 = 3
153 GTC = 4
Ang Li73697b32015-12-03 00:41:53 +0000154
155 class Enterprise:
Ang Li82522812016-06-02 13:57:21 -0700156 # Enterprise Config Macros
157 EMPTY_VALUE = "NULL"
158 EAP = "eap"
159 PHASE2 = "phase2"
160 IDENTITY = "identity"
161 ANON_IDENTITY = "anonymous_identity"
162 PASSWORD = "password"
163 SUBJECT_MATCH = "subject_match"
Ang Li73697b32015-12-03 00:41:53 +0000164 ALTSUBJECT_MATCH = "altsubject_match"
165 DOM_SUFFIX_MATCH = "domain_suffix_match"
Ang Li82522812016-06-02 13:57:21 -0700166 CLIENT_CERT = "client_cert"
167 CA_CERT = "ca_cert"
168 ENGINE = "engine"
169 ENGINE_ID = "engine_id"
170 PRIVATE_KEY_ID = "key_id"
171 REALM = "realm"
172 PLMN = "plmn"
173 FQDN = "FQDN"
174 FRIENDLY_NAME = "providerFriendlyName"
175 ROAMING_IDS = "roamingConsortiumIds"
Jimmy Chen7baec622020-06-23 19:00:33 +0800176 OCSP = "ocsp"
Omar El Ayach8c017902020-10-18 10:26:57 -0700177
Ang Li73697b32015-12-03 00:41:53 +0000178 # End of Macros for EAP
179
180 # Macros for wifi p2p.
181 WIFI_P2P_SERVICE_TYPE_ALL = 0
182 WIFI_P2P_SERVICE_TYPE_BONJOUR = 1
183 WIFI_P2P_SERVICE_TYPE_UPNP = 2
184 WIFI_P2P_SERVICE_TYPE_VENDOR_SPECIFIC = 255
185
186 class ScanResult:
187 CHANNEL_WIDTH_20MHZ = 0
188 CHANNEL_WIDTH_40MHZ = 1
189 CHANNEL_WIDTH_80MHZ = 2
190 CHANNEL_WIDTH_160MHZ = 3
191 CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4
192
193 # Macros for wifi rtt.
194 class RttType(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700195 TYPE_ONE_SIDED = 1
196 TYPE_TWO_SIDED = 2
Ang Li73697b32015-12-03 00:41:53 +0000197
198 class RttPeerType(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700199 PEER_TYPE_AP = 1
200 PEER_TYPE_STA = 2 # Requires NAN.
201 PEER_P2P_GO = 3
202 PEER_P2P_CLIENT = 4
203 PEER_NAN = 5
Ang Li73697b32015-12-03 00:41:53 +0000204
205 class RttPreamble(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700206 PREAMBLE_LEGACY = 0x01
207 PREAMBLE_HT = 0x02
208 PREAMBLE_VHT = 0x04
Ang Li73697b32015-12-03 00:41:53 +0000209
210 class RttBW(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700211 BW_5_SUPPORT = 0x01
212 BW_10_SUPPORT = 0x02
213 BW_20_SUPPORT = 0x04
214 BW_40_SUPPORT = 0x08
215 BW_80_SUPPORT = 0x10
Ang Li73697b32015-12-03 00:41:53 +0000216 BW_160_SUPPORT = 0x20
217
218 class Rtt(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700219 STATUS_SUCCESS = 0
220 STATUS_FAILURE = 1
221 STATUS_FAIL_NO_RSP = 2
222 STATUS_FAIL_REJECTED = 3
223 STATUS_FAIL_NOT_SCHEDULED_YET = 4
224 STATUS_FAIL_TM_TIMEOUT = 5
225 STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6
226 STATUS_FAIL_NO_CAPABILITY = 7
227 STATUS_ABORTED = 8
228 STATUS_FAIL_INVALID_TS = 9
229 STATUS_FAIL_PROTOCOL = 10
230 STATUS_FAIL_SCHEDULE = 11
231 STATUS_FAIL_BUSY_TRY_LATER = 12
232 STATUS_INVALID_REQ = 13
233 STATUS_NO_WIFI = 14
234 STATUS_FAIL_FTM_PARAM_OVERRIDE = 15
Ang Li73697b32015-12-03 00:41:53 +0000235
Ang Li82522812016-06-02 13:57:21 -0700236 REASON_UNSPECIFIED = -1
237 REASON_NOT_AVAILABLE = -2
238 REASON_INVALID_LISTENER = -3
239 REASON_INVALID_REQUEST = -4
Ang Li73697b32015-12-03 00:41:53 +0000240
241 class RttParam:
242 device_type = "deviceType"
243 request_type = "requestType"
244 BSSID = "bssid"
245 channel_width = "channelWidth"
246 frequency = "frequency"
247 center_freq0 = "centerFreq0"
248 center_freq1 = "centerFreq1"
249 number_burst = "numberBurst"
250 interval = "interval"
251 num_samples_per_burst = "numSamplesPerBurst"
252 num_retries_per_measurement_frame = "numRetriesPerMeasurementFrame"
253 num_retries_per_FTMR = "numRetriesPerFTMR"
254 lci_request = "LCIRequest"
255 lcr_request = "LCRRequest"
256 burst_timeout = "burstTimeout"
257 preamble = "preamble"
258 bandwidth = "bandwidth"
259 margin = "margin"
260
261 RTT_MARGIN_OF_ERROR = {
262 RttBW.BW_80_SUPPORT: 2,
263 RttBW.BW_40_SUPPORT: 5,
264 RttBW.BW_20_SUPPORT: 5
265 }
266
267 # Macros as specified in the WifiScanner code.
Ang Li82522812016-06-02 13:57:21 -0700268 WIFI_BAND_UNSPECIFIED = 0 # not specified
269 WIFI_BAND_24_GHZ = 1 # 2.4 GHz band
270 WIFI_BAND_5_GHZ = 2 # 5 GHz band without DFS channels
271 WIFI_BAND_5_GHZ_DFS_ONLY = 4 # 5 GHz band with DFS channels
272 WIFI_BAND_5_GHZ_WITH_DFS = 6 # 5 GHz band with DFS channels
273 WIFI_BAND_BOTH = 3 # both bands without DFS channels
274 WIFI_BAND_BOTH_WITH_DFS = 7 # both bands with DFS channels
Ang Li73697b32015-12-03 00:41:53 +0000275
276 REPORT_EVENT_AFTER_BUFFER_FULL = 0
277 REPORT_EVENT_AFTER_EACH_SCAN = 1
278 REPORT_EVENT_FULL_SCAN_RESULT = 2
279
xshuaabcfeb2018-02-14 11:43:24 -0800280 SCAN_TYPE_LOW_LATENCY = 0
281 SCAN_TYPE_LOW_POWER = 1
282 SCAN_TYPE_HIGH_ACCURACY = 2
283
Ang Li73697b32015-12-03 00:41:53 +0000284 # US Wifi frequencies
Omar El Ayach8c017902020-10-18 10:26:57 -0700285 ALL_2G_FREQUENCIES = [
286 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462
287 ]
288 DFS_5G_FREQUENCIES = [
289 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640,
290 5660, 5680, 5700, 5720
291 ]
292 NONE_DFS_5G_FREQUENCIES = [
293 5180, 5200, 5220, 5240, 5745, 5765, 5785, 5805, 5825
294 ]
Ang Li73697b32015-12-03 00:41:53 +0000295 ALL_5G_FREQUENCIES = DFS_5G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES
296
297 band_to_frequencies = {
Ang Li82522812016-06-02 13:57:21 -0700298 WIFI_BAND_24_GHZ: ALL_2G_FREQUENCIES,
299 WIFI_BAND_5_GHZ: NONE_DFS_5G_FREQUENCIES,
300 WIFI_BAND_5_GHZ_DFS_ONLY: DFS_5G_FREQUENCIES,
301 WIFI_BAND_5_GHZ_WITH_DFS: ALL_5G_FREQUENCIES,
302 WIFI_BAND_BOTH: ALL_2G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES,
303 WIFI_BAND_BOTH_WITH_DFS: ALL_5G_FREQUENCIES + ALL_2G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000304 }
305
306 # All Wifi frequencies to channels lookup.
307 freq_to_channel = {
308 2412: 1,
309 2417: 2,
310 2422: 3,
311 2427: 4,
312 2432: 5,
313 2437: 6,
314 2442: 7,
315 2447: 8,
316 2452: 9,
317 2457: 10,
318 2462: 11,
319 2467: 12,
320 2472: 13,
321 2484: 14,
322 4915: 183,
323 4920: 184,
324 4925: 185,
325 4935: 187,
326 4940: 188,
327 4945: 189,
328 4960: 192,
329 4980: 196,
330 5035: 7,
331 5040: 8,
332 5045: 9,
333 5055: 11,
334 5060: 12,
335 5080: 16,
336 5170: 34,
337 5180: 36,
338 5190: 38,
339 5200: 40,
340 5210: 42,
341 5220: 44,
342 5230: 46,
343 5240: 48,
344 5260: 52,
345 5280: 56,
346 5300: 60,
347 5320: 64,
348 5500: 100,
349 5520: 104,
350 5540: 108,
351 5560: 112,
352 5580: 116,
353 5600: 120,
354 5620: 124,
355 5640: 128,
356 5660: 132,
357 5680: 136,
358 5700: 140,
359 5745: 149,
360 5765: 153,
361 5785: 157,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700362 5795: 159,
Ang Li73697b32015-12-03 00:41:53 +0000363 5805: 161,
364 5825: 165,
365 }
366
367 # All Wifi channels to frequencies lookup.
368 channel_2G_to_freq = {
369 1: 2412,
370 2: 2417,
371 3: 2422,
372 4: 2427,
373 5: 2432,
374 6: 2437,
375 7: 2442,
376 8: 2447,
377 9: 2452,
378 10: 2457,
379 11: 2462,
380 12: 2467,
381 13: 2472,
382 14: 2484
383 }
384
385 channel_5G_to_freq = {
386 183: 4915,
387 184: 4920,
388 185: 4925,
389 187: 4935,
390 188: 4940,
391 189: 4945,
392 192: 4960,
393 196: 4980,
394 7: 5035,
395 8: 5040,
396 9: 5045,
397 11: 5055,
398 12: 5060,
399 16: 5080,
400 34: 5170,
401 36: 5180,
402 38: 5190,
403 40: 5200,
404 42: 5210,
405 44: 5220,
406 46: 5230,
407 48: 5240,
Omar El Ayach8c017902020-10-18 10:26:57 -0700408 50: 5250,
Ang Li73697b32015-12-03 00:41:53 +0000409 52: 5260,
410 56: 5280,
411 60: 5300,
412 64: 5320,
413 100: 5500,
414 104: 5520,
415 108: 5540,
416 112: 5560,
417 116: 5580,
418 120: 5600,
419 124: 5620,
420 128: 5640,
421 132: 5660,
422 136: 5680,
423 140: 5700,
424 149: 5745,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700425 151: 5755,
Ang Li73697b32015-12-03 00:41:53 +0000426 153: 5765,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700427 155: 5775,
Ang Li73697b32015-12-03 00:41:53 +0000428 157: 5785,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700429 159: 5795,
Ang Li73697b32015-12-03 00:41:53 +0000430 161: 5805,
431 165: 5825
432 }
433
Ang Li82522812016-06-02 13:57:21 -0700434
Ang Li73697b32015-12-03 00:41:53 +0000435class WifiChannelBase:
436 ALL_2G_FREQUENCIES = []
437 DFS_5G_FREQUENCIES = []
438 NONE_DFS_5G_FREQUENCIES = []
439 ALL_5G_FREQUENCIES = DFS_5G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES
440 MIX_CHANNEL_SCAN = []
441
442 def band_to_freq(self, band):
443 _band_to_frequencies = {
Omar El Ayach8c017902020-10-18 10:26:57 -0700444 WifiEnums.WIFI_BAND_24_GHZ:
445 self.ALL_2G_FREQUENCIES,
446 WifiEnums.WIFI_BAND_5_GHZ:
447 self.NONE_DFS_5G_FREQUENCIES,
448 WifiEnums.WIFI_BAND_5_GHZ_DFS_ONLY:
449 self.DFS_5G_FREQUENCIES,
450 WifiEnums.WIFI_BAND_5_GHZ_WITH_DFS:
451 self.ALL_5G_FREQUENCIES,
Ang Li82522812016-06-02 13:57:21 -0700452 WifiEnums.WIFI_BAND_BOTH:
453 self.ALL_2G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES,
454 WifiEnums.WIFI_BAND_BOTH_WITH_DFS:
455 self.ALL_5G_FREQUENCIES + self.ALL_2G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000456 }
457 return _band_to_frequencies[band]
458
Ang Li82522812016-06-02 13:57:21 -0700459
Ang Li73697b32015-12-03 00:41:53 +0000460class WifiChannelUS(WifiChannelBase):
461 # US Wifi frequencies
Omar El Ayach8c017902020-10-18 10:26:57 -0700462 ALL_2G_FREQUENCIES = [
463 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462
464 ]
465 NONE_DFS_5G_FREQUENCIES = [
466 5180, 5200, 5220, 5240, 5745, 5765, 5785, 5805, 5825
467 ]
468 MIX_CHANNEL_SCAN = [
469 2412, 2437, 2462, 5180, 5200, 5280, 5260, 5300, 5500, 5320, 5520, 5560,
470 5700, 5745, 5805
471 ]
Ang Li73697b32015-12-03 00:41:53 +0000472
473 def __init__(self, model=None):
Omar El Ayach8c017902020-10-18 10:26:57 -0700474 self.DFS_5G_FREQUENCIES = [
475 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620,
476 5640, 5660, 5680, 5700, 5720
477 ]
Girish Moturu0c567b02017-08-11 16:20:01 -0700478 self.ALL_5G_FREQUENCIES = self.DFS_5G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000479
Bindu Mahadevff295782019-02-08 16:17:48 -0800480
Girish Moturuf02fa1d2017-05-21 09:51:23 +0530481class WifiReferenceNetworks:
482 """ Class to parse and return networks of different band and
483 auth type from reference_networks
484 """
485 def __init__(self, obj):
486 self.reference_networks = obj
487 self.WIFI_2G = "2g"
488 self.WIFI_5G = "5g"
489
490 self.secure_networks_2g = []
491 self.secure_networks_5g = []
492 self.open_networks_2g = []
493 self.open_networks_5g = []
494 self._parse_networks()
495
496 def _parse_networks(self):
497 for network in self.reference_networks:
498 for key in network:
499 if key == self.WIFI_2G:
500 if "password" in network[key]:
501 self.secure_networks_2g.append(network[key])
502 else:
503 self.open_networks_2g.append(network[key])
504 else:
505 if "password" in network[key]:
506 self.secure_networks_5g.append(network[key])
507 else:
508 self.open_networks_5g.append(network[key])
509
510 def return_2g_secure_networks(self):
511 return self.secure_networks_2g
512
513 def return_5g_secure_networks(self):
514 return self.secure_networks_5g
515
516 def return_2g_open_networks(self):
517 return self.open_networks_2g
518
519 def return_5g_open_networks(self):
520 return self.open_networks_5g
521
522 def return_secure_networks(self):
523 return self.secure_networks_2g + self.secure_networks_5g
524
525 def return_open_networks(self):
526 return self.open_networks_2g + self.open_networks_5g
527
Ang Li82522812016-06-02 13:57:21 -0700528
529def _assert_on_fail_handler(func, assert_on_fail, *args, **kwargs):
530 """Wrapper function that handles the bahevior of assert_on_fail.
531
532 When assert_on_fail is True, let all test signals through, which can
533 terminate test cases directly. When assert_on_fail is False, the wrapper
534 raises no test signals and reports operation status by returning True or
535 False.
536
537 Args:
538 func: The function to wrap. This function reports operation status by
539 raising test signals.
540 assert_on_fail: A boolean that specifies if the output of the wrapper
541 is test signal based or return value based.
542 args: Positional args for func.
543 kwargs: Name args for func.
544
545 Returns:
546 If assert_on_fail is True, returns True/False to signal operation
547 status, otherwise return nothing.
548 """
549 try:
550 func(*args, **kwargs)
551 if not assert_on_fail:
552 return True
553 except signals.TestSignal:
554 if assert_on_fail:
555 raise
556 return False
557
558
559def assert_network_in_list(target, network_list):
560 """Makes sure a specified target Wi-Fi network exists in a list of Wi-Fi
561 networks.
562
563 Args:
564 target: A dict representing a Wi-Fi network.
565 E.g. {WifiEnums.SSID_KEY: "SomeNetwork"}
566 network_list: A list of dicts, each representing a Wi-Fi network.
567 """
568 match_results = match_networks(target, network_list)
569 asserts.assert_true(
570 match_results, "Target network %s, does not exist in network list %s" %
571 (target, network_list))
572
573
Ang Li73697b32015-12-03 00:41:53 +0000574def match_networks(target_params, networks):
575 """Finds the WiFi networks that match a given set of parameters in a list
576 of WiFi networks.
577
Girish Moturubc48d9f2016-11-01 13:24:14 -0700578 To be considered a match, the network should contain every key-value pair
579 of target_params
Ang Li73697b32015-12-03 00:41:53 +0000580
581 Args:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700582 target_params: A dict with 1 or more key-value pairs representing a Wi-Fi network.
583 E.g { 'SSID': 'wh_ap1_5g', 'BSSID': '30:b5:c2:33:e4:47' }
Ang Li73697b32015-12-03 00:41:53 +0000584 networks: A list of dict objects representing WiFi networks.
585
586 Returns:
587 The networks that match the target parameters.
588 """
589 results = []
Betty Zhou3caa0982017-02-22 19:26:20 -0800590 asserts.assert_true(target_params,
591 "Expected networks object 'target_params' is empty")
Ang Li73697b32015-12-03 00:41:53 +0000592 for n in networks:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700593 add_network = 1
Ang Li9a66de72016-02-08 15:26:38 -0800594 for k, v in target_params.items():
595 if k not in n:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700596 add_network = 0
597 break
Ang Li9a66de72016-02-08 15:26:38 -0800598 if n[k] != v:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700599 add_network = 0
600 break
601 if add_network:
Ang Li73697b32015-12-03 00:41:53 +0000602 results.append(n)
603 return results
604
Bindu Mahadevff295782019-02-08 16:17:48 -0800605
Roshan Pius93b519c2018-05-09 12:07:11 -0700606def wait_for_wifi_state(ad, state, assert_on_fail=True):
607 """Waits for the device to transition to the specified wifi state
608
609 Args:
610 ad: An AndroidDevice object.
611 state: Wifi state to wait for.
612 assert_on_fail: If True, error checks in this function will raise test
613 failure signals.
614
615 Returns:
616 If assert_on_fail is False, function returns True if the device transitions
617 to the specified state, False otherwise. If assert_on_fail is True, no return value.
618 """
Omar El Ayach8c017902020-10-18 10:26:57 -0700619 return _assert_on_fail_handler(_wait_for_wifi_state,
620 assert_on_fail,
621 ad,
622 state=state)
Roshan Pius93b519c2018-05-09 12:07:11 -0700623
624
625def _wait_for_wifi_state(ad, state):
626 """Toggles the state of wifi.
627
628 TestFailure signals are raised when something goes wrong.
629
630 Args:
631 ad: An AndroidDevice object.
632 state: Wifi state to wait for.
633 """
634 if state == ad.droid.wifiCheckState():
635 # Check if the state is already achieved, so we don't wait for the
636 # state change event by mistake.
637 return
638 ad.droid.wifiStartTrackingStateChange()
Omar El Ayach8c017902020-10-18 10:26:57 -0700639 fail_msg = "Device did not transition to Wi-Fi state to %s on %s." % (
640 state, ad.serial)
Roshan Pius93b519c2018-05-09 12:07:11 -0700641 try:
642 ad.ed.wait_for_event(wifi_constants.WIFI_STATE_CHANGED,
643 lambda x: x["data"]["enabled"] == state,
644 SHORT_TIMEOUT)
645 except Empty:
646 asserts.assert_equal(state, ad.droid.wifiCheckState(), fail_msg)
647 finally:
648 ad.droid.wifiStopTrackingStateChange()
Ang Li82522812016-06-02 13:57:21 -0700649
Bindu Mahadevff295782019-02-08 16:17:48 -0800650
Ang Li82522812016-06-02 13:57:21 -0700651def wifi_toggle_state(ad, new_state=None, assert_on_fail=True):
Ang Li6b557182015-11-11 17:19:17 -0800652 """Toggles the state of wifi.
Ang Li73697b32015-12-03 00:41:53 +0000653
Ang Li6b557182015-11-11 17:19:17 -0800654 Args:
655 ad: An AndroidDevice object.
656 new_state: Wifi state to set to. If None, opposite of the current state.
Ang Li82522812016-06-02 13:57:21 -0700657 assert_on_fail: If True, error checks in this function will raise test
658 failure signals.
Ang Li73697b32015-12-03 00:41:53 +0000659
Ang Li6b557182015-11-11 17:19:17 -0800660 Returns:
Ang Li82522812016-06-02 13:57:21 -0700661 If assert_on_fail is False, function returns True if the toggle was
662 successful, False otherwise. If assert_on_fail is True, no return value.
663 """
Omar El Ayach8c017902020-10-18 10:26:57 -0700664 return _assert_on_fail_handler(_wifi_toggle_state,
665 assert_on_fail,
666 ad,
667 new_state=new_state)
Ang Li82522812016-06-02 13:57:21 -0700668
669
670def _wifi_toggle_state(ad, new_state=None):
671 """Toggles the state of wifi.
672
673 TestFailure signals are raised when something goes wrong.
674
675 Args:
676 ad: An AndroidDevice object.
677 new_state: The state to set Wi-Fi to. If None, opposite of the current
678 state will be set.
Ang Li6b557182015-11-11 17:19:17 -0800679 """
Ang Li31b00782016-06-21 13:04:23 -0700680 if new_state is None:
681 new_state = not ad.droid.wifiCheckState()
Ang Lie5c85c92016-07-27 15:38:09 -0700682 elif new_state == ad.droid.wifiCheckState():
683 # Check if the new_state is already achieved, so we don't wait for the
684 # state change event by mistake.
685 return
686 ad.droid.wifiStartTrackingStateChange()
Ang Li31b00782016-06-21 13:04:23 -0700687 ad.log.info("Setting Wi-Fi state to %s.", new_state)
Roshan Pius5a027fa2018-05-04 13:59:38 -0700688 ad.ed.clear_all_events()
Ang Li31b00782016-06-21 13:04:23 -0700689 # Setting wifi state.
Ang Li6b557182015-11-11 17:19:17 -0800690 ad.droid.wifiToggleState(new_state)
Jaineel3bd9bea2019-12-13 12:44:17 -0800691 time.sleep(2)
Ang Lie2e93a22016-06-22 16:43:28 -0700692 fail_msg = "Failed to set Wi-Fi state to %s on %s." % (new_state,
693 ad.serial)
Ang Li73697b32015-12-03 00:41:53 +0000694 try:
Roshan Pius5a027fa2018-05-04 13:59:38 -0700695 ad.ed.wait_for_event(wifi_constants.WIFI_STATE_CHANGED,
696 lambda x: x["data"]["enabled"] == new_state,
697 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +0000698 except Empty:
Ang Li82522812016-06-02 13:57:21 -0700699 asserts.assert_equal(new_state, ad.droid.wifiCheckState(), fail_msg)
Ang Li6b557182015-11-11 17:19:17 -0800700 finally:
701 ad.droid.wifiStopTrackingStateChange()
702
Ang Li82522812016-06-02 13:57:21 -0700703
Ang Li6b557182015-11-11 17:19:17 -0800704def reset_wifi(ad):
Ang Li1179fa72016-06-16 09:44:06 -0700705 """Clears all saved Wi-Fi networks on a device.
706
707 This will turn Wi-Fi on.
Ang Li6b557182015-11-11 17:19:17 -0800708
709 Args:
710 ad: An AndroidDevice object.
711
Ang Li6b557182015-11-11 17:19:17 -0800712 """
Ang Li6b557182015-11-11 17:19:17 -0800713 networks = ad.droid.wifiGetConfiguredNetworks()
714 if not networks:
715 return
716 for n in networks:
717 ad.droid.wifiForgetNetwork(n['networkId'])
718 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800719 event = ad.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS,
Ang Li82522812016-06-02 13:57:21 -0700720 SHORT_TIMEOUT)
Ang Li6b557182015-11-11 17:19:17 -0800721 except Empty:
Ang Li1179fa72016-06-16 09:44:06 -0700722 logging.warning("Could not confirm the removal of network %s.", n)
723 # Check again to see if there's any network left.
Betty Zhou3caa0982017-02-22 19:26:20 -0800724 asserts.assert_true(
725 not ad.droid.wifiGetConfiguredNetworks(),
726 "Failed to remove these configured Wi-Fi networks: %s" % networks)
Ang Li82522812016-06-02 13:57:21 -0700727
Ang Li73697b32015-12-03 00:41:53 +0000728
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700729def toggle_airplane_mode_on_and_off(ad):
730 """Turn ON and OFF Airplane mode.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800731
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700732 ad: An AndroidDevice object.
733 Returns: Assert if turning on/off Airplane mode fails.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800734
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700735 """
736 ad.log.debug("Toggling Airplane mode ON.")
Omar El Ayach8c017902020-10-18 10:26:57 -0700737 asserts.assert_true(utils.force_airplane_mode(ad, True),
738 "Can not turn on airplane mode on: %s" % ad.serial)
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700739 time.sleep(DEFAULT_TIMEOUT)
740 ad.log.debug("Toggling Airplane mode OFF.")
Omar El Ayach8c017902020-10-18 10:26:57 -0700741 asserts.assert_true(utils.force_airplane_mode(ad, False),
742 "Can not turn on airplane mode on: %s" % ad.serial)
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700743 time.sleep(DEFAULT_TIMEOUT)
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800744
745
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700746def toggle_wifi_off_and_on(ad):
747 """Turn OFF and ON WiFi.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800748
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700749 ad: An AndroidDevice object.
750 Returns: Assert if turning off/on WiFi fails.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800751
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700752 """
753 ad.log.debug("Toggling wifi OFF.")
754 wifi_toggle_state(ad, False)
755 time.sleep(DEFAULT_TIMEOUT)
756 ad.log.debug("Toggling wifi ON.")
757 wifi_toggle_state(ad, True)
758 time.sleep(DEFAULT_TIMEOUT)
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800759
760
Ang Li73697b32015-12-03 00:41:53 +0000761def wifi_forget_network(ad, net_ssid):
Ang Li8e767182015-12-09 17:29:24 -0800762 """Remove configured Wifi network on an android device.
Ang Li73697b32015-12-03 00:41:53 +0000763
Ang Li8e767182015-12-09 17:29:24 -0800764 Args:
765 ad: android_device object for forget network.
766 net_ssid: ssid of network to be forget
Ang Li73697b32015-12-03 00:41:53 +0000767
Ang Li8e767182015-12-09 17:29:24 -0800768 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700769 networks = ad.droid.wifiGetConfiguredNetworks()
Ang Li8e767182015-12-09 17:29:24 -0800770 if not networks:
771 return
772 for n in networks:
773 if net_ssid in n[WifiEnums.SSID_KEY]:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700774 ad.droid.wifiForgetNetwork(n['networkId'])
Ang Li8e767182015-12-09 17:29:24 -0800775 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800776 event = ad.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS,
Betty Zhou3caa0982017-02-22 19:26:20 -0800777 SHORT_TIMEOUT)
Ang Li8e767182015-12-09 17:29:24 -0800778 except Empty:
Girish Moturu1bf82302016-11-01 13:27:00 -0700779 asserts.fail("Failed to remove network %s." % n)
Jimmy Chen8e40e152021-05-06 14:37:18 +0800780 break
Ang Li73697b32015-12-03 00:41:53 +0000781
Ang Li82522812016-06-02 13:57:21 -0700782
Ang Li73697b32015-12-03 00:41:53 +0000783def wifi_test_device_init(ad):
784 """Initializes an android device for wifi testing.
785
786 0. Make sure SL4A connection is established on the android device.
787 1. Disable location service's WiFi scan.
788 2. Turn WiFi on.
789 3. Clear all saved networks.
790 4. Set country code to US.
791 5. Enable WiFi verbose logging.
792 6. Sync device time with computer time.
793 7. Turn off cellular data.
Ang Lifee28402016-07-13 13:43:29 -0700794 8. Turn off ambient display.
Ang Li73697b32015-12-03 00:41:53 +0000795 """
Ang Lifee28402016-07-13 13:43:29 -0700796 utils.require_sl4a((ad, ))
Ang Li73697b32015-12-03 00:41:53 +0000797 ad.droid.wifiScannerToggleAlwaysAvailable(False)
798 msg = "Failed to turn off location service's scan."
Ang Li82522812016-06-02 13:57:21 -0700799 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
800 wifi_toggle_state(ad, True)
Ang Li6b557182015-11-11 17:19:17 -0800801 reset_wifi(ad)
Ang Li73697b32015-12-03 00:41:53 +0000802 ad.droid.wifiEnableVerboseLogging(1)
Ang Li8e767182015-12-09 17:29:24 -0800803 msg = "Failed to enable WiFi verbose logging."
Ang Li82522812016-06-02 13:57:21 -0700804 asserts.assert_equal(ad.droid.wifiGetVerboseLoggingLevel(), 1, msg)
Ang Li73697b32015-12-03 00:41:53 +0000805 # We don't verify the following settings since they are not critical.
Ang Lie2e93a22016-06-22 16:43:28 -0700806 # Set wpa_supplicant log level to EXCESSIVE.
Omar El Ayach8c017902020-10-18 10:26:57 -0700807 output = ad.adb.shell(
808 "wpa_cli -i wlan0 -p -g@android:wpa_wlan0 IFNAME="
809 "wlan0 log_level EXCESSIVE",
810 ignore_status=True)
Ang Lie2e93a22016-06-22 16:43:28 -0700811 ad.log.info("wpa_supplicant log change status: %s", output)
Ang Lifee28402016-07-13 13:43:29 -0700812 utils.sync_device_time(ad)
Ang Li0bf8e022016-01-04 17:34:48 -0800813 ad.droid.telephonyToggleDataConnection(False)
Roshan Pius48df08c2019-09-13 08:07:30 -0700814 set_wifi_country_code(ad, WifiEnums.CountryCode.US)
Ang Lifee28402016-07-13 13:43:29 -0700815 utils.set_ambient_display(ad, False)
Ang Li73697b32015-12-03 00:41:53 +0000816
Omar El Ayach8c017902020-10-18 10:26:57 -0700817
Roshan Pius48df08c2019-09-13 08:07:30 -0700818def set_wifi_country_code(ad, country_code):
819 """Sets the wifi country code on the device.
820
821 Args:
822 ad: An AndroidDevice object.
823 country_code: 2 letter ISO country code
codycaldwell35b87182020-01-16 14:08:01 -0800824
825 Raises:
826 An RpcException if unable to set the country code.
Roshan Pius48df08c2019-09-13 08:07:30 -0700827 """
Jaineelc5b56a62019-10-10 17:12:02 -0700828 try:
codycaldwell35b87182020-01-16 14:08:01 -0800829 ad.adb.shell("cmd wifi force-country-code enabled %s" % country_code)
Jaineel Mehtacbad5cc2020-11-19 21:38:18 +0000830 except Exception as e:
Jaineelc5b56a62019-10-10 17:12:02 -0700831 ad.droid.wifiSetCountryCode(WifiEnums.CountryCode.US)
Roshan Pius48df08c2019-09-13 08:07:30 -0700832
Ang Li82522812016-06-02 13:57:21 -0700833
Ang Li6b557182015-11-11 17:19:17 -0800834def start_wifi_connection_scan(ad):
Ang Li73697b32015-12-03 00:41:53 +0000835 """Starts a wifi connection scan and wait for results to become available.
836
837 Args:
Ang Li6b557182015-11-11 17:19:17 -0800838 ad: An AndroidDevice object.
Ang Li73697b32015-12-03 00:41:53 +0000839 """
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800840 ad.ed.clear_all_events()
Ang Li6b557182015-11-11 17:19:17 -0800841 ad.droid.wifiStartScan()
Ang Li82522812016-06-02 13:57:21 -0700842 try:
843 ad.ed.pop_event("WifiManagerScanResultsAvailable", 60)
844 except Empty:
845 asserts.fail("Wi-Fi results did not become available within 60s.")
846
Ang Li73697b32015-12-03 00:41:53 +0000847
Roshan Piuscb9bc482018-02-01 14:27:09 -0800848def start_wifi_connection_scan_and_return_status(ad):
849 """
850 Starts a wifi connection scan and wait for results to become available
851 or a scan failure to be reported.
852
853 Args:
854 ad: An AndroidDevice object.
855 Returns:
856 True: if scan succeeded & results are available
857 False: if scan failed
858 """
859 ad.ed.clear_all_events()
860 ad.droid.wifiStartScan()
861 try:
Omar El Ayach8c017902020-10-18 10:26:57 -0700862 events = ad.ed.pop_events("WifiManagerScan(ResultsAvailable|Failure)",
863 60)
Roshan Piuscb9bc482018-02-01 14:27:09 -0800864 except Empty:
865 asserts.fail(
866 "Wi-Fi scan results/failure did not become available within 60s.")
867 # If there are multiple matches, we check for atleast one success.
868 for event in events:
869 if event["name"] == "WifiManagerScanResultsAvailable":
870 return True
871 elif event["name"] == "WifiManagerScanFailure":
872 ad.log.debug("Scan failure received")
873 return False
874
875
Omar El Ayach8c017902020-10-18 10:26:57 -0700876def start_wifi_connection_scan_and_check_for_network(ad,
877 network_ssid,
Roshan Piuscb9bc482018-02-01 14:27:09 -0800878 max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800879 """
880 Start connectivity scans & checks if the |network_ssid| is seen in
881 scan results. The method performs a max of |max_tries| connectivity scans
882 to find the network.
883
884 Args:
885 ad: An AndroidDevice object.
886 network_ssid: SSID of the network we are looking for.
887 max_tries: Number of scans to try.
888 Returns:
889 True: if network_ssid is found in scan results.
890 False: if network_ssid is not found in scan results.
891 """
892 for num_tries in range(max_tries):
Roshan Piuscb9bc482018-02-01 14:27:09 -0800893 if start_wifi_connection_scan_and_return_status(ad):
894 scan_results = ad.droid.wifiGetScanResults()
Omar El Ayach8c017902020-10-18 10:26:57 -0700895 match_results = match_networks({WifiEnums.SSID_KEY: network_ssid},
896 scan_results)
Roshan Piuscb9bc482018-02-01 14:27:09 -0800897 if len(match_results) > 0:
898 return True
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800899 return False
900
901
Omar El Ayach8c017902020-10-18 10:26:57 -0700902def start_wifi_connection_scan_and_ensure_network_found(
903 ad, network_ssid, max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800904 """
905 Start connectivity scans & ensure the |network_ssid| is seen in
906 scan results. The method performs a max of |max_tries| connectivity scans
907 to find the network.
908 This method asserts on failure!
909
910 Args:
911 ad: An AndroidDevice object.
912 network_ssid: SSID of the network we are looking for.
913 max_tries: Number of scans to try.
914 """
915 ad.log.info("Starting scans to ensure %s is present", network_ssid)
916 assert_msg = "Failed to find " + network_ssid + " in scan results" \
917 " after " + str(max_tries) + " tries"
Omar El Ayach8c017902020-10-18 10:26:57 -0700918 asserts.assert_true(
919 start_wifi_connection_scan_and_check_for_network(
920 ad, network_ssid, max_tries), assert_msg)
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800921
922
Omar El Ayach8c017902020-10-18 10:26:57 -0700923def start_wifi_connection_scan_and_ensure_network_not_found(
924 ad, network_ssid, max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800925 """
926 Start connectivity scans & ensure the |network_ssid| is not seen in
927 scan results. The method performs a max of |max_tries| connectivity scans
928 to find the network.
929 This method asserts on failure!
930
931 Args:
932 ad: An AndroidDevice object.
933 network_ssid: SSID of the network we are looking for.
934 max_tries: Number of scans to try.
935 """
936 ad.log.info("Starting scans to ensure %s is not present", network_ssid)
937 assert_msg = "Found " + network_ssid + " in scan results" \
938 " after " + str(max_tries) + " tries"
Omar El Ayach8c017902020-10-18 10:26:57 -0700939 asserts.assert_false(
940 start_wifi_connection_scan_and_check_for_network(
941 ad, network_ssid, max_tries), assert_msg)
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800942
943
Ang Li73697b32015-12-03 00:41:53 +0000944def start_wifi_background_scan(ad, scan_setting):
945 """Starts wifi background scan.
946
947 Args:
948 ad: android_device object to initiate connection on.
949 scan_setting: A dict representing the settings of the scan.
950
951 Returns:
952 If scan was started successfully, event data of success event is returned.
953 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700954 idx = ad.droid.wifiScannerStartBackgroundScan(scan_setting)
955 event = ad.ed.pop_event("WifiScannerScan{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -0800956 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +0000957 return event['data']
958
Ang Li82522812016-06-02 13:57:21 -0700959
Girish Moturu38b993c2021-03-25 13:03:50 -0700960def start_wifi_tethering(ad, ssid, password, band=None, hidden=None,
961 security=None):
Ang Li73697b32015-12-03 00:41:53 +0000962 """Starts wifi tethering on an android_device.
963
964 Args:
965 ad: android_device to start wifi tethering on.
966 ssid: The SSID the soft AP should broadcast.
967 password: The password the soft AP should use.
968 band: The band the soft AP should be set on. It should be either
969 WifiEnums.WIFI_CONFIG_APBAND_2G or WifiEnums.WIFI_CONFIG_APBAND_5G.
Roshan Piusce821342018-01-10 11:03:04 -0800970 hidden: boolean to indicate if the AP needs to be hidden or not.
Girish Moturu38b993c2021-03-25 13:03:50 -0700971 security: security type of softap.
Ang Li73697b32015-12-03 00:41:53 +0000972
973 Returns:
Girish Moturu3581d612016-11-02 15:08:51 -0700974 No return value. Error checks in this function will raise test failure signals
Ang Li73697b32015-12-03 00:41:53 +0000975 """
Ang Li82522812016-06-02 13:57:21 -0700976 config = {WifiEnums.SSID_KEY: ssid}
Ang Li73697b32015-12-03 00:41:53 +0000977 if password:
978 config[WifiEnums.PWD_KEY] = password
979 if band:
lesl6d30a172020-03-05 15:05:22 +0800980 config[WifiEnums.AP_BAND_KEY] = band
Roshan Piusce821342018-01-10 11:03:04 -0800981 if hidden:
Omar El Ayach8c017902020-10-18 10:26:57 -0700982 config[WifiEnums.HIDDEN_KEY] = hidden
Girish Moturu38b993c2021-03-25 13:03:50 -0700983 if security:
984 config[WifiEnums.SECURITY] = security
Omar El Ayach8c017902020-10-18 10:26:57 -0700985 asserts.assert_true(ad.droid.wifiSetWifiApConfiguration(config),
986 "Failed to update WifiAp Configuration")
Girish Moturu40d7dc22016-11-02 12:14:56 -0700987 ad.droid.wifiStartTrackingTetherStateChange()
988 ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
Rebecca Silbersteina2889852016-08-11 00:48:53 -0700989 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700990 ad.ed.pop_event("ConnectivityManagerOnTetheringStarted")
991 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -0800992 lambda x: x["data"]["ACTIVE_TETHER"], 30)
Ang Li76216d12016-09-20 14:51:57 -0700993 ad.log.debug("Tethering started successfully.")
Rebecca Silbersteina2889852016-08-11 00:48:53 -0700994 except Empty:
995 msg = "Failed to receive confirmation of wifi tethering starting"
996 asserts.fail(msg)
997 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700998 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li73697b32015-12-03 00:41:53 +0000999
Bindu Mahadevff295782019-02-08 16:17:48 -08001000
Omar El Ayach8c017902020-10-18 10:26:57 -07001001def save_wifi_soft_ap_config(ad,
1002 wifi_config,
1003 band=None,
1004 hidden=None,
1005 security=None,
1006 password=None,
1007 channel=None,
1008 max_clients=None,
lesl6d30a172020-03-05 15:05:22 +08001009 shutdown_timeout_enable=None,
1010 shutdown_timeout_millis=None,
1011 client_control_enable=None,
Omar El Ayach8c017902020-10-18 10:26:57 -07001012 allowedList=None,
lesl67124362021-05-04 19:33:14 +08001013 blockedList=None,
1014 bands=None,
1015 channel_frequencys=None,
1016 mac_randomization_setting=None,
1017 bridged_opportunistic_shutdown_enabled=None,
1018 ieee80211ax_enabled=None):
lesl6d30a172020-03-05 15:05:22 +08001019 """ Save a soft ap configuration and verified
1020 Args:
1021 ad: android_device to set soft ap configuration.
1022 wifi_config: a soft ap configuration object, at least include SSID.
1023 band: specifies the band for the soft ap.
1024 hidden: specifies the soft ap need to broadcast its SSID or not.
1025 security: specifies the security type for the soft ap.
1026 password: specifies the password for the soft ap.
1027 channel: specifies the channel for the soft ap.
1028 max_clients: specifies the maximum connected client number.
1029 shutdown_timeout_enable: specifies the auto shut down enable or not.
1030 shutdown_timeout_millis: specifies the shut down timeout value.
1031 client_control_enable: specifies the client control enable or not.
1032 allowedList: specifies allowed clients list.
1033 blockedList: specifies blocked clients list.
lesl67124362021-05-04 19:33:14 +08001034 bands: specifies the band list for the soft ap.
1035 channel_frequencys: specifies the channel frequency list for soft ap.
1036 mac_randomization_setting: specifies the mac randomization setting.
1037 bridged_opportunistic_shutdown_enabled: specifies the opportunistic
1038 shutdown enable or not.
1039 ieee80211ax_enabled: specifies the ieee80211ax enable or not.
lesl6d30a172020-03-05 15:05:22 +08001040 """
1041 if security and password:
Omar El Ayach8c017902020-10-18 10:26:57 -07001042 wifi_config[WifiEnums.SECURITY] = security
1043 wifi_config[WifiEnums.PWD_KEY] = password
lesl67124362021-05-04 19:33:14 +08001044 if hidden is not None:
Girish Moturu528b5442018-06-07 10:48:14 -07001045 wifi_config[WifiEnums.HIDDEN_KEY] = hidden
lesl67124362021-05-04 19:33:14 +08001046 if max_clients is not None:
lesl6d30a172020-03-05 15:05:22 +08001047 wifi_config[WifiEnums.AP_MAXCLIENTS_KEY] = max_clients
lesl67124362021-05-04 19:33:14 +08001048 if shutdown_timeout_enable is not None:
lesl6d30a172020-03-05 15:05:22 +08001049 wifi_config[
1050 WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] = shutdown_timeout_enable
lesl67124362021-05-04 19:33:14 +08001051 if shutdown_timeout_millis is not None:
Omar El Ayach8c017902020-10-18 10:26:57 -07001052 wifi_config[WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] = shutdown_timeout_millis
lesl67124362021-05-04 19:33:14 +08001053 if client_control_enable is not None:
lesl6d30a172020-03-05 15:05:22 +08001054 wifi_config[WifiEnums.AP_CLIENTCONTROL_KEY] = client_control_enable
lesl67124362021-05-04 19:33:14 +08001055 if allowedList is not None:
lesl6d30a172020-03-05 15:05:22 +08001056 wifi_config[WifiEnums.AP_ALLOWEDLIST_KEY] = allowedList
lesl67124362021-05-04 19:33:14 +08001057 if blockedList is not None:
lesl6d30a172020-03-05 15:05:22 +08001058 wifi_config[WifiEnums.AP_BLOCKEDLIST_KEY] = blockedList
lesl67124362021-05-04 19:33:14 +08001059 if mac_randomization_setting is not None:
1060 wifi_config[WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY
1061 ] = mac_randomization_setting
1062 if bridged_opportunistic_shutdown_enabled is not None:
1063 wifi_config[WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY
1064 ] = bridged_opportunistic_shutdown_enabled
1065 if ieee80211ax_enabled is not None:
1066 wifi_config[WifiEnums.AP_IEEE80211AX_ENABLED_KEY]= ieee80211ax_enabled
1067 if channel_frequencys is not None:
1068 wifi_config[WifiEnums.AP_CHANNEL_FREQUENCYS_KEY] = channel_frequencys
1069 elif bands is not None:
1070 wifi_config[WifiEnums.AP_BANDS_KEY] = bands
1071 elif band is not None:
1072 if channel is not None:
1073 wifi_config[WifiEnums.AP_BAND_KEY] = band
1074 wifi_config[WifiEnums.AP_CHANNEL_KEY] = channel
1075 else:
1076 wifi_config[WifiEnums.AP_BAND_KEY] = band
lesl6d30a172020-03-05 15:05:22 +08001077
1078 if WifiEnums.AP_CHANNEL_KEY in wifi_config and wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001079 WifiEnums.AP_CHANNEL_KEY] == 0:
lesl6d30a172020-03-05 15:05:22 +08001080 del wifi_config[WifiEnums.AP_CHANNEL_KEY]
1081
1082 if WifiEnums.SECURITY in wifi_config and wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001083 WifiEnums.SECURITY] == WifiEnums.SoftApSecurityType.OPEN:
lesl6d30a172020-03-05 15:05:22 +08001084 del wifi_config[WifiEnums.SECURITY]
1085 del wifi_config[WifiEnums.PWD_KEY]
1086
Girish Moturu528b5442018-06-07 10:48:14 -07001087 asserts.assert_true(ad.droid.wifiSetWifiApConfiguration(wifi_config),
1088 "Failed to set WifiAp Configuration")
1089
1090 wifi_ap = ad.droid.wifiGetApConfiguration()
1091 asserts.assert_true(
1092 wifi_ap[WifiEnums.SSID_KEY] == wifi_config[WifiEnums.SSID_KEY],
lesl6d30a172020-03-05 15:05:22 +08001093 "Hotspot SSID doesn't match")
1094 if WifiEnums.SECURITY in wifi_config:
1095 asserts.assert_true(
1096 wifi_ap[WifiEnums.SECURITY] == wifi_config[WifiEnums.SECURITY],
1097 "Hotspot Security doesn't match")
1098 if WifiEnums.PWD_KEY in wifi_config:
1099 asserts.assert_true(
1100 wifi_ap[WifiEnums.PWD_KEY] == wifi_config[WifiEnums.PWD_KEY],
1101 "Hotspot Password doesn't match")
Girish Moturu528b5442018-06-07 10:48:14 -07001102
lesl6d30a172020-03-05 15:05:22 +08001103 if WifiEnums.HIDDEN_KEY in wifi_config:
1104 asserts.assert_true(
1105 wifi_ap[WifiEnums.HIDDEN_KEY] == wifi_config[WifiEnums.HIDDEN_KEY],
1106 "Hotspot hidden setting doesn't match")
1107
lesl6d30a172020-03-05 15:05:22 +08001108 if WifiEnums.AP_CHANNEL_KEY in wifi_config:
1109 asserts.assert_true(
1110 wifi_ap[WifiEnums.AP_CHANNEL_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001111 WifiEnums.AP_CHANNEL_KEY], "Hotspot Channel doesn't match")
lesl6d30a172020-03-05 15:05:22 +08001112 if WifiEnums.AP_MAXCLIENTS_KEY in wifi_config:
1113 asserts.assert_true(
1114 wifi_ap[WifiEnums.AP_MAXCLIENTS_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001115 WifiEnums.AP_MAXCLIENTS_KEY],
1116 "Hotspot Max Clients doesn't match")
lesl6d30a172020-03-05 15:05:22 +08001117 if WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY in wifi_config:
1118 asserts.assert_true(
1119 wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001120 WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY],
lesl6d30a172020-03-05 15:05:22 +08001121 "Hotspot ShutDown feature flag doesn't match")
1122 if WifiEnums.AP_SHUTDOWNTIMEOUT_KEY in wifi_config:
1123 asserts.assert_true(
1124 wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001125 WifiEnums.AP_SHUTDOWNTIMEOUT_KEY],
lesl6d30a172020-03-05 15:05:22 +08001126 "Hotspot ShutDown timeout setting doesn't match")
1127 if WifiEnums.AP_CLIENTCONTROL_KEY in wifi_config:
1128 asserts.assert_true(
1129 wifi_ap[WifiEnums.AP_CLIENTCONTROL_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001130 WifiEnums.AP_CLIENTCONTROL_KEY],
lesl6d30a172020-03-05 15:05:22 +08001131 "Hotspot Client control flag doesn't match")
1132 if WifiEnums.AP_ALLOWEDLIST_KEY in wifi_config:
1133 asserts.assert_true(
1134 wifi_ap[WifiEnums.AP_ALLOWEDLIST_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001135 WifiEnums.AP_ALLOWEDLIST_KEY],
lesl6d30a172020-03-05 15:05:22 +08001136 "Hotspot Allowed List doesn't match")
1137 if WifiEnums.AP_BLOCKEDLIST_KEY in wifi_config:
1138 asserts.assert_true(
1139 wifi_ap[WifiEnums.AP_BLOCKEDLIST_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001140 WifiEnums.AP_BLOCKEDLIST_KEY],
lesl6d30a172020-03-05 15:05:22 +08001141 "Hotspot Blocked List doesn't match")
Bindu Mahadevff295782019-02-08 16:17:48 -08001142
lesl67124362021-05-04 19:33:14 +08001143 if WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY in wifi_config:
1144 asserts.assert_true(
1145 wifi_ap[WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY] == wifi_config[
1146 WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY],
1147 "Hotspot Mac randomization setting doesn't match")
1148
1149 if WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY in wifi_config:
1150 asserts.assert_true(
1151 wifi_ap[WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY] == wifi_config[
1152 WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY],
1153 "Hotspot bridged shutdown enable setting doesn't match")
1154
1155 if WifiEnums.AP_IEEE80211AX_ENABLED_KEY in wifi_config:
1156 asserts.assert_true(
1157 wifi_ap[WifiEnums.AP_IEEE80211AX_ENABLED_KEY] == wifi_config[
1158 WifiEnums.AP_IEEE80211AX_ENABLED_KEY],
1159 "Hotspot 80211 AX enable setting doesn't match")
1160
1161 if WifiEnums.AP_CHANNEL_FREQUENCYS_KEY in wifi_config:
1162 asserts.assert_true(
1163 wifi_ap[WifiEnums.AP_CHANNEL_FREQUENCYS_KEY] == wifi_config[
1164 WifiEnums.AP_CHANNEL_FREQUENCYS_KEY],
1165 "Hotspot channels setting doesn't match")
Omar El Ayach8c017902020-10-18 10:26:57 -07001166
Girish Moturu528b5442018-06-07 10:48:14 -07001167def start_wifi_tethering_saved_config(ad):
1168 """ Turn on wifi hotspot with a config that is already saved """
1169 ad.droid.wifiStartTrackingTetherStateChange()
1170 ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
1171 try:
1172 ad.ed.pop_event("ConnectivityManagerOnTetheringStarted")
1173 ad.ed.wait_for_event("TetherStateChanged",
1174 lambda x: x["data"]["ACTIVE_TETHER"], 30)
1175 except:
1176 asserts.fail("Didn't receive wifi tethering starting confirmation")
1177 finally:
1178 ad.droid.wifiStopTrackingTetherStateChange()
Betty Zhou3caa0982017-02-22 19:26:20 -08001179
Bindu Mahadevff295782019-02-08 16:17:48 -08001180
Ang Li73697b32015-12-03 00:41:53 +00001181def stop_wifi_tethering(ad):
1182 """Stops wifi tethering on an android_device.
Ang Li73697b32015-12-03 00:41:53 +00001183 Args:
1184 ad: android_device to stop wifi tethering on.
1185 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001186 ad.droid.wifiStartTrackingTetherStateChange()
1187 ad.droid.connectivityStopTethering(tel_defines.TETHERING_WIFI)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001188 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001189 ad.ed.pop_event("WifiManagerApDisabled", 30)
1190 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -08001191 lambda x: not x["data"]["ACTIVE_TETHER"], 30)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001192 except Empty:
1193 msg = "Failed to receive confirmation of wifi tethering stopping"
1194 asserts.fail(msg)
1195 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001196 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li82522812016-06-02 13:57:21 -07001197
Ang Li76216d12016-09-20 14:51:57 -07001198
Roshan Pius58916a32016-06-16 16:26:44 -07001199def toggle_wifi_and_wait_for_reconnection(ad,
1200 network,
1201 num_of_tries=1,
1202 assert_on_fail=True):
1203 """Toggle wifi state and then wait for Android device to reconnect to
1204 the provided wifi network.
1205
1206 This expects the device to be already connected to the provided network.
1207
1208 Logic steps are
1209 1. Ensure that we're connected to the network.
1210 2. Turn wifi off.
1211 3. Wait for 10 seconds.
1212 4. Turn wifi on.
1213 5. Wait for the "connected" event, then confirm the connected ssid is the
1214 one requested.
1215
1216 Args:
1217 ad: android_device object to initiate connection on.
1218 network: A dictionary representing the network to await connection. The
1219 dictionary must have the key "SSID".
1220 num_of_tries: An integer that is the number of times to try before
1221 delaring failure. Default is 1.
1222 assert_on_fail: If True, error checks in this function will raise test
1223 failure signals.
1224
1225 Returns:
1226 If assert_on_fail is False, function returns True if the toggle was
1227 successful, False otherwise. If assert_on_fail is True, no return value.
1228 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001229 return _assert_on_fail_handler(_toggle_wifi_and_wait_for_reconnection,
1230 assert_on_fail,
1231 ad,
1232 network,
1233 num_of_tries=num_of_tries)
Roshan Pius58916a32016-06-16 16:26:44 -07001234
1235
Girish Moturu5d9f4202019-12-03 15:29:21 -08001236def _toggle_wifi_and_wait_for_reconnection(ad, network, num_of_tries=3):
Roshan Pius58916a32016-06-16 16:26:44 -07001237 """Toggle wifi state and then wait for Android device to reconnect to
1238 the provided wifi network.
1239
1240 This expects the device to be already connected to the provided network.
1241
1242 Logic steps are
1243 1. Ensure that we're connected to the network.
1244 2. Turn wifi off.
1245 3. Wait for 10 seconds.
1246 4. Turn wifi on.
1247 5. Wait for the "connected" event, then confirm the connected ssid is the
1248 one requested.
1249
1250 This will directly fail a test if anything goes wrong.
1251
1252 Args:
1253 ad: android_device object to initiate connection on.
1254 network: A dictionary representing the network to await connection. The
1255 dictionary must have the key "SSID".
1256 num_of_tries: An integer that is the number of times to try before
1257 delaring failure. Default is 1.
1258 """
Roshan Pius58916a32016-06-16 16:26:44 -07001259 expected_ssid = network[WifiEnums.SSID_KEY]
1260 # First ensure that we're already connected to the provided network.
1261 verify_con = {WifiEnums.SSID_KEY: expected_ssid}
1262 verify_wifi_connection_info(ad, verify_con)
1263 # Now toggle wifi state and wait for the connection event.
1264 wifi_toggle_state(ad, False)
1265 time.sleep(10)
1266 wifi_toggle_state(ad, True)
1267 ad.droid.wifiStartTrackingStateChange()
1268 try:
1269 connect_result = None
1270 for i in range(num_of_tries):
1271 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -08001272 connect_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
Roshan Pius58916a32016-06-16 16:26:44 -07001273 30)
1274 break
1275 except Empty:
1276 pass
Omar El Ayach8c017902020-10-18 10:26:57 -07001277 asserts.assert_true(
1278 connect_result, "Failed to connect to Wi-Fi network %s on %s" %
1279 (network, ad.serial))
Betty Zhou3caa0982017-02-22 19:26:20 -08001280 logging.debug("Connection result on %s: %s.", ad.serial,
1281 connect_result)
Roshan Pius58916a32016-06-16 16:26:44 -07001282 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001283 asserts.assert_equal(
1284 actual_ssid, expected_ssid, "Connected to the wrong network on %s."
1285 "Expected %s, but got %s." %
1286 (ad.serial, expected_ssid, actual_ssid))
Betty Zhou3caa0982017-02-22 19:26:20 -08001287 logging.info("Connected to Wi-Fi network %s on %s", actual_ssid,
1288 ad.serial)
Roshan Pius58916a32016-06-16 16:26:44 -07001289 finally:
1290 ad.droid.wifiStopTrackingStateChange()
1291
1292
Omar El Ayach8c017902020-10-18 10:26:57 -07001293def wait_for_connect(ad,
1294 expected_ssid=None,
1295 expected_id=None,
1296 tries=2,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001297 assert_on_fail=True):
Roshan Piusd1204442018-11-12 12:20:39 -08001298 """Wait for a connect event.
1299
1300 This will directly fail a test if anything goes wrong.
1301
1302 Args:
1303 ad: An Android device object.
1304 expected_ssid: SSID of the network to connect to.
1305 expected_id: Network Id of the network to connect to.
1306 tries: An integer that is the number of times to try before failing.
1307 assert_on_fail: If True, error checks in this function will raise test
1308 failure signals.
1309
1310 Returns:
1311 Returns a value only if assert_on_fail is false.
1312 Returns True if the connection was successful, False otherwise.
1313 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001314 return _assert_on_fail_handler(_wait_for_connect, assert_on_fail, ad,
1315 expected_ssid, expected_id, tries)
Roshan Piusd1204442018-11-12 12:20:39 -08001316
1317
Oscar Shucb9af9b2019-05-02 20:01:49 +00001318def _wait_for_connect(ad, expected_ssid=None, expected_id=None, tries=2):
Roshan Piusd1204442018-11-12 12:20:39 -08001319 """Wait for a connect event.
1320
1321 Args:
1322 ad: An Android device object.
1323 expected_ssid: SSID of the network to connect to.
1324 expected_id: Network Id of the network to connect to.
1325 tries: An integer that is the number of times to try before failing.
1326 """
1327 ad.droid.wifiStartTrackingStateChange()
1328 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001329 connect_result = _wait_for_connect_event(ad,
1330 ssid=expected_ssid,
1331 id=expected_id,
1332 tries=tries)
1333 asserts.assert_true(
1334 connect_result,
1335 "Failed to connect to Wi-Fi network %s" % expected_ssid)
Roshan Piusd1204442018-11-12 12:20:39 -08001336 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
1337 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1338 if expected_ssid:
1339 asserts.assert_equal(actual_ssid, expected_ssid,
1340 "Connected to the wrong network")
1341 actual_id = connect_result['data'][WifiEnums.NETID_KEY]
1342 if expected_id:
1343 asserts.assert_equal(actual_id, expected_id,
1344 "Connected to the wrong network")
1345 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
1346 except Empty:
1347 asserts.fail("Failed to start connection process to %s" %
1348 expected_ssid)
1349 except Exception as error:
1350 ad.log.error("Failed to connect to %s with error %s", expected_ssid,
1351 error)
1352 raise signals.TestFailure("Failed to connect to %s network" %
1353 expected_ssid)
1354 finally:
1355 ad.droid.wifiStopTrackingStateChange()
1356
1357
Oscar Shucb9af9b2019-05-02 20:01:49 +00001358def _wait_for_connect_event(ad, ssid=None, id=None, tries=1):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001359 """Wait for a connect event on queue and pop when available.
1360
1361 Args:
1362 ad: An Android device object.
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001363 ssid: SSID of the network to connect to.
1364 id: Network Id of the network to connect to.
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001365 tries: An integer that is the number of times to try before failing.
1366
1367 Returns:
1368 A dict with details of the connection data, which looks like this:
1369 {
1370 'time': 1485460337798,
1371 'name': 'WifiNetworkConnected',
1372 'data': {
1373 'rssi': -27,
1374 'is_24ghz': True,
1375 'mac_address': '02:00:00:00:00:00',
1376 'network_id': 1,
1377 'BSSID': '30:b5:c2:33:d3:fc',
1378 'ip_address': 117483712,
1379 'link_speed': 54,
1380 'supplicant_state': 'completed',
1381 'hidden_ssid': False,
1382 'SSID': 'wh_ap1_2g',
1383 'is_5ghz': False}
1384 }
1385
1386 """
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001387 conn_result = None
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001388
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001389 # If ssid and network id is None, just wait for any connect event.
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001390 if id is None and ssid is None:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001391 for i in range(tries):
1392 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001393 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
1394 30)
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001395 break
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001396 except Empty:
1397 pass
1398 else:
Omar El Ayach8c017902020-10-18 10:26:57 -07001399 # If ssid or network id is specified, wait for specific connect event.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001400 for i in range(tries):
1401 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001402 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
1403 30)
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001404 if id and conn_result['data'][WifiEnums.NETID_KEY] == id:
1405 break
1406 elif ssid and conn_result['data'][WifiEnums.SSID_KEY] == ssid:
1407 break
1408 except Empty:
1409 pass
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001410
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001411 return conn_result
1412
Bindu Mahadevff295782019-02-08 16:17:48 -08001413
Roshan Piusffc29912019-01-18 13:39:49 -08001414def wait_for_disconnect(ad, timeout=10):
1415 """Wait for a disconnect event within the specified timeout.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001416
1417 Args:
1418 ad: Android device object.
Roshan Piusffc29912019-01-18 13:39:49 -08001419 timeout: Timeout in seconds.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001420
1421 """
1422 try:
1423 ad.droid.wifiStartTrackingStateChange()
Roshan Piusffc29912019-01-18 13:39:49 -08001424 event = ad.ed.pop_event("WifiNetworkDisconnected", timeout)
Roshan Piusbf7e3982018-02-15 12:37:41 -08001425 except Empty:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001426 raise signals.TestFailure("Device did not disconnect from the network")
Roshan Piusffc29912019-01-18 13:39:49 -08001427 finally:
1428 ad.droid.wifiStopTrackingStateChange()
1429
1430
1431def ensure_no_disconnect(ad, duration=10):
1432 """Ensure that there is no disconnect for the specified duration.
1433
1434 Args:
1435 ad: Android device object.
1436 duration: Duration in seconds.
1437
1438 """
1439 try:
1440 ad.droid.wifiStartTrackingStateChange()
1441 event = ad.ed.pop_event("WifiNetworkDisconnected", duration)
1442 raise signals.TestFailure("Device disconnected from the network")
1443 except Empty:
1444 pass
1445 finally:
1446 ad.droid.wifiStopTrackingStateChange()
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001447
1448
Omar El Ayach8c017902020-10-18 10:26:57 -07001449def connect_to_wifi_network(ad,
1450 network,
1451 assert_on_fail=True,
1452 check_connectivity=True,
1453 hidden=False):
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001454 """Connection logic for open and psk wifi networks.
1455
1456 Args:
Jong Wook Kim92356922018-02-06 18:32:49 -08001457 ad: AndroidDevice to use for connection
1458 network: network info of the network to connect to
1459 assert_on_fail: If true, errors from wifi_connect will raise
1460 test failure signals.
Joe Brennan48c3f692019-04-11 08:30:16 -07001461 hidden: Is the Wifi network hidden.
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001462 """
Joe Brennan48c3f692019-04-11 08:30:16 -07001463 if hidden:
1464 start_wifi_connection_scan_and_ensure_network_not_found(
1465 ad, network[WifiEnums.SSID_KEY])
1466 else:
1467 start_wifi_connection_scan_and_ensure_network_found(
1468 ad, network[WifiEnums.SSID_KEY])
Jong Wook Kim92356922018-02-06 18:32:49 -08001469 wifi_connect(ad,
1470 network,
1471 num_of_tries=3,
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001472 assert_on_fail=assert_on_fail,
1473 check_connectivity=check_connectivity)
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001474
1475
1476def connect_to_wifi_network_with_id(ad, network_id, network_ssid):
1477 """Connect to the given network using network id and verify SSID.
1478
1479 Args:
1480 network_id: int Network Id of the network.
1481 network_ssid: string SSID of the network.
1482
1483 Returns: True if connect using network id was successful;
1484 False otherwise.
1485
1486 """
Jong Wook Kim92356922018-02-06 18:32:49 -08001487 start_wifi_connection_scan_and_ensure_network_found(ad, network_ssid)
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001488 wifi_connect_by_id(ad, network_id)
1489 connect_data = ad.droid.wifiGetConnectionInfo()
1490 connect_ssid = connect_data[WifiEnums.SSID_KEY]
1491 ad.log.debug("Expected SSID = %s Connected SSID = %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001492 (network_ssid, connect_ssid))
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001493 if connect_ssid != network_ssid:
1494 return False
1495 return True
1496
1497
Omar El Ayach8c017902020-10-18 10:26:57 -07001498def wifi_connect(ad,
1499 network,
1500 num_of_tries=1,
1501 assert_on_fail=True,
1502 check_connectivity=True):
Ang Li99d8c6d2015-12-09 15:56:13 -08001503 """Connect an Android device to a wifi network.
Ang Li73697b32015-12-03 00:41:53 +00001504
1505 Initiate connection to a wifi network, wait for the "connected" event, then
Ang Li99d8c6d2015-12-09 15:56:13 -08001506 confirm the connected ssid is the one requested.
Ang Li73697b32015-12-03 00:41:53 +00001507
Ang Li82522812016-06-02 13:57:21 -07001508 This will directly fail a test if anything goes wrong.
1509
Ang Li73697b32015-12-03 00:41:53 +00001510 Args:
1511 ad: android_device object to initiate connection on.
Ang Li99d8c6d2015-12-09 15:56:13 -08001512 network: A dictionary representing the network to connect to. The
Ang Li82522812016-06-02 13:57:21 -07001513 dictionary must have the key "SSID".
1514 num_of_tries: An integer that is the number of times to try before
1515 delaring failure. Default is 1.
1516 assert_on_fail: If True, error checks in this function will raise test
1517 failure signals.
1518
1519 Returns:
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001520 Returns a value only if assert_on_fail is false.
1521 Returns True if the connection was successful, False otherwise.
Ang Li73697b32015-12-03 00:41:53 +00001522 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001523 return _assert_on_fail_handler(_wifi_connect,
1524 assert_on_fail,
1525 ad,
1526 network,
1527 num_of_tries=num_of_tries,
1528 check_connectivity=check_connectivity)
Ang Li82522812016-06-02 13:57:21 -07001529
1530
Oscar Shucb9af9b2019-05-02 20:01:49 +00001531def _wifi_connect(ad, network, num_of_tries=1, check_connectivity=True):
Ang Li82522812016-06-02 13:57:21 -07001532 """Connect an Android device to a wifi network.
1533
1534 Initiate connection to a wifi network, wait for the "connected" event, then
1535 confirm the connected ssid is the one requested.
1536
1537 This will directly fail a test if anything goes wrong.
1538
1539 Args:
1540 ad: android_device object to initiate connection on.
1541 network: A dictionary representing the network to connect to. The
1542 dictionary must have the key "SSID".
1543 num_of_tries: An integer that is the number of times to try before
1544 delaring failure. Default is 1.
1545 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001546 asserts.assert_true(
1547 WifiEnums.SSID_KEY in network,
1548 "Key '%s' must be present in network definition." % WifiEnums.SSID_KEY)
Ang Li99d8c6d2015-12-09 15:56:13 -08001549 ad.droid.wifiStartTrackingStateChange()
Betty Zhoud35dab82016-12-06 15:24:23 -08001550 expected_ssid = network[WifiEnums.SSID_KEY]
Bindu Mahadev50374df2017-01-04 11:03:32 -08001551 ad.droid.wifiConnectByConfig(network)
1552 ad.log.info("Starting connection process to %s", expected_ssid)
Ang Li73697b32015-12-03 00:41:53 +00001553 try:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001554 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_CONFIG_SUCCESS, 30)
Omar El Ayach8c017902020-10-18 10:26:57 -07001555 connect_result = _wait_for_connect_event(ad,
1556 ssid=expected_ssid,
1557 tries=num_of_tries)
1558 asserts.assert_true(
1559 connect_result, "Failed to connect to Wi-Fi network %s on %s" %
1560 (network, ad.serial))
Ang Li31b00782016-06-21 13:04:23 -07001561 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
Ang Li99d8c6d2015-12-09 15:56:13 -08001562 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001563 asserts.assert_equal(
1564 actual_ssid, expected_ssid,
1565 "Connected to the wrong network on %s." % ad.serial)
Ang Li31b00782016-06-21 13:04:23 -07001566 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
Bindu Mahadev50374df2017-01-04 11:03:32 -08001567
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001568 if check_connectivity:
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08001569 internet = validate_connection(ad, DEFAULT_PING_ADDR)
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001570 if not internet:
Omar El Ayach8c017902020-10-18 10:26:57 -07001571 raise signals.TestFailure(
1572 "Failed to connect to internet on %s" % expected_ssid)
Bindu Mahadev50374df2017-01-04 11:03:32 -08001573 except Empty:
1574 asserts.fail("Failed to start connection process to %s on %s" %
1575 (network, ad.serial))
Bindu Mahadev4e710362016-11-17 16:17:11 -08001576 except Exception as error:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001577 ad.log.error("Failed to connect to %s with error %s", expected_ssid,
1578 error)
1579 raise signals.TestFailure("Failed to connect to %s network" % network)
1580
Ang Li73697b32015-12-03 00:41:53 +00001581 finally:
Ang Li99d8c6d2015-12-09 15:56:13 -08001582 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001583
Bindu Mahadev50374df2017-01-04 11:03:32 -08001584
Oscar Shucb9af9b2019-05-02 20:01:49 +00001585def wifi_connect_by_id(ad, network_id, num_of_tries=3, assert_on_fail=True):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001586 """Connect an Android device to a wifi network using network Id.
1587
1588 Start connection to the wifi network, with the given network Id, wait for
1589 the "connected" event, then verify the connected network is the one requested.
1590
1591 This will directly fail a test if anything goes wrong.
1592
1593 Args:
1594 ad: android_device object to initiate connection on.
1595 network_id: Integer specifying the network id of the network.
1596 num_of_tries: An integer that is the number of times to try before
1597 delaring failure. Default is 1.
1598 assert_on_fail: If True, error checks in this function will raise test
1599 failure signals.
1600
1601 Returns:
1602 Returns a value only if assert_on_fail is false.
1603 Returns True if the connection was successful, False otherwise.
1604 """
1605 _assert_on_fail_handler(_wifi_connect_by_id, assert_on_fail, ad,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001606 network_id, num_of_tries)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001607
1608
Oscar Shucb9af9b2019-05-02 20:01:49 +00001609def _wifi_connect_by_id(ad, network_id, num_of_tries=1):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001610 """Connect an Android device to a wifi network using it's network id.
1611
1612 Start connection to the wifi network, with the given network id, wait for
1613 the "connected" event, then verify the connected network is the one requested.
1614
1615 Args:
1616 ad: android_device object to initiate connection on.
1617 network_id: Integer specifying the network id of the network.
1618 num_of_tries: An integer that is the number of times to try before
1619 delaring failure. Default is 1.
1620 """
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001621 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001622 # Clear all previous events.
1623 ad.ed.clear_all_events()
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001624 ad.droid.wifiConnectByNetworkId(network_id)
1625 ad.log.info("Starting connection to network with id %d", network_id)
1626 try:
1627 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_NETID_SUCCESS, 60)
Omar El Ayach8c017902020-10-18 10:26:57 -07001628 connect_result = _wait_for_connect_event(ad,
1629 id=network_id,
1630 tries=num_of_tries)
1631 asserts.assert_true(
1632 connect_result,
1633 "Failed to connect to Wi-Fi network using network id")
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001634 ad.log.debug("Wi-Fi connection result: %s", connect_result)
1635 actual_id = connect_result['data'][WifiEnums.NETID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001636 asserts.assert_equal(
1637 actual_id, network_id, "Connected to the wrong network on %s."
1638 "Expected network id = %d, but got %d." %
1639 (ad.serial, network_id, actual_id))
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001640 expected_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1641 ad.log.info("Connected to Wi-Fi network %s with %d network id.",
Omar El Ayach8c017902020-10-18 10:26:57 -07001642 expected_ssid, network_id)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001643
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001644 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1645 if not internet:
1646 raise signals.TestFailure("Failed to connect to internet on %s" %
1647 expected_ssid)
1648 except Empty:
1649 asserts.fail("Failed to connect to network with id %d on %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001650 (network_id, ad.serial))
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001651 except Exception as error:
1652 ad.log.error("Failed to connect to network with id %d with error %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07001653 network_id, error)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001654 raise signals.TestFailure("Failed to connect to network with network"
1655 " id %d" % network_id)
1656 finally:
1657 ad.droid.wifiStopTrackingStateChange()
1658
Oscar Shu0b5ff4d2019-08-07 18:11:56 +00001659
Omar El Ayach8c017902020-10-18 10:26:57 -07001660def wifi_connect_using_network_request(ad,
1661 network,
1662 network_specifier,
Roshan Pius5561d232021-01-22 16:34:39 -08001663 num_of_tries=3):
Roshan Piusc999e5e2018-11-09 10:59:52 -08001664 """Connect an Android device to a wifi network using network request.
1665
1666 Trigger a network request with the provided network specifier,
1667 wait for the "onMatch" event, ensure that the scan results in "onMatch"
1668 event contain the specified network, then simulate the user granting the
1669 request with the specified network selected. Then wait for the "onAvailable"
1670 network callback indicating successful connection to network.
1671
1672 Args:
1673 ad: android_device object to initiate connection on.
1674 network_specifier: A dictionary representing the network specifier to
1675 use.
1676 network: A dictionary representing the network to connect to. The
1677 dictionary must have the key "SSID".
1678 num_of_tries: An integer that is the number of times to try before
1679 delaring failure.
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001680 Returns:
1681 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001682 """
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001683 key = ad.droid.connectivityRequestWifiNetwork(network_specifier, 0)
1684 ad.log.info("Sent network request %s with %s " % (key, network_specifier))
Roshan Piusc999e5e2018-11-09 10:59:52 -08001685 # Need a delay here because UI interaction should only start once wifi
1686 # starts processing the request.
1687 time.sleep(wifi_constants.NETWORK_REQUEST_CB_REGISTER_DELAY_SEC)
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001688 _wait_for_wifi_connect_after_network_request(ad, network, key, num_of_tries)
1689 return key
Roshan Piusc999e5e2018-11-09 10:59:52 -08001690
1691
Omar El Ayach8c017902020-10-18 10:26:57 -07001692def wait_for_wifi_connect_after_network_request(ad,
1693 network,
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001694 key,
Omar El Ayach8c017902020-10-18 10:26:57 -07001695 num_of_tries=3,
Roshan Piusc999e5e2018-11-09 10:59:52 -08001696 assert_on_fail=True):
1697 """
1698 Simulate and verify the connection flow after initiating the network
1699 request.
1700
1701 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1702 event contain the specified network, then simulate the user granting the
1703 request with the specified network selected. Then wait for the "onAvailable"
1704 network callback indicating successful connection to network.
1705
1706 Args:
1707 ad: android_device object to initiate connection on.
1708 network: A dictionary representing the network to connect to. The
1709 dictionary must have the key "SSID".
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001710 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001711 num_of_tries: An integer that is the number of times to try before
1712 delaring failure.
1713 assert_on_fail: If True, error checks in this function will raise test
1714 failure signals.
1715
1716 Returns:
1717 Returns a value only if assert_on_fail is false.
1718 Returns True if the connection was successful, False otherwise.
1719 """
1720 _assert_on_fail_handler(_wait_for_wifi_connect_after_network_request,
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001721 assert_on_fail, ad, network, key, num_of_tries)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001722
1723
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001724def _wait_for_wifi_connect_after_network_request(ad, network, key, num_of_tries=3):
Roshan Piusc999e5e2018-11-09 10:59:52 -08001725 """
1726 Simulate and verify the connection flow after initiating the network
1727 request.
1728
1729 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1730 event contain the specified network, then simulate the user granting the
1731 request with the specified network selected. Then wait for the "onAvailable"
1732 network callback indicating successful connection to network.
1733
1734 Args:
1735 ad: android_device object to initiate connection on.
1736 network: A dictionary representing the network to connect to. The
1737 dictionary must have the key "SSID".
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001738 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001739 num_of_tries: An integer that is the number of times to try before
1740 delaring failure.
1741 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001742 asserts.assert_true(
1743 WifiEnums.SSID_KEY in network,
1744 "Key '%s' must be present in network definition." % WifiEnums.SSID_KEY)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001745 ad.droid.wifiStartTrackingStateChange()
1746 expected_ssid = network[WifiEnums.SSID_KEY]
1747 ad.droid.wifiRegisterNetworkRequestMatchCallback()
1748 # Wait for the platform to scan and return a list of networks
1749 # matching the request
1750 try:
1751 matched_network = None
Omar El Ayach8c017902020-10-18 10:26:57 -07001752 for _ in [0, num_of_tries]:
Roshan Piusc999e5e2018-11-09 10:59:52 -08001753 on_match_event = ad.ed.pop_event(
1754 wifi_constants.WIFI_NETWORK_REQUEST_MATCH_CB_ON_MATCH, 60)
1755 asserts.assert_true(on_match_event,
1756 "Network request on match not received.")
1757 matched_scan_results = on_match_event["data"]
1758 ad.log.debug("Network request on match results %s",
1759 matched_scan_results)
1760 matched_network = match_networks(
1761 {WifiEnums.SSID_KEY: network[WifiEnums.SSID_KEY]},
1762 matched_scan_results)
Roshan Pius6cd4aaf2021-02-09 15:54:30 -08001763 ad.log.debug("Network request on match %s", matched_network)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001764 if matched_network:
Omar El Ayach8c017902020-10-18 10:26:57 -07001765 break
Roshan Piusc999e5e2018-11-09 10:59:52 -08001766
Omar El Ayach8c017902020-10-18 10:26:57 -07001767 asserts.assert_true(matched_network,
1768 "Target network %s not found" % network)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001769
1770 ad.droid.wifiSendUserSelectionForNetworkRequestMatch(network)
1771 ad.log.info("Sent user selection for network request %s",
1772 expected_ssid)
1773
1774 # Wait for the platform to connect to the network.
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001775 autils.wait_for_event_with_keys(
1776 ad, cconsts.EVENT_NETWORK_CALLBACK,
1777 60,
1778 (cconsts.NETWORK_CB_KEY_ID, key),
1779 (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_AVAILABLE))
1780 on_capabilities_changed = autils.wait_for_event_with_keys(
1781 ad, cconsts.EVENT_NETWORK_CALLBACK,
1782 10,
1783 (cconsts.NETWORK_CB_KEY_ID, key),
1784 (cconsts.NETWORK_CB_KEY_EVENT,
1785 cconsts.NETWORK_CB_CAPABILITIES_CHANGED))
Roshan Pius008fe7f2021-03-25 14:18:17 -07001786 connected_network = None
1787 # WifiInfo is attached to TransportInfo only in S.
1788 if ad.droid.isSdkAtLeastS():
1789 connected_network = (
1790 on_capabilities_changed["data"][
1791 cconsts.NETWORK_CB_KEY_TRANSPORT_INFO]
1792 )
1793 else:
1794 connected_network = ad.droid.wifiGetConnectionInfo()
Roshan Piusc999e5e2018-11-09 10:59:52 -08001795 ad.log.info("Connected to network %s", connected_network)
Omar El Ayach8c017902020-10-18 10:26:57 -07001796 asserts.assert_equal(
1797 connected_network[WifiEnums.SSID_KEY], expected_ssid,
1798 "Connected to the wrong network."
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001799 "Expected %s, but got %s."
1800 % (network, connected_network))
Roshan Piusc999e5e2018-11-09 10:59:52 -08001801 except Empty:
1802 asserts.fail("Failed to connect to %s" % expected_ssid)
1803 except Exception as error:
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001804 ad.log.error("Failed to connect to %s with error %s" %
Roshan Piusc999e5e2018-11-09 10:59:52 -08001805 (expected_ssid, error))
1806 raise signals.TestFailure("Failed to connect to %s network" % network)
1807 finally:
1808 ad.droid.wifiStopTrackingStateChange()
1809
1810
Omar El Ayach8c017902020-10-18 10:26:57 -07001811def wifi_passpoint_connect(ad,
1812 passpoint_network,
1813 num_of_tries=1,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001814 assert_on_fail=True):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001815 """Connect an Android device to a wifi network.
1816
1817 Initiate connection to a wifi network, wait for the "connected" event, then
1818 confirm the connected ssid is the one requested.
1819
1820 This will directly fail a test if anything goes wrong.
1821
1822 Args:
1823 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001824 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001825 num_of_tries: An integer that is the number of times to try before
1826 delaring failure. Default is 1.
1827 assert_on_fail: If True, error checks in this function will raise test
1828 failure signals.
1829
1830 Returns:
1831 If assert_on_fail is False, function returns network id, if the connect was
1832 successful, False otherwise. If assert_on_fail is True, no return value.
1833 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001834 _assert_on_fail_handler(_wifi_passpoint_connect,
1835 assert_on_fail,
1836 ad,
1837 passpoint_network,
1838 num_of_tries=num_of_tries)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001839
1840
Oscar Shucb9af9b2019-05-02 20:01:49 +00001841def _wifi_passpoint_connect(ad, passpoint_network, num_of_tries=1):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001842 """Connect an Android device to a wifi network.
1843
1844 Initiate connection to a wifi network, wait for the "connected" event, then
1845 confirm the connected ssid is the one requested.
1846
1847 This will directly fail a test if anything goes wrong.
1848
1849 Args:
1850 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001851 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001852 num_of_tries: An integer that is the number of times to try before
1853 delaring failure. Default is 1.
1854 """
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001855 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001856 expected_ssid = passpoint_network
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001857 ad.log.info("Starting connection process to passpoint %s", expected_ssid)
1858
1859 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001860 connect_result = _wait_for_connect_event(ad, expected_ssid,
1861 num_of_tries)
1862 asserts.assert_true(
1863 connect_result, "Failed to connect to WiFi passpoint network %s on"
1864 " %s" % (expected_ssid, ad.serial))
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001865 ad.log.info("Wi-Fi connection result: %s.", connect_result)
1866 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001867 asserts.assert_equal(
1868 actual_ssid, expected_ssid,
1869 "Connected to the wrong network on %s." % ad.serial)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001870 ad.log.info("Connected to Wi-Fi passpoint network %s.", actual_ssid)
1871
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001872 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1873 if not internet:
1874 raise signals.TestFailure("Failed to connect to internet on %s" %
1875 expected_ssid)
1876 except Exception as error:
1877 ad.log.error("Failed to connect to passpoint network %s with error %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07001878 expected_ssid, error)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001879 raise signals.TestFailure("Failed to connect to %s passpoint network" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001880 expected_ssid)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001881
1882 finally:
1883 ad.droid.wifiStopTrackingStateChange()
1884
1885
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001886def delete_passpoint(ad, fqdn):
1887 """Delete a required Passpoint configuration."""
1888 try:
1889 ad.droid.removePasspointConfig(fqdn)
1890 return True
1891 except Exception as error:
Omar El Ayach8c017902020-10-18 10:26:57 -07001892 ad.log.error(
1893 "Failed to remove passpoint configuration with FQDN=%s "
1894 "and error=%s", fqdn, error)
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001895 return False
1896
1897
Ang Li73697b32015-12-03 00:41:53 +00001898def start_wifi_single_scan(ad, scan_setting):
1899 """Starts wifi single shot scan.
1900
1901 Args:
1902 ad: android_device object to initiate connection on.
1903 scan_setting: A dict representing the settings of the scan.
1904
1905 Returns:
1906 If scan was started successfully, event data of success event is returned.
1907 """
Ang Li82522812016-06-02 13:57:21 -07001908 idx = ad.droid.wifiScannerStartScan(scan_setting)
1909 event = ad.ed.pop_event("WifiScannerScan%sonSuccess" % idx, SHORT_TIMEOUT)
Ang Li31b00782016-06-21 13:04:23 -07001910 ad.log.debug("Got event %s", event)
Ang Li73697b32015-12-03 00:41:53 +00001911 return event['data']
1912
Ang Li82522812016-06-02 13:57:21 -07001913
Ang Li73697b32015-12-03 00:41:53 +00001914def track_connection(ad, network_ssid, check_connection_count):
1915 """Track wifi connection to network changes for given number of counts
1916
1917 Args:
1918 ad: android_device object for forget network.
1919 network_ssid: network ssid to which connection would be tracked
1920 check_connection_count: Integer for maximum number network connection
Ang Li82522812016-06-02 13:57:21 -07001921 check.
Ang Li73697b32015-12-03 00:41:53 +00001922 Returns:
Ang Li73697b32015-12-03 00:41:53 +00001923 True if connection to given network happen, else return False.
1924 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001925 ad.droid.wifiStartTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001926 while check_connection_count > 0:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001927 connect_network = ad.ed.pop_event("WifiNetworkConnected", 120)
Ang Li31b00782016-06-21 13:04:23 -07001928 ad.log.info("Connected to network %s", connect_network)
Ang Li82522812016-06-02 13:57:21 -07001929 if (WifiEnums.SSID_KEY in connect_network['data'] and
1930 connect_network['data'][WifiEnums.SSID_KEY] == network_ssid):
1931 return True
Ang Li8e767182015-12-09 17:29:24 -08001932 check_connection_count -= 1
Girish Moturu40d7dc22016-11-02 12:14:56 -07001933 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001934 return False
1935
Ang Li82522812016-06-02 13:57:21 -07001936
Ang Li73697b32015-12-03 00:41:53 +00001937def get_scan_time_and_channels(wifi_chs, scan_setting, stime_channel):
1938 """Calculate the scan time required based on the band or channels in scan
1939 setting
1940
1941 Args:
1942 wifi_chs: Object of channels supported
1943 scan_setting: scan setting used for start scan
1944 stime_channel: scan time per channel
1945
1946 Returns:
1947 scan_time: time required for completing a scan
1948 scan_channels: channel used for scanning
1949 """
1950 scan_time = 0
1951 scan_channels = []
1952 if "band" in scan_setting and "channels" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001953 scan_channels = wifi_chs.band_to_freq(scan_setting["band"])
Ang Li73697b32015-12-03 00:41:53 +00001954 elif "channels" in scan_setting and "band" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001955 scan_channels = scan_setting["channels"]
Ang Li73697b32015-12-03 00:41:53 +00001956 scan_time = len(scan_channels) * stime_channel
1957 for channel in scan_channels:
Ang Li8e767182015-12-09 17:29:24 -08001958 if channel in WifiEnums.DFS_5G_FREQUENCIES:
Ang Li82522812016-06-02 13:57:21 -07001959 scan_time += 132 #passive scan time on DFS
Ang Li73697b32015-12-03 00:41:53 +00001960 return scan_time, scan_channels
1961
Ang Li82522812016-06-02 13:57:21 -07001962
Ang Li73697b32015-12-03 00:41:53 +00001963def start_wifi_track_bssid(ad, track_setting):
1964 """Start tracking Bssid for the given settings.
1965
1966 Args:
1967 ad: android_device object.
1968 track_setting: Setting for which the bssid tracking should be started
1969
1970 Returns:
1971 If tracking started successfully, event data of success event is returned.
1972 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001973 idx = ad.droid.wifiScannerStartTrackingBssids(
Ang Li82522812016-06-02 13:57:21 -07001974 track_setting["bssidInfos"], track_setting["apLostThreshold"])
Girish Moturu40d7dc22016-11-02 12:14:56 -07001975 event = ad.ed.pop_event("WifiScannerBssid{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -08001976 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +00001977 return event['data']
1978
Ang Li82522812016-06-02 13:57:21 -07001979
Ang Li73697b32015-12-03 00:41:53 +00001980def convert_pem_key_to_pkcs8(in_file, out_file):
1981 """Converts the key file generated by us to the format required by
1982 Android using openssl.
1983
1984 The input file must have the extension "pem". The output file must
1985 have the extension "der".
1986
1987 Args:
1988 in_file: The original key file.
1989 out_file: The full path to the converted key file, including
1990 filename.
1991 """
Ang Li82522812016-06-02 13:57:21 -07001992 asserts.assert_true(in_file.endswith(".pem"), "Input file has to be .pem.")
Omar El Ayach8c017902020-10-18 10:26:57 -07001993 asserts.assert_true(out_file.endswith(".der"),
1994 "Output file has to be .der.")
Ang Li73697b32015-12-03 00:41:53 +00001995 cmd = ("openssl pkcs8 -inform PEM -in {} -outform DER -out {} -nocrypt"
1996 " -topk8").format(in_file, out_file)
Ang Lifee28402016-07-13 13:43:29 -07001997 utils.exe_cmd(cmd)
Ang Li73697b32015-12-03 00:41:53 +00001998
Ang Li82522812016-06-02 13:57:21 -07001999
Omar El Ayach8c017902020-10-18 10:26:57 -07002000def validate_connection(ad,
2001 ping_addr=DEFAULT_PING_ADDR,
2002 wait_time=15,
Girish Moturu804a3492020-02-17 14:32:02 -08002003 ping_gateway=True):
Ang Li73697b32015-12-03 00:41:53 +00002004 """Validate internet connection by pinging the address provided.
2005
2006 Args:
2007 ad: android_device object.
2008 ping_addr: address on internet for pinging.
Girish Moturua2a5bf22019-08-16 09:52:29 -07002009 wait_time: wait for some time before validating connection
Ang Li73697b32015-12-03 00:41:53 +00002010
2011 Returns:
Bindu Mahadev50374df2017-01-04 11:03:32 -08002012 ping output if successful, NULL otherwise.
Ang Li73697b32015-12-03 00:41:53 +00002013 """
Girish Moturua2a5bf22019-08-16 09:52:29 -07002014 # wait_time to allow for DHCP to complete.
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08002015 for i in range(wait_time):
Girish Moturuacf35002020-11-09 23:37:35 -08002016 if ad.droid.connectivityNetworkIsConnected(
Omar El Ayach8c017902020-10-18 10:26:57 -07002017 ) and ad.droid.connectivityGetIPv4DefaultGateway():
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08002018 break
2019 time.sleep(1)
Girish Moturu804a3492020-02-17 14:32:02 -08002020 ping = False
2021 try:
2022 ping = ad.droid.httpPing(ping_addr)
2023 ad.log.info("Http ping result: %s.", ping)
2024 except:
2025 pass
2026 if not ping and ping_gateway:
2027 ad.log.info("Http ping failed. Pinging default gateway")
2028 gw = ad.droid.connectivityGetIPv4DefaultGateway()
2029 result = ad.adb.shell("ping -c 6 {}".format(gw))
2030 ad.log.info("Default gateway ping result: %s" % result)
2031 ping = False if "100% packet loss" in result else True
Ang Li73697b32015-12-03 00:41:53 +00002032 return ping
2033
Ang Li82522812016-06-02 13:57:21 -07002034
Ang Li73697b32015-12-03 00:41:53 +00002035#TODO(angli): This can only verify if an actual value is exactly the same.
2036# Would be nice to be able to verify an actual value is one of serveral.
2037def verify_wifi_connection_info(ad, expected_con):
2038 """Verifies that the information of the currently connected wifi network is
2039 as expected.
2040
2041 Args:
2042 expected_con: A dict representing expected key-value pairs for wifi
2043 connection. e.g. {"SSID": "test_wifi"}
2044 """
2045 current_con = ad.droid.wifiGetConnectionInfo()
Ang Li374d7602016-02-08 17:27:27 -08002046 case_insensitive = ["BSSID", "supplicant_state"]
Ang Li31b00782016-06-21 13:04:23 -07002047 ad.log.debug("Current connection: %s", current_con)
Ang Li73697b32015-12-03 00:41:53 +00002048 for k, expected_v in expected_con.items():
Ang Li9a66de72016-02-08 15:26:38 -08002049 # Do not verify authentication related fields.
2050 if k == "password":
2051 continue
Ang Li82522812016-06-02 13:57:21 -07002052 msg = "Field %s does not exist in wifi connection info %s." % (
2053 k, current_con)
Ang Li374d7602016-02-08 17:27:27 -08002054 if k not in current_con:
2055 raise signals.TestFailure(msg)
2056 actual_v = current_con[k]
2057 if k in case_insensitive:
2058 actual_v = actual_v.lower()
2059 expected_v = expected_v.lower()
Ang Li73697b32015-12-03 00:41:53 +00002060 msg = "Expected %s to be %s, actual %s is %s." % (k, expected_v, k,
Ang Li82522812016-06-02 13:57:21 -07002061 actual_v)
Ang Li374d7602016-02-08 17:27:27 -08002062 if actual_v != expected_v:
2063 raise signals.TestFailure(msg)
Ang Li73697b32015-12-03 00:41:53 +00002064
Ang Li82522812016-06-02 13:57:21 -07002065
Omar El Ayach8c017902020-10-18 10:26:57 -07002066def check_autoconnect_to_open_network(
2067 ad, conn_timeout=WIFI_CONNECTION_TIMEOUT_DEFAULT):
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08002068 """Connects to any open WiFI AP
2069 Args:
2070 timeout value in sec to wait for UE to connect to a WiFi AP
2071 Returns:
2072 True if UE connects to WiFi AP (supplicant_state = completed)
2073 False if UE fails to complete connection within WIFI_CONNECTION_TIMEOUT time.
2074 """
2075 if ad.droid.wifiCheckState():
2076 return True
2077 ad.droid.wifiToggleState()
2078 wifi_connection_state = None
2079 timeout = time.time() + conn_timeout
2080 while wifi_connection_state != "completed":
Omar El Ayach8c017902020-10-18 10:26:57 -07002081 wifi_connection_state = ad.droid.wifiGetConnectionInfo(
2082 )['supplicant_state']
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08002083 if time.time() > timeout:
2084 ad.log.warning("Failed to connect to WiFi AP")
2085 return False
2086 return True
2087
2088
Ang Li73697b32015-12-03 00:41:53 +00002089def expand_enterprise_config_by_phase2(config):
2090 """Take an enterprise config and generate a list of configs, each with
2091 a different phase2 auth type.
2092
2093 Args:
2094 config: A dict representing enterprise config.
2095
2096 Returns
2097 A list of enterprise configs.
2098 """
2099 results = []
Ang Li0e7e58f2016-02-22 12:15:02 -08002100 phase2_types = WifiEnums.EapPhase2
2101 if config[WifiEnums.Enterprise.EAP] == WifiEnums.Eap.PEAP:
2102 # Skip unsupported phase2 types for PEAP.
2103 phase2_types = [WifiEnums.EapPhase2.GTC, WifiEnums.EapPhase2.MSCHAPV2]
2104 for phase2_type in phase2_types:
Ang Li73697b32015-12-03 00:41:53 +00002105 # Skip a special case for passpoint TTLS.
Omar El Ayach8c017902020-10-18 10:26:57 -07002106 if (WifiEnums.Enterprise.FQDN in config
2107 and phase2_type == WifiEnums.EapPhase2.GTC):
Ang Li73697b32015-12-03 00:41:53 +00002108 continue
2109 c = dict(config)
Girish Moturu150d32f2017-02-14 12:27:07 -08002110 c[WifiEnums.Enterprise.PHASE2] = phase2_type.value
Ang Li73697b32015-12-03 00:41:53 +00002111 results.append(c)
2112 return results
Ang Li2d3fe982016-06-08 10:00:43 -07002113
2114
Girish Moturub48a13c2017-02-27 11:36:42 -08002115def generate_eap_test_name(config, ad=None):
Girish Moturu150d32f2017-02-14 12:27:07 -08002116 """ Generates a test case name based on an EAP configuration.
2117
2118 Args:
2119 config: A dict representing an EAP credential.
Girish Moturub48a13c2017-02-27 11:36:42 -08002120 ad object: Redundant but required as the same param is passed
2121 to test_func in run_generated_tests
Girish Moturu150d32f2017-02-14 12:27:07 -08002122
2123 Returns:
2124 A string representing the name of a generated EAP test case.
2125 """
2126 eap = WifiEnums.Eap
2127 eap_phase2 = WifiEnums.EapPhase2
Girish Moturub48a13c2017-02-27 11:36:42 -08002128 Ent = WifiEnums.Enterprise
Girish Moturu150d32f2017-02-14 12:27:07 -08002129 name = "test_connect-"
2130 eap_name = ""
2131 for e in eap:
2132 if e.value == config[Ent.EAP]:
2133 eap_name = e.name
2134 break
2135 if "peap0" in config[WifiEnums.SSID_KEY].lower():
2136 eap_name = "PEAP0"
2137 if "peap1" in config[WifiEnums.SSID_KEY].lower():
2138 eap_name = "PEAP1"
2139 name += eap_name
2140 if Ent.PHASE2 in config:
2141 for e in eap_phase2:
2142 if e.value == config[Ent.PHASE2]:
2143 name += "-{}".format(e.name)
2144 break
2145 return name
2146
2147
Ang Li2d3fe982016-06-08 10:00:43 -07002148def group_attenuators(attenuators):
2149 """Groups a list of attenuators into attenuator groups for backward
2150 compatibility reasons.
2151
2152 Most legacy Wi-Fi setups have two attenuators each connected to a separate
2153 AP. The new Wi-Fi setup has four attenuators, each connected to one channel
2154 on an AP, so two of them are connected to one AP.
2155
2156 To make the existing scripts work in the new setup, when the script needs
2157 to attenuate one AP, it needs to set attenuation on both attenuators
2158 connected to the same AP.
2159
2160 This function groups attenuators properly so the scripts work in both
2161 legacy and new Wi-Fi setups.
2162
2163 Args:
2164 attenuators: A list of attenuator objects, either two or four in length.
2165
2166 Raises:
2167 signals.TestFailure is raised if the attenuator list does not have two
2168 or four objects.
2169 """
2170 attn0 = attenuator.AttenuatorGroup("AP0")
2171 attn1 = attenuator.AttenuatorGroup("AP1")
2172 # Legacy testbed setup has two attenuation channels.
2173 num_of_attns = len(attenuators)
2174 if num_of_attns == 2:
2175 attn0.add(attenuators[0])
2176 attn1.add(attenuators[1])
2177 elif num_of_attns == 4:
2178 attn0.add(attenuators[0])
2179 attn0.add(attenuators[1])
2180 attn1.add(attenuators[2])
2181 attn1.add(attenuators[3])
2182 else:
2183 asserts.fail(("Either two or four attenuators are required for this "
2184 "test, but found %s") % num_of_attns)
2185 return [attn0, attn1]
Jong Wook Kim92356922018-02-06 18:32:49 -08002186
Bindu Mahadevff295782019-02-08 16:17:48 -08002187
Girish Moturu36348a32019-12-10 08:41:54 -08002188def set_attns(attenuator, attn_val_name, roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002189 """Sets attenuation values on attenuators used in this test.
2190
2191 Args:
2192 attenuator: The attenuator object.
2193 attn_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002194 roaming_attn: Dictionary specifying the attenuation params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002195 """
2196 logging.info("Set attenuation values to %s", roaming_attn[attn_val_name])
2197 try:
2198 attenuator[0].set_atten(roaming_attn[attn_val_name][0])
2199 attenuator[1].set_atten(roaming_attn[attn_val_name][1])
2200 attenuator[2].set_atten(roaming_attn[attn_val_name][2])
2201 attenuator[3].set_atten(roaming_attn[attn_val_name][3])
2202 except:
2203 logging.exception("Failed to set attenuation values %s.",
Omar El Ayach8c017902020-10-18 10:26:57 -07002204 attn_val_name)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002205 raise
2206
Omar El Ayach8c017902020-10-18 10:26:57 -07002207
Girish Moturu36348a32019-12-10 08:41:54 -08002208def set_attns_steps(attenuators,
2209 atten_val_name,
2210 roaming_attn=ROAMING_ATTN,
2211 steps=10,
2212 wait_time=12):
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002213 """Set attenuation values on attenuators used in this test. It will change
2214 the attenuation values linearly from current value to target value step by
2215 step.
2216
2217 Args:
2218 attenuators: The list of attenuator objects that you want to change
2219 their attenuation value.
2220 atten_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002221 roaming_attn: Dictionary specifying the attenuation params.
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002222 steps: Number of attenuator changes to reach the target value.
2223 wait_time: Sleep time for each change of attenuator.
2224 """
2225 logging.info("Set attenuation values to %s in %d step(s)",
Omar El Ayach8c017902020-10-18 10:26:57 -07002226 roaming_attn[atten_val_name], steps)
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002227 start_atten = [attenuator.get_atten() for attenuator in attenuators]
2228 target_atten = roaming_attn[atten_val_name]
2229 for current_step in range(steps):
2230 progress = (current_step + 1) / steps
2231 for i, attenuator in enumerate(attenuators):
2232 amount_since_start = (target_atten[i] - start_atten[i]) * progress
2233 attenuator.set_atten(round(start_atten[i] + amount_since_start))
2234 time.sleep(wait_time)
2235
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002236
Girish Moturu36348a32019-12-10 08:41:54 -08002237def trigger_roaming_and_validate(dut,
2238 attenuator,
2239 attn_val_name,
2240 expected_con,
2241 roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002242 """Sets attenuators to trigger roaming and validate the DUT connected
2243 to the BSSID expected.
2244
2245 Args:
2246 attenuator: The attenuator object.
2247 attn_val_name: Name of the attenuation value pair to use.
2248 expected_con: The network information of the expected network.
Girish Moturu36348a32019-12-10 08:41:54 -08002249 roaming_attn: Dictionary specifying the attenaution params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002250 """
2251 expected_con = {
2252 WifiEnums.SSID_KEY: expected_con[WifiEnums.SSID_KEY],
2253 WifiEnums.BSSID_KEY: expected_con["bssid"],
2254 }
Girish Moturu36348a32019-12-10 08:41:54 -08002255 set_attns_steps(attenuator, attn_val_name, roaming_attn)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002256
Hsiu-Chang Chenef856402018-09-18 12:32:49 +08002257 verify_wifi_connection_info(dut, expected_con)
2258 expected_bssid = expected_con[WifiEnums.BSSID_KEY]
2259 logging.info("Roamed to %s successfully", expected_bssid)
2260 if not validate_connection(dut):
2261 raise signals.TestFailure("Fail to connect to internet on %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07002262 expected_bssid)
2263
Jong Wook Kim92356922018-02-06 18:32:49 -08002264
2265def create_softap_config():
2266 """Create a softap config with random ssid and password."""
2267 ap_ssid = "softap_" + utils.rand_ascii_str(8)
2268 ap_password = utils.rand_ascii_str(8)
2269 logging.info("softap setup: %s %s", ap_ssid, ap_password)
2270 config = {
2271 WifiEnums.SSID_KEY: ap_ssid,
2272 WifiEnums.PWD_KEY: ap_password,
2273 }
2274 return config
Girish Moturucf4dccd2018-08-27 12:22:00 -07002275
Omar El Ayach8c017902020-10-18 10:26:57 -07002276
Bindu Mahadevff295782019-02-08 16:17:48 -08002277def start_softap_and_verify(ad, band):
2278 """Bring-up softap and verify AP mode and in scan results.
2279
2280 Args:
2281 band: The band to use for softAP.
2282
2283 Returns: dict, the softAP config.
2284
2285 """
lesl2f0fb232019-11-05 16:35:28 +08002286 # Register before start the test.
2287 callbackId = ad.dut.droid.registerSoftApCallback()
2288 # Check softap info value is default
2289 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2290 asserts.assert_true(frequency == 0, "Softap frequency is not reset")
2291 asserts.assert_true(bandwdith == 0, "Softap bandwdith is not reset")
2292
Bindu Mahadevff295782019-02-08 16:17:48 -08002293 config = create_softap_config()
2294 start_wifi_tethering(ad.dut,
2295 config[WifiEnums.SSID_KEY],
Omar El Ayach8c017902020-10-18 10:26:57 -07002296 config[WifiEnums.PWD_KEY],
2297 band=band)
Bindu Mahadevff295782019-02-08 16:17:48 -08002298 asserts.assert_true(ad.dut.droid.wifiIsApEnabled(),
Omar El Ayach8c017902020-10-18 10:26:57 -07002299 "SoftAp is not reported as running")
2300 start_wifi_connection_scan_and_ensure_network_found(
2301 ad.dut_client, config[WifiEnums.SSID_KEY])
lesl2f0fb232019-11-05 16:35:28 +08002302
2303 # Check softap info can get from callback succeed and assert value should be
2304 # valid.
2305 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2306 asserts.assert_true(frequency > 0, "Softap frequency is not valid")
2307 asserts.assert_true(bandwdith > 0, "Softap bandwdith is not valid")
2308 # Unregister callback
2309 ad.dut.droid.unregisterSoftApCallback(callbackId)
2310
Bindu Mahadevff295782019-02-08 16:17:48 -08002311 return config
2312
Omar El Ayach8c017902020-10-18 10:26:57 -07002313
lesle8e3c0a2019-02-22 17:06:04 +08002314def wait_for_expected_number_of_softap_clients(ad, callbackId,
Omar El Ayach8c017902020-10-18 10:26:57 -07002315 expected_num_of_softap_clients):
lesle8e3c0a2019-02-22 17:06:04 +08002316 """Wait for the number of softap clients to be updated as expected.
2317 Args:
2318 callbackId: Id of the callback associated with registering.
2319 expected_num_of_softap_clients: expected number of softap clients.
2320 """
2321 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002322 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
James Mattis5a5dd492020-05-14 13:09:43 -07002323 clientData = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data']
2324 clientCount = clientData[wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07002325 clientMacAddresses = clientData[
2326 wifi_constants.SOFTAP_CLIENTS_MACS_CALLBACK_KEY]
2327 asserts.assert_equal(
2328 clientCount, expected_num_of_softap_clients,
2329 "The number of softap clients doesn't match the expected number")
2330 asserts.assert_equal(
2331 len(clientMacAddresses), expected_num_of_softap_clients,
2332 "The number of mac addresses doesn't match the expected number")
James Mattis5a5dd492020-05-14 13:09:43 -07002333 for macAddress in clientMacAddresses:
Omar El Ayach8c017902020-10-18 10:26:57 -07002334 asserts.assert_true(checkMacAddress(macAddress),
2335 "An invalid mac address was returned")
2336
James Mattis5a5dd492020-05-14 13:09:43 -07002337
2338def checkMacAddress(input):
2339 """Validate whether a string is a valid mac address or not.
2340
2341 Args:
2342 input: The string to validate.
2343
2344 Returns: True/False, returns true for a valid mac address and false otherwise.
2345 """
2346 macValidationRegex = "[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$"
2347 if re.match(macValidationRegex, input.lower()):
2348 return True
2349 return False
lesle8e3c0a2019-02-22 17:06:04 +08002350
Omar El Ayach8c017902020-10-18 10:26:57 -07002351
lesle8e3c0a2019-02-22 17:06:04 +08002352def wait_for_expected_softap_state(ad, callbackId, expected_softap_state):
2353 """Wait for the expected softap state change.
2354 Args:
2355 callbackId: Id of the callback associated with registering.
2356 expected_softap_state: The expected softap state.
2357 """
2358 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002359 callbackId) + wifi_constants.SOFTAP_STATE_CHANGED
2360 asserts.assert_equal(
2361 ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data'][
2362 wifi_constants.SOFTAP_STATE_CHANGE_CALLBACK_KEY],
2363 expected_softap_state,
2364 "Softap state doesn't match with expected state")
2365
lesle8e3c0a2019-02-22 17:06:04 +08002366
2367def get_current_number_of_softap_clients(ad, callbackId):
2368 """pop up all of softap client updated event from queue.
2369 Args:
2370 callbackId: Id of the callback associated with registering.
2371
2372 Returns:
2373 If exist aleast callback, returns last updated number_of_softap_clients.
2374 Returns None when no any match callback event in queue.
2375 """
2376 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002377 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
lesle8e3c0a2019-02-22 17:06:04 +08002378 events = ad.ed.pop_all(eventStr)
2379 for event in events:
Omar El Ayach8c017902020-10-18 10:26:57 -07002380 num_of_clients = event['data'][
2381 wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
lesle8e3c0a2019-02-22 17:06:04 +08002382 if len(events) == 0:
2383 return None
2384 return num_of_clients
Bindu Mahadevff295782019-02-08 16:17:48 -08002385
Omar El Ayach8c017902020-10-18 10:26:57 -07002386
lesl67124362021-05-04 19:33:14 +08002387def get_current_softap_info(ad, callbackId, need_to_wait):
lesl2f0fb232019-11-05 16:35:28 +08002388 """pop up all of softap info changed event from queue.
2389 Args:
2390 callbackId: Id of the callback associated with registering.
lesl67124362021-05-04 19:33:14 +08002391 need_to_wait: Wait for the info callback event before pop all.
lesl2f0fb232019-11-05 16:35:28 +08002392 Returns:
2393 Returns last updated information of softap.
2394 """
2395 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002396 callbackId) + wifi_constants.SOFTAP_INFO_CHANGED
lesl67124362021-05-04 19:33:14 +08002397 ad.log.debug("softap info dump from eventStr %s", eventStr)
lesl2f0fb232019-11-05 16:35:28 +08002398 frequency = 0
2399 bandwidth = 0
lesl67124362021-05-04 19:33:14 +08002400 if (need_to_wait):
lesl2f0fb232019-11-05 16:35:28 +08002401 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
Omar El Ayach8c017902020-10-18 10:26:57 -07002402 frequency = event['data'][
2403 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2404 bandwidth = event['data'][
2405 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
lesl2f0fb232019-11-05 16:35:28 +08002406 ad.log.info("softap info updated, frequency is %s, bandwidth is %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07002407 frequency, bandwidth)
lesl2f0fb232019-11-05 16:35:28 +08002408
2409 events = ad.ed.pop_all(eventStr)
2410 for event in events:
Omar El Ayach8c017902020-10-18 10:26:57 -07002411 frequency = event['data'][
2412 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2413 bandwidth = event['data'][
2414 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
2415 ad.log.info("softap info, frequency is %s, bandwidth is %s", frequency,
2416 bandwidth)
lesl2f0fb232019-11-05 16:35:28 +08002417 return frequency, bandwidth
2418
lesl67124362021-05-04 19:33:14 +08002419def get_current_softap_infos(ad, callbackId, need_to_wait):
2420 """pop up all of softap info list changed event from queue.
2421 Args:
2422 callbackId: Id of the callback associated with registering.
2423 need_to_wait: Wait for the info callback event before pop all.
2424 Returns:
2425 Returns last updated informations of softap.
2426 """
2427 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
2428 callbackId) + wifi_constants.SOFTAP_INFOLIST_CHANGED
2429 ad.log.debug("softap info dump from eventStr %s", eventStr)
2430
2431 if (need_to_wait):
2432 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
2433 infos = event['data']
2434
2435 events = ad.ed.pop_all(eventStr)
2436 for event in events:
2437 infos = event['data']
2438
2439 for info in infos:
2440 frequency = info[
2441 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2442 bandwidth = info[
2443 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
2444 wifistandard = info[
2445 wifi_constants.SOFTAP_INFO_WIFISTANDARD_CALLBACK_KEY]
2446 bssid = info[
2447 wifi_constants.SOFTAP_INFO_BSSID_CALLBACK_KEY]
2448 ad.log.info(
2449 "softap info, freq:%s, bw:%s, wifistandard:%s, bssid:%s",
2450 frequency, bandwidth, wifistandard, bssid)
2451
2452 return infos
2453
2454def get_current_softap_capability(ad, callbackId, need_to_wait):
2455 """pop up all of softap info list changed event from queue.
2456 Args:
2457 callbackId: Id of the callback associated with registering.
2458 need_to_wait: Wait for the info callback event before pop all.
2459 Returns:
2460 Returns last updated capability of softap.
2461 """
2462 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
2463 callbackId) + wifi_constants.SOFTAP_CAPABILITY_CHANGED
2464 ad.log.debug("softap capability dump from eventStr %s", eventStr)
2465 if (need_to_wait):
2466 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
2467 capability = event['data']
2468
2469 events = ad.ed.pop_all(eventStr)
2470 for event in events:
2471 capability = event['data']
2472
2473 return capability
lesl2f0fb232019-11-05 16:35:28 +08002474
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002475def get_ssrdumps(ad):
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002476 """Pulls dumps in the ssrdump dir
2477 Args:
2478 ad: android device object.
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002479 """
2480 logs = ad.get_file_names("/data/vendor/ssrdump/")
2481 if logs:
2482 ad.log.info("Pulling ssrdumps %s", logs)
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002483 log_path = os.path.join(ad.device_log_path, "SSRDUMPS_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002484 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002485 ad.pull_files(logs, log_path)
Hsiu-Chang Chen769bef12020-10-10 06:07:52 +00002486 ad.adb.shell("find /data/vendor/ssrdump/ -type f -delete",
Omar El Ayach8c017902020-10-18 10:26:57 -07002487 ignore_status=True)
2488
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002489
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002490def start_pcap(pcap, wifi_band, test_name):
Girish Moturucf4dccd2018-08-27 12:22:00 -07002491 """Start packet capture in monitor mode.
2492
2493 Args:
2494 pcap: packet capture object
2495 wifi_band: '2g' or '5g' or 'dual'
Bindu Mahadev76551c12018-12-13 19:42:14 +00002496 test_name: test name to be used for pcap file name
2497
2498 Returns:
xianyuanjia0431ba32018-12-14 09:56:42 -08002499 Dictionary with wifi band as key and the tuple
2500 (pcap Process object, log directory) as the value
Girish Moturucf4dccd2018-08-27 12:22:00 -07002501 """
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002502 log_dir = os.path.join(
Xianyuan Jia5cd06bb2019-06-10 16:29:57 -07002503 context.get_current_context().get_full_output_path(), 'PacketCapture')
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002504 os.makedirs(log_dir, exist_ok=True)
Girish Moturucf4dccd2018-08-27 12:22:00 -07002505 if wifi_band == 'dual':
2506 bands = [BAND_2G, BAND_5G]
2507 else:
2508 bands = [wifi_band]
xianyuanjia0431ba32018-12-14 09:56:42 -08002509 procs = {}
Girish Moturucf4dccd2018-08-27 12:22:00 -07002510 for band in bands:
xianyuanjia0431ba32018-12-14 09:56:42 -08002511 proc = pcap.start_packet_capture(band, log_dir, test_name)
2512 procs[band] = (proc, os.path.join(log_dir, test_name))
2513 return procs
Girish Moturucf4dccd2018-08-27 12:22:00 -07002514
Bindu Mahadevff295782019-02-08 16:17:48 -08002515
xianyuanjia0431ba32018-12-14 09:56:42 -08002516def stop_pcap(pcap, procs, test_status=None):
Bindu Mahadev76551c12018-12-13 19:42:14 +00002517 """Stop packet capture in monitor mode.
2518
2519 Since, the pcap logs in monitor mode can be very large, we will
2520 delete them if they are not required. 'test_status' if True, will delete
2521 the pcap files. If False, we will keep them.
Girish Moturucf4dccd2018-08-27 12:22:00 -07002522
2523 Args:
2524 pcap: packet capture object
xianyuanjia0431ba32018-12-14 09:56:42 -08002525 procs: dictionary returned by start_pcap
Bindu Mahadev76551c12018-12-13 19:42:14 +00002526 test_status: status of the test case
Girish Moturucf4dccd2018-08-27 12:22:00 -07002527 """
xianyuanjia0431ba32018-12-14 09:56:42 -08002528 for proc, fname in procs.values():
2529 pcap.stop_packet_capture(proc)
Bindu Mahadev76551c12018-12-13 19:42:14 +00002530
2531 if test_status:
xianyuanjia0431ba32018-12-14 09:56:42 -08002532 shutil.rmtree(os.path.dirname(fname))
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002533
Omar El Ayach8c017902020-10-18 10:26:57 -07002534
Jaineel95887fd2019-10-16 16:19:01 -07002535def verify_mac_not_found_in_pcap(ad, mac, packets):
xshuf7267682019-06-03 14:41:56 -07002536 """Verify that a mac address is not found in the captured packets.
2537
2538 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002539 ad: android device object
xshuf7267682019-06-03 14:41:56 -07002540 mac: string representation of the mac address
2541 packets: packets obtained by rdpcap(pcap_fname)
2542 """
2543 for pkt in packets:
2544 logging.debug("Packet Summary = %s", pkt.summary())
2545 if mac in pkt.summary():
Jaineel95887fd2019-10-16 16:19:01 -07002546 asserts.fail("Device %s caught Factory MAC: %s in packet sniffer."
2547 "Packet = %s" % (ad.serial, mac, pkt.show()))
Bindu Mahadevff295782019-02-08 16:17:48 -08002548
Omar El Ayach8c017902020-10-18 10:26:57 -07002549
Jaineel95887fd2019-10-16 16:19:01 -07002550def verify_mac_is_found_in_pcap(ad, mac, packets):
Nate Jiangc2c09c62019-06-05 17:26:08 -07002551 """Verify that a mac address is found in the captured packets.
2552
2553 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002554 ad: android device object
Nate Jiangc2c09c62019-06-05 17:26:08 -07002555 mac: string representation of the mac address
2556 packets: packets obtained by rdpcap(pcap_fname)
2557 """
2558 for pkt in packets:
2559 if mac in pkt.summary():
2560 return
Jaineel95887fd2019-10-16 16:19:01 -07002561 asserts.fail("Did not find MAC = %s in packet sniffer."
2562 "for device %s" % (mac, ad.serial))
Nate Jiangc2c09c62019-06-05 17:26:08 -07002563
Omar El Ayach8c017902020-10-18 10:26:57 -07002564
Girish Moturuddc0d382020-08-24 12:08:41 -07002565def start_cnss_diags(ads, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002566 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002567 start_cnss_diag(ad, cnss_diag_file, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002568
Bindu Mahadevff295782019-02-08 16:17:48 -08002569
Girish Moturuddc0d382020-08-24 12:08:41 -07002570def start_cnss_diag(ad, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002571 """Start cnss_diag to record extra wifi logs
2572
2573 Args:
2574 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002575 cnss_diag_file: cnss diag config file to push to device.
2576 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002577 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002578 if ad.model not in pixel_models:
2579 ad.log.info("Device not supported to collect pixel logger")
2580 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002581 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2582 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2583 else:
2584 prop = wifi_constants.CNSS_DIAG_PROP
2585 if ad.adb.getprop(prop) != 'true':
Omar El Ayach8c017902020-10-18 10:26:57 -07002586 if not int(
2587 ad.adb.shell("ls -l %s%s | wc -l" %
2588 (CNSS_DIAG_CONFIG_PATH, CNSS_DIAG_CONFIG_FILE))):
Girish Moturuddc0d382020-08-24 12:08:41 -07002589 ad.adb.push("%s %s" % (cnss_diag_file, CNSS_DIAG_CONFIG_PATH))
Omar El Ayach8c017902020-10-18 10:26:57 -07002590 ad.adb.shell(
2591 "find /data/vendor/wifi/cnss_diag/wlan_logs/ -type f -delete",
2592 ignore_status=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002593 ad.adb.shell("setprop %s true" % prop, ignore_status=True)
2594
Bindu Mahadevff295782019-02-08 16:17:48 -08002595
Girish Moturuddc0d382020-08-24 12:08:41 -07002596def stop_cnss_diags(ads, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002597 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002598 stop_cnss_diag(ad, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002599
Bindu Mahadevff295782019-02-08 16:17:48 -08002600
Girish Moturuddc0d382020-08-24 12:08:41 -07002601def stop_cnss_diag(ad, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002602 """Stops cnss_diag
2603
2604 Args:
2605 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002606 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002607 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002608 if ad.model not in pixel_models:
2609 ad.log.info("Device not supported to collect pixel logger")
2610 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002611 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2612 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2613 else:
2614 prop = wifi_constants.CNSS_DIAG_PROP
2615 ad.adb.shell("setprop %s false" % prop, ignore_status=True)
2616
Bindu Mahadevff295782019-02-08 16:17:48 -08002617
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002618def get_cnss_diag_log(ad):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002619 """Pulls the cnss_diag logs in the wlan_logs dir
2620 Args:
2621 ad: android device object.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002622 """
2623 logs = ad.get_file_names("/data/vendor/wifi/cnss_diag/wlan_logs/")
2624 if logs:
2625 ad.log.info("Pulling cnss_diag logs %s", logs)
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002626 log_path = os.path.join(ad.device_log_path, "CNSS_DIAG_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002627 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002628 ad.pull_files(logs, log_path)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002629
Bindu Mahadevff295782019-02-08 16:17:48 -08002630
Omar El Ayach8c017902020-10-18 10:26:57 -07002631LinkProbeResult = namedtuple(
2632 'LinkProbeResult',
2633 ('is_success', 'stdout', 'elapsed_time', 'failure_reason'))
David Sue4cd9c22019-03-26 18:07:26 -07002634
2635
2636def send_link_probe(ad):
2637 """Sends a link probe to the currently connected AP, and returns whether the
2638 probe succeeded or not.
2639
2640 Args:
2641 ad: android device object
2642 Returns:
2643 LinkProbeResult namedtuple
2644 """
2645 stdout = ad.adb.shell('cmd wifi send-link-probe')
2646 asserts.assert_false('Error' in stdout or 'Exception' in stdout,
2647 'Exception while sending link probe: ' + stdout)
2648
2649 is_success = False
2650 elapsed_time = None
2651 failure_reason = None
2652 if 'succeeded' in stdout:
2653 is_success = True
2654 elapsed_time = next(
2655 (int(token) for token in stdout.split() if token.isdigit()), None)
2656 elif 'failed with reason' in stdout:
2657 failure_reason = next(
2658 (int(token) for token in stdout.split() if token.isdigit()), None)
2659 else:
2660 asserts.fail('Unexpected link probe result: ' + stdout)
2661
Omar El Ayach8c017902020-10-18 10:26:57 -07002662 return LinkProbeResult(is_success=is_success,
2663 stdout=stdout,
2664 elapsed_time=elapsed_time,
2665 failure_reason=failure_reason)
David Sue4cd9c22019-03-26 18:07:26 -07002666
2667
2668def send_link_probes(ad, num_probes, delay_sec):
2669 """Sends a sequence of link probes to the currently connected AP, and
2670 returns whether the probes succeeded or not.
2671
2672 Args:
2673 ad: android device object
2674 num_probes: number of probes to perform
2675 delay_sec: delay time between probes, in seconds
2676 Returns:
2677 List[LinkProbeResult] one LinkProbeResults for each probe
2678 """
2679 logging.info('Sending link probes')
2680 results = []
2681 for _ in range(num_probes):
2682 # send_link_probe() will also fail the test if it sees an exception
2683 # in the stdout of the adb shell command
2684 result = send_link_probe(ad)
2685 logging.info('link probe results: ' + str(result))
2686 results.append(result)
2687 time.sleep(delay_sec)
2688
2689 return results
2690
2691
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002692def ap_setup(test, index, ap, network, bandwidth=80, channel=6):
Omar El Ayach8c017902020-10-18 10:26:57 -07002693 """Set up the AP with provided network info.
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002694
2695 Args:
2696 test: the calling test class object.
2697 index: int, index of the AP.
2698 ap: access_point object of the AP.
2699 network: dict with information of the network, including ssid,
2700 password and bssid.
2701 bandwidth: the operation bandwidth for the AP, default 80MHz.
2702 channel: the channel number for the AP.
2703 Returns:
2704 brconfigs: the bridge interface configs
2705 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002706 bss_settings = []
2707 ssid = network[WifiEnums.SSID_KEY]
2708 test.access_points[index].close()
2709 time.sleep(5)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002710
Omar El Ayach8c017902020-10-18 10:26:57 -07002711 # Configure AP as required.
2712 if "password" in network.keys():
2713 password = network["password"]
2714 security = hostapd_security.Security(security_mode="wpa",
2715 password=password)
2716 else:
2717 security = hostapd_security.Security(security_mode=None, password=None)
2718 config = hostapd_ap_preset.create_ap_preset(channel=channel,
2719 ssid=ssid,
2720 security=security,
2721 bss_settings=bss_settings,
2722 vht_bandwidth=bandwidth,
2723 profile_name='whirlwind',
2724 iface_wlan_2g=ap.wlan_2g,
2725 iface_wlan_5g=ap.wlan_5g)
2726 ap.start_ap(config)
2727 logging.info("AP started on channel {} with SSID {}".format(channel, ssid))
Bindu Mahadevff295782019-02-08 16:17:48 -08002728
2729
2730def turn_ap_off(test, AP):
2731 """Bring down hostapd on the Access Point.
2732 Args:
2733 test: The test class object.
2734 AP: int, indicating which AP to turn OFF.
2735 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002736 hostapd_2g = test.access_points[AP - 1]._aps['wlan0'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002737 if hostapd_2g.is_alive():
2738 hostapd_2g.stop()
2739 logging.debug('Turned WLAN0 AP%d off' % AP)
Omar El Ayach8c017902020-10-18 10:26:57 -07002740 hostapd_5g = test.access_points[AP - 1]._aps['wlan1'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002741 if hostapd_5g.is_alive():
2742 hostapd_5g.stop()
2743 logging.debug('Turned WLAN1 AP%d off' % AP)
2744
2745
2746def turn_ap_on(test, AP):
2747 """Bring up hostapd on the Access Point.
2748 Args:
2749 test: The test class object.
2750 AP: int, indicating which AP to turn ON.
2751 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002752 hostapd_2g = test.access_points[AP - 1]._aps['wlan0'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002753 if not hostapd_2g.is_alive():
2754 hostapd_2g.start(hostapd_2g.config)
2755 logging.debug('Turned WLAN0 AP%d on' % AP)
Omar El Ayach8c017902020-10-18 10:26:57 -07002756 hostapd_5g = test.access_points[AP - 1]._aps['wlan1'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002757 if not hostapd_5g.is_alive():
2758 hostapd_5g.start(hostapd_5g.config)
2759 logging.debug('Turned WLAN1 AP%d on' % AP)
Joe Brennan48c3f692019-04-11 08:30:16 -07002760
2761
2762def turn_location_off_and_scan_toggle_off(ad):
2763 """Turns off wifi location scans."""
2764 utils.set_location_service(ad, False)
2765 ad.droid.wifiScannerToggleAlwaysAvailable(False)
2766 msg = "Failed to turn off location service's scan."
2767 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
Alfie Chen675be872020-06-04 10:48:14 +08002768
2769
2770def set_softap_channel(dut, ap_iface='wlan1', cs_count=10, channel=2462):
2771 """ Set SoftAP mode channel
2772
2773 Args:
2774 dut: android device object
2775 ap_iface: interface of SoftAP mode.
2776 cs_count: how many beacon frames before switch channel, default = 10
2777 channel: a wifi channel.
2778 """
2779 chan_switch_cmd = 'hostapd_cli -i {} chan_switch {} {}'
Omar El Ayach8c017902020-10-18 10:26:57 -07002780 chan_switch_cmd_show = chan_switch_cmd.format(ap_iface, cs_count, channel)
Alfie Chen675be872020-06-04 10:48:14 +08002781 dut.log.info('adb shell {}'.format(chan_switch_cmd_show))
Omar El Ayach8c017902020-10-18 10:26:57 -07002782 chan_switch_result = dut.adb.shell(
2783 chan_switch_cmd.format(ap_iface, cs_count, channel))
Alfie Chen675be872020-06-04 10:48:14 +08002784 if chan_switch_result == 'OK':
2785 dut.log.info('switch hotspot channel to {}'.format(channel))
2786 return chan_switch_result
2787
2788 asserts.fail("Failed to switch hotspot channel")
Alfie Chen310f7ff2021-01-26 20:36:09 +08002789
2790def get_wlan0_link(dut):
2791 """ get wlan0 interface status"""
2792 get_wlan0 = 'wpa_cli -iwlan0 -g@android:wpa_wlan0 IFNAME=wlan0 status'
2793 out = dut.adb.shell(get_wlan0)
2794 out = dict(re.findall(r'(\S+)=(".*?"|\S+)', out))
2795 asserts.assert_true("ssid" in out,
2796 "Client doesn't connect to any network")
Alfie Chenb3263dd2021-02-04 18:54:34 +08002797 return out