blob: a644a85788a8fb88d816b05e0be91f4883acbadc [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)
Ang Li73697b32015-12-03 00:41:53 +0000780
Ang Li82522812016-06-02 13:57:21 -0700781
Ang Li73697b32015-12-03 00:41:53 +0000782def wifi_test_device_init(ad):
783 """Initializes an android device for wifi testing.
784
785 0. Make sure SL4A connection is established on the android device.
786 1. Disable location service's WiFi scan.
787 2. Turn WiFi on.
788 3. Clear all saved networks.
789 4. Set country code to US.
790 5. Enable WiFi verbose logging.
791 6. Sync device time with computer time.
792 7. Turn off cellular data.
Ang Lifee28402016-07-13 13:43:29 -0700793 8. Turn off ambient display.
Ang Li73697b32015-12-03 00:41:53 +0000794 """
Ang Lifee28402016-07-13 13:43:29 -0700795 utils.require_sl4a((ad, ))
Ang Li73697b32015-12-03 00:41:53 +0000796 ad.droid.wifiScannerToggleAlwaysAvailable(False)
797 msg = "Failed to turn off location service's scan."
Ang Li82522812016-06-02 13:57:21 -0700798 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
799 wifi_toggle_state(ad, True)
Ang Li6b557182015-11-11 17:19:17 -0800800 reset_wifi(ad)
Ang Li73697b32015-12-03 00:41:53 +0000801 ad.droid.wifiEnableVerboseLogging(1)
Ang Li8e767182015-12-09 17:29:24 -0800802 msg = "Failed to enable WiFi verbose logging."
Ang Li82522812016-06-02 13:57:21 -0700803 asserts.assert_equal(ad.droid.wifiGetVerboseLoggingLevel(), 1, msg)
Ang Li73697b32015-12-03 00:41:53 +0000804 # We don't verify the following settings since they are not critical.
Ang Lie2e93a22016-06-22 16:43:28 -0700805 # Set wpa_supplicant log level to EXCESSIVE.
Omar El Ayach8c017902020-10-18 10:26:57 -0700806 output = ad.adb.shell(
807 "wpa_cli -i wlan0 -p -g@android:wpa_wlan0 IFNAME="
808 "wlan0 log_level EXCESSIVE",
809 ignore_status=True)
Ang Lie2e93a22016-06-22 16:43:28 -0700810 ad.log.info("wpa_supplicant log change status: %s", output)
Ang Lifee28402016-07-13 13:43:29 -0700811 utils.sync_device_time(ad)
Ang Li0bf8e022016-01-04 17:34:48 -0800812 ad.droid.telephonyToggleDataConnection(False)
Roshan Pius48df08c2019-09-13 08:07:30 -0700813 set_wifi_country_code(ad, WifiEnums.CountryCode.US)
Ang Lifee28402016-07-13 13:43:29 -0700814 utils.set_ambient_display(ad, False)
Ang Li73697b32015-12-03 00:41:53 +0000815
Omar El Ayach8c017902020-10-18 10:26:57 -0700816
Roshan Pius48df08c2019-09-13 08:07:30 -0700817def set_wifi_country_code(ad, country_code):
818 """Sets the wifi country code on the device.
819
820 Args:
821 ad: An AndroidDevice object.
822 country_code: 2 letter ISO country code
codycaldwell35b87182020-01-16 14:08:01 -0800823
824 Raises:
825 An RpcException if unable to set the country code.
Roshan Pius48df08c2019-09-13 08:07:30 -0700826 """
Jaineelc5b56a62019-10-10 17:12:02 -0700827 try:
codycaldwell35b87182020-01-16 14:08:01 -0800828 ad.adb.shell("cmd wifi force-country-code enabled %s" % country_code)
Jaineel Mehtacbad5cc2020-11-19 21:38:18 +0000829 except Exception as e:
Jaineelc5b56a62019-10-10 17:12:02 -0700830 ad.droid.wifiSetCountryCode(WifiEnums.CountryCode.US)
Roshan Pius48df08c2019-09-13 08:07:30 -0700831
Ang Li82522812016-06-02 13:57:21 -0700832
Ang Li6b557182015-11-11 17:19:17 -0800833def start_wifi_connection_scan(ad):
Ang Li73697b32015-12-03 00:41:53 +0000834 """Starts a wifi connection scan and wait for results to become available.
835
836 Args:
Ang Li6b557182015-11-11 17:19:17 -0800837 ad: An AndroidDevice object.
Ang Li73697b32015-12-03 00:41:53 +0000838 """
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800839 ad.ed.clear_all_events()
Ang Li6b557182015-11-11 17:19:17 -0800840 ad.droid.wifiStartScan()
Ang Li82522812016-06-02 13:57:21 -0700841 try:
842 ad.ed.pop_event("WifiManagerScanResultsAvailable", 60)
843 except Empty:
844 asserts.fail("Wi-Fi results did not become available within 60s.")
845
Ang Li73697b32015-12-03 00:41:53 +0000846
Roshan Piuscb9bc482018-02-01 14:27:09 -0800847def start_wifi_connection_scan_and_return_status(ad):
848 """
849 Starts a wifi connection scan and wait for results to become available
850 or a scan failure to be reported.
851
852 Args:
853 ad: An AndroidDevice object.
854 Returns:
855 True: if scan succeeded & results are available
856 False: if scan failed
857 """
858 ad.ed.clear_all_events()
859 ad.droid.wifiStartScan()
860 try:
Omar El Ayach8c017902020-10-18 10:26:57 -0700861 events = ad.ed.pop_events("WifiManagerScan(ResultsAvailable|Failure)",
862 60)
Roshan Piuscb9bc482018-02-01 14:27:09 -0800863 except Empty:
864 asserts.fail(
865 "Wi-Fi scan results/failure did not become available within 60s.")
866 # If there are multiple matches, we check for atleast one success.
867 for event in events:
868 if event["name"] == "WifiManagerScanResultsAvailable":
869 return True
870 elif event["name"] == "WifiManagerScanFailure":
871 ad.log.debug("Scan failure received")
872 return False
873
874
Omar El Ayach8c017902020-10-18 10:26:57 -0700875def start_wifi_connection_scan_and_check_for_network(ad,
876 network_ssid,
Roshan Piuscb9bc482018-02-01 14:27:09 -0800877 max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800878 """
879 Start connectivity scans & checks if the |network_ssid| is seen in
880 scan results. The method performs a max of |max_tries| connectivity scans
881 to find the network.
882
883 Args:
884 ad: An AndroidDevice object.
885 network_ssid: SSID of the network we are looking for.
886 max_tries: Number of scans to try.
887 Returns:
888 True: if network_ssid is found in scan results.
889 False: if network_ssid is not found in scan results.
890 """
891 for num_tries in range(max_tries):
Roshan Piuscb9bc482018-02-01 14:27:09 -0800892 if start_wifi_connection_scan_and_return_status(ad):
893 scan_results = ad.droid.wifiGetScanResults()
Omar El Ayach8c017902020-10-18 10:26:57 -0700894 match_results = match_networks({WifiEnums.SSID_KEY: network_ssid},
895 scan_results)
Roshan Piuscb9bc482018-02-01 14:27:09 -0800896 if len(match_results) > 0:
897 return True
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800898 return False
899
900
Omar El Ayach8c017902020-10-18 10:26:57 -0700901def start_wifi_connection_scan_and_ensure_network_found(
902 ad, network_ssid, max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800903 """
904 Start connectivity scans & ensure the |network_ssid| is seen in
905 scan results. The method performs a max of |max_tries| connectivity scans
906 to find the network.
907 This method asserts on failure!
908
909 Args:
910 ad: An AndroidDevice object.
911 network_ssid: SSID of the network we are looking for.
912 max_tries: Number of scans to try.
913 """
914 ad.log.info("Starting scans to ensure %s is present", network_ssid)
915 assert_msg = "Failed to find " + network_ssid + " in scan results" \
916 " after " + str(max_tries) + " tries"
Omar El Ayach8c017902020-10-18 10:26:57 -0700917 asserts.assert_true(
918 start_wifi_connection_scan_and_check_for_network(
919 ad, network_ssid, max_tries), assert_msg)
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800920
921
Omar El Ayach8c017902020-10-18 10:26:57 -0700922def start_wifi_connection_scan_and_ensure_network_not_found(
923 ad, network_ssid, max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800924 """
925 Start connectivity scans & ensure the |network_ssid| is not seen in
926 scan results. The method performs a max of |max_tries| connectivity scans
927 to find the network.
928 This method asserts on failure!
929
930 Args:
931 ad: An AndroidDevice object.
932 network_ssid: SSID of the network we are looking for.
933 max_tries: Number of scans to try.
934 """
935 ad.log.info("Starting scans to ensure %s is not present", network_ssid)
936 assert_msg = "Found " + network_ssid + " in scan results" \
937 " after " + str(max_tries) + " tries"
Omar El Ayach8c017902020-10-18 10:26:57 -0700938 asserts.assert_false(
939 start_wifi_connection_scan_and_check_for_network(
940 ad, network_ssid, max_tries), assert_msg)
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800941
942
Ang Li73697b32015-12-03 00:41:53 +0000943def start_wifi_background_scan(ad, scan_setting):
944 """Starts wifi background scan.
945
946 Args:
947 ad: android_device object to initiate connection on.
948 scan_setting: A dict representing the settings of the scan.
949
950 Returns:
951 If scan was started successfully, event data of success event is returned.
952 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700953 idx = ad.droid.wifiScannerStartBackgroundScan(scan_setting)
954 event = ad.ed.pop_event("WifiScannerScan{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -0800955 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +0000956 return event['data']
957
Ang Li82522812016-06-02 13:57:21 -0700958
Girish Moturu38b993c2021-03-25 13:03:50 -0700959def start_wifi_tethering(ad, ssid, password, band=None, hidden=None,
960 security=None):
Ang Li73697b32015-12-03 00:41:53 +0000961 """Starts wifi tethering on an android_device.
962
963 Args:
964 ad: android_device to start wifi tethering on.
965 ssid: The SSID the soft AP should broadcast.
966 password: The password the soft AP should use.
967 band: The band the soft AP should be set on. It should be either
968 WifiEnums.WIFI_CONFIG_APBAND_2G or WifiEnums.WIFI_CONFIG_APBAND_5G.
Roshan Piusce821342018-01-10 11:03:04 -0800969 hidden: boolean to indicate if the AP needs to be hidden or not.
Girish Moturu38b993c2021-03-25 13:03:50 -0700970 security: security type of softap.
Ang Li73697b32015-12-03 00:41:53 +0000971
972 Returns:
Girish Moturu3581d612016-11-02 15:08:51 -0700973 No return value. Error checks in this function will raise test failure signals
Ang Li73697b32015-12-03 00:41:53 +0000974 """
Ang Li82522812016-06-02 13:57:21 -0700975 config = {WifiEnums.SSID_KEY: ssid}
Ang Li73697b32015-12-03 00:41:53 +0000976 if password:
977 config[WifiEnums.PWD_KEY] = password
978 if band:
lesl6d30a172020-03-05 15:05:22 +0800979 config[WifiEnums.AP_BAND_KEY] = band
Roshan Piusce821342018-01-10 11:03:04 -0800980 if hidden:
Omar El Ayach8c017902020-10-18 10:26:57 -0700981 config[WifiEnums.HIDDEN_KEY] = hidden
Girish Moturu38b993c2021-03-25 13:03:50 -0700982 if security:
983 config[WifiEnums.SECURITY] = security
Omar El Ayach8c017902020-10-18 10:26:57 -0700984 asserts.assert_true(ad.droid.wifiSetWifiApConfiguration(config),
985 "Failed to update WifiAp Configuration")
Girish Moturu40d7dc22016-11-02 12:14:56 -0700986 ad.droid.wifiStartTrackingTetherStateChange()
987 ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
Rebecca Silbersteina2889852016-08-11 00:48:53 -0700988 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700989 ad.ed.pop_event("ConnectivityManagerOnTetheringStarted")
990 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -0800991 lambda x: x["data"]["ACTIVE_TETHER"], 30)
Ang Li76216d12016-09-20 14:51:57 -0700992 ad.log.debug("Tethering started successfully.")
Rebecca Silbersteina2889852016-08-11 00:48:53 -0700993 except Empty:
994 msg = "Failed to receive confirmation of wifi tethering starting"
995 asserts.fail(msg)
996 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700997 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li73697b32015-12-03 00:41:53 +0000998
Bindu Mahadevff295782019-02-08 16:17:48 -0800999
Omar El Ayach8c017902020-10-18 10:26:57 -07001000def save_wifi_soft_ap_config(ad,
1001 wifi_config,
1002 band=None,
1003 hidden=None,
1004 security=None,
1005 password=None,
1006 channel=None,
1007 max_clients=None,
lesl6d30a172020-03-05 15:05:22 +08001008 shutdown_timeout_enable=None,
1009 shutdown_timeout_millis=None,
1010 client_control_enable=None,
Omar El Ayach8c017902020-10-18 10:26:57 -07001011 allowedList=None,
lesl67124362021-05-04 19:33:14 +08001012 blockedList=None,
1013 bands=None,
1014 channel_frequencys=None,
1015 mac_randomization_setting=None,
1016 bridged_opportunistic_shutdown_enabled=None,
1017 ieee80211ax_enabled=None):
lesl6d30a172020-03-05 15:05:22 +08001018 """ Save a soft ap configuration and verified
1019 Args:
1020 ad: android_device to set soft ap configuration.
1021 wifi_config: a soft ap configuration object, at least include SSID.
1022 band: specifies the band for the soft ap.
1023 hidden: specifies the soft ap need to broadcast its SSID or not.
1024 security: specifies the security type for the soft ap.
1025 password: specifies the password for the soft ap.
1026 channel: specifies the channel for the soft ap.
1027 max_clients: specifies the maximum connected client number.
1028 shutdown_timeout_enable: specifies the auto shut down enable or not.
1029 shutdown_timeout_millis: specifies the shut down timeout value.
1030 client_control_enable: specifies the client control enable or not.
1031 allowedList: specifies allowed clients list.
1032 blockedList: specifies blocked clients list.
lesl67124362021-05-04 19:33:14 +08001033 bands: specifies the band list for the soft ap.
1034 channel_frequencys: specifies the channel frequency list for soft ap.
1035 mac_randomization_setting: specifies the mac randomization setting.
1036 bridged_opportunistic_shutdown_enabled: specifies the opportunistic
1037 shutdown enable or not.
1038 ieee80211ax_enabled: specifies the ieee80211ax enable or not.
lesl6d30a172020-03-05 15:05:22 +08001039 """
1040 if security and password:
Omar El Ayach8c017902020-10-18 10:26:57 -07001041 wifi_config[WifiEnums.SECURITY] = security
1042 wifi_config[WifiEnums.PWD_KEY] = password
lesl67124362021-05-04 19:33:14 +08001043 if hidden is not None:
Girish Moturu528b5442018-06-07 10:48:14 -07001044 wifi_config[WifiEnums.HIDDEN_KEY] = hidden
lesl67124362021-05-04 19:33:14 +08001045 if max_clients is not None:
lesl6d30a172020-03-05 15:05:22 +08001046 wifi_config[WifiEnums.AP_MAXCLIENTS_KEY] = max_clients
lesl67124362021-05-04 19:33:14 +08001047 if shutdown_timeout_enable is not None:
lesl6d30a172020-03-05 15:05:22 +08001048 wifi_config[
1049 WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] = shutdown_timeout_enable
lesl67124362021-05-04 19:33:14 +08001050 if shutdown_timeout_millis is not None:
Omar El Ayach8c017902020-10-18 10:26:57 -07001051 wifi_config[WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] = shutdown_timeout_millis
lesl67124362021-05-04 19:33:14 +08001052 if client_control_enable is not None:
lesl6d30a172020-03-05 15:05:22 +08001053 wifi_config[WifiEnums.AP_CLIENTCONTROL_KEY] = client_control_enable
lesl67124362021-05-04 19:33:14 +08001054 if allowedList is not None:
lesl6d30a172020-03-05 15:05:22 +08001055 wifi_config[WifiEnums.AP_ALLOWEDLIST_KEY] = allowedList
lesl67124362021-05-04 19:33:14 +08001056 if blockedList is not None:
lesl6d30a172020-03-05 15:05:22 +08001057 wifi_config[WifiEnums.AP_BLOCKEDLIST_KEY] = blockedList
lesl67124362021-05-04 19:33:14 +08001058 if mac_randomization_setting is not None:
1059 wifi_config[WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY
1060 ] = mac_randomization_setting
1061 if bridged_opportunistic_shutdown_enabled is not None:
1062 wifi_config[WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY
1063 ] = bridged_opportunistic_shutdown_enabled
1064 if ieee80211ax_enabled is not None:
1065 wifi_config[WifiEnums.AP_IEEE80211AX_ENABLED_KEY]= ieee80211ax_enabled
1066 if channel_frequencys is not None:
1067 wifi_config[WifiEnums.AP_CHANNEL_FREQUENCYS_KEY] = channel_frequencys
1068 elif bands is not None:
1069 wifi_config[WifiEnums.AP_BANDS_KEY] = bands
1070 elif band is not None:
1071 if channel is not None:
1072 wifi_config[WifiEnums.AP_BAND_KEY] = band
1073 wifi_config[WifiEnums.AP_CHANNEL_KEY] = channel
1074 else:
1075 wifi_config[WifiEnums.AP_BAND_KEY] = band
lesl6d30a172020-03-05 15:05:22 +08001076
1077 if WifiEnums.AP_CHANNEL_KEY in wifi_config and wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001078 WifiEnums.AP_CHANNEL_KEY] == 0:
lesl6d30a172020-03-05 15:05:22 +08001079 del wifi_config[WifiEnums.AP_CHANNEL_KEY]
1080
1081 if WifiEnums.SECURITY in wifi_config and wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001082 WifiEnums.SECURITY] == WifiEnums.SoftApSecurityType.OPEN:
lesl6d30a172020-03-05 15:05:22 +08001083 del wifi_config[WifiEnums.SECURITY]
1084 del wifi_config[WifiEnums.PWD_KEY]
1085
Girish Moturu528b5442018-06-07 10:48:14 -07001086 asserts.assert_true(ad.droid.wifiSetWifiApConfiguration(wifi_config),
1087 "Failed to set WifiAp Configuration")
1088
1089 wifi_ap = ad.droid.wifiGetApConfiguration()
1090 asserts.assert_true(
1091 wifi_ap[WifiEnums.SSID_KEY] == wifi_config[WifiEnums.SSID_KEY],
lesl6d30a172020-03-05 15:05:22 +08001092 "Hotspot SSID doesn't match")
1093 if WifiEnums.SECURITY in wifi_config:
1094 asserts.assert_true(
1095 wifi_ap[WifiEnums.SECURITY] == wifi_config[WifiEnums.SECURITY],
1096 "Hotspot Security doesn't match")
1097 if WifiEnums.PWD_KEY in wifi_config:
1098 asserts.assert_true(
1099 wifi_ap[WifiEnums.PWD_KEY] == wifi_config[WifiEnums.PWD_KEY],
1100 "Hotspot Password doesn't match")
Girish Moturu528b5442018-06-07 10:48:14 -07001101
lesl6d30a172020-03-05 15:05:22 +08001102 if WifiEnums.HIDDEN_KEY in wifi_config:
1103 asserts.assert_true(
1104 wifi_ap[WifiEnums.HIDDEN_KEY] == wifi_config[WifiEnums.HIDDEN_KEY],
1105 "Hotspot hidden setting doesn't match")
1106
lesl6d30a172020-03-05 15:05:22 +08001107 if WifiEnums.AP_CHANNEL_KEY in wifi_config:
1108 asserts.assert_true(
1109 wifi_ap[WifiEnums.AP_CHANNEL_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001110 WifiEnums.AP_CHANNEL_KEY], "Hotspot Channel doesn't match")
lesl6d30a172020-03-05 15:05:22 +08001111 if WifiEnums.AP_MAXCLIENTS_KEY in wifi_config:
1112 asserts.assert_true(
1113 wifi_ap[WifiEnums.AP_MAXCLIENTS_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001114 WifiEnums.AP_MAXCLIENTS_KEY],
1115 "Hotspot Max Clients doesn't match")
lesl6d30a172020-03-05 15:05:22 +08001116 if WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY in wifi_config:
1117 asserts.assert_true(
1118 wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001119 WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY],
lesl6d30a172020-03-05 15:05:22 +08001120 "Hotspot ShutDown feature flag doesn't match")
1121 if WifiEnums.AP_SHUTDOWNTIMEOUT_KEY in wifi_config:
1122 asserts.assert_true(
1123 wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001124 WifiEnums.AP_SHUTDOWNTIMEOUT_KEY],
lesl6d30a172020-03-05 15:05:22 +08001125 "Hotspot ShutDown timeout setting doesn't match")
1126 if WifiEnums.AP_CLIENTCONTROL_KEY in wifi_config:
1127 asserts.assert_true(
1128 wifi_ap[WifiEnums.AP_CLIENTCONTROL_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001129 WifiEnums.AP_CLIENTCONTROL_KEY],
lesl6d30a172020-03-05 15:05:22 +08001130 "Hotspot Client control flag doesn't match")
1131 if WifiEnums.AP_ALLOWEDLIST_KEY in wifi_config:
1132 asserts.assert_true(
1133 wifi_ap[WifiEnums.AP_ALLOWEDLIST_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001134 WifiEnums.AP_ALLOWEDLIST_KEY],
lesl6d30a172020-03-05 15:05:22 +08001135 "Hotspot Allowed List doesn't match")
1136 if WifiEnums.AP_BLOCKEDLIST_KEY in wifi_config:
1137 asserts.assert_true(
1138 wifi_ap[WifiEnums.AP_BLOCKEDLIST_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001139 WifiEnums.AP_BLOCKEDLIST_KEY],
lesl6d30a172020-03-05 15:05:22 +08001140 "Hotspot Blocked List doesn't match")
Bindu Mahadevff295782019-02-08 16:17:48 -08001141
lesl67124362021-05-04 19:33:14 +08001142 if WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY in wifi_config:
1143 asserts.assert_true(
1144 wifi_ap[WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY] == wifi_config[
1145 WifiEnums.AP_MAC_RANDOMIZATION_SETTING_KEY],
1146 "Hotspot Mac randomization setting doesn't match")
1147
1148 if WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY in wifi_config:
1149 asserts.assert_true(
1150 wifi_ap[WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY] == wifi_config[
1151 WifiEnums.AP_BRIDGED_OPPORTUNISTIC_SHUTDOWN_ENABLE_KEY],
1152 "Hotspot bridged shutdown enable setting doesn't match")
1153
1154 if WifiEnums.AP_IEEE80211AX_ENABLED_KEY in wifi_config:
1155 asserts.assert_true(
1156 wifi_ap[WifiEnums.AP_IEEE80211AX_ENABLED_KEY] == wifi_config[
1157 WifiEnums.AP_IEEE80211AX_ENABLED_KEY],
1158 "Hotspot 80211 AX enable setting doesn't match")
1159
1160 if WifiEnums.AP_CHANNEL_FREQUENCYS_KEY in wifi_config:
1161 asserts.assert_true(
1162 wifi_ap[WifiEnums.AP_CHANNEL_FREQUENCYS_KEY] == wifi_config[
1163 WifiEnums.AP_CHANNEL_FREQUENCYS_KEY],
1164 "Hotspot channels setting doesn't match")
Omar El Ayach8c017902020-10-18 10:26:57 -07001165
Girish Moturu528b5442018-06-07 10:48:14 -07001166def start_wifi_tethering_saved_config(ad):
1167 """ Turn on wifi hotspot with a config that is already saved """
1168 ad.droid.wifiStartTrackingTetherStateChange()
1169 ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
1170 try:
1171 ad.ed.pop_event("ConnectivityManagerOnTetheringStarted")
1172 ad.ed.wait_for_event("TetherStateChanged",
1173 lambda x: x["data"]["ACTIVE_TETHER"], 30)
1174 except:
1175 asserts.fail("Didn't receive wifi tethering starting confirmation")
1176 finally:
1177 ad.droid.wifiStopTrackingTetherStateChange()
Betty Zhou3caa0982017-02-22 19:26:20 -08001178
Bindu Mahadevff295782019-02-08 16:17:48 -08001179
Ang Li73697b32015-12-03 00:41:53 +00001180def stop_wifi_tethering(ad):
1181 """Stops wifi tethering on an android_device.
Ang Li73697b32015-12-03 00:41:53 +00001182 Args:
1183 ad: android_device to stop wifi tethering on.
1184 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001185 ad.droid.wifiStartTrackingTetherStateChange()
1186 ad.droid.connectivityStopTethering(tel_defines.TETHERING_WIFI)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001187 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001188 ad.ed.pop_event("WifiManagerApDisabled", 30)
1189 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -08001190 lambda x: not x["data"]["ACTIVE_TETHER"], 30)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001191 except Empty:
1192 msg = "Failed to receive confirmation of wifi tethering stopping"
1193 asserts.fail(msg)
1194 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001195 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li82522812016-06-02 13:57:21 -07001196
Ang Li76216d12016-09-20 14:51:57 -07001197
Roshan Pius58916a32016-06-16 16:26:44 -07001198def toggle_wifi_and_wait_for_reconnection(ad,
1199 network,
1200 num_of_tries=1,
1201 assert_on_fail=True):
1202 """Toggle wifi state and then wait for Android device to reconnect to
1203 the provided wifi network.
1204
1205 This expects the device to be already connected to the provided network.
1206
1207 Logic steps are
1208 1. Ensure that we're connected to the network.
1209 2. Turn wifi off.
1210 3. Wait for 10 seconds.
1211 4. Turn wifi on.
1212 5. Wait for the "connected" event, then confirm the connected ssid is the
1213 one requested.
1214
1215 Args:
1216 ad: android_device object to initiate connection on.
1217 network: A dictionary representing the network to await connection. The
1218 dictionary must have the key "SSID".
1219 num_of_tries: An integer that is the number of times to try before
1220 delaring failure. Default is 1.
1221 assert_on_fail: If True, error checks in this function will raise test
1222 failure signals.
1223
1224 Returns:
1225 If assert_on_fail is False, function returns True if the toggle was
1226 successful, False otherwise. If assert_on_fail is True, no return value.
1227 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001228 return _assert_on_fail_handler(_toggle_wifi_and_wait_for_reconnection,
1229 assert_on_fail,
1230 ad,
1231 network,
1232 num_of_tries=num_of_tries)
Roshan Pius58916a32016-06-16 16:26:44 -07001233
1234
Girish Moturu5d9f4202019-12-03 15:29:21 -08001235def _toggle_wifi_and_wait_for_reconnection(ad, network, num_of_tries=3):
Roshan Pius58916a32016-06-16 16:26:44 -07001236 """Toggle wifi state and then wait for Android device to reconnect to
1237 the provided wifi network.
1238
1239 This expects the device to be already connected to the provided network.
1240
1241 Logic steps are
1242 1. Ensure that we're connected to the network.
1243 2. Turn wifi off.
1244 3. Wait for 10 seconds.
1245 4. Turn wifi on.
1246 5. Wait for the "connected" event, then confirm the connected ssid is the
1247 one requested.
1248
1249 This will directly fail a test if anything goes wrong.
1250
1251 Args:
1252 ad: android_device object to initiate connection on.
1253 network: A dictionary representing the network to await connection. The
1254 dictionary must have the key "SSID".
1255 num_of_tries: An integer that is the number of times to try before
1256 delaring failure. Default is 1.
1257 """
Roshan Pius58916a32016-06-16 16:26:44 -07001258 expected_ssid = network[WifiEnums.SSID_KEY]
1259 # First ensure that we're already connected to the provided network.
1260 verify_con = {WifiEnums.SSID_KEY: expected_ssid}
1261 verify_wifi_connection_info(ad, verify_con)
1262 # Now toggle wifi state and wait for the connection event.
1263 wifi_toggle_state(ad, False)
1264 time.sleep(10)
1265 wifi_toggle_state(ad, True)
1266 ad.droid.wifiStartTrackingStateChange()
1267 try:
1268 connect_result = None
1269 for i in range(num_of_tries):
1270 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -08001271 connect_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
Roshan Pius58916a32016-06-16 16:26:44 -07001272 30)
1273 break
1274 except Empty:
1275 pass
Omar El Ayach8c017902020-10-18 10:26:57 -07001276 asserts.assert_true(
1277 connect_result, "Failed to connect to Wi-Fi network %s on %s" %
1278 (network, ad.serial))
Betty Zhou3caa0982017-02-22 19:26:20 -08001279 logging.debug("Connection result on %s: %s.", ad.serial,
1280 connect_result)
Roshan Pius58916a32016-06-16 16:26:44 -07001281 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001282 asserts.assert_equal(
1283 actual_ssid, expected_ssid, "Connected to the wrong network on %s."
1284 "Expected %s, but got %s." %
1285 (ad.serial, expected_ssid, actual_ssid))
Betty Zhou3caa0982017-02-22 19:26:20 -08001286 logging.info("Connected to Wi-Fi network %s on %s", actual_ssid,
1287 ad.serial)
Roshan Pius58916a32016-06-16 16:26:44 -07001288 finally:
1289 ad.droid.wifiStopTrackingStateChange()
1290
1291
Omar El Ayach8c017902020-10-18 10:26:57 -07001292def wait_for_connect(ad,
1293 expected_ssid=None,
1294 expected_id=None,
1295 tries=2,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001296 assert_on_fail=True):
Roshan Piusd1204442018-11-12 12:20:39 -08001297 """Wait for a connect event.
1298
1299 This will directly fail a test if anything goes wrong.
1300
1301 Args:
1302 ad: An Android device object.
1303 expected_ssid: SSID of the network to connect to.
1304 expected_id: Network Id of the network to connect to.
1305 tries: An integer that is the number of times to try before failing.
1306 assert_on_fail: If True, error checks in this function will raise test
1307 failure signals.
1308
1309 Returns:
1310 Returns a value only if assert_on_fail is false.
1311 Returns True if the connection was successful, False otherwise.
1312 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001313 return _assert_on_fail_handler(_wait_for_connect, assert_on_fail, ad,
1314 expected_ssid, expected_id, tries)
Roshan Piusd1204442018-11-12 12:20:39 -08001315
1316
Oscar Shucb9af9b2019-05-02 20:01:49 +00001317def _wait_for_connect(ad, expected_ssid=None, expected_id=None, tries=2):
Roshan Piusd1204442018-11-12 12:20:39 -08001318 """Wait for a connect event.
1319
1320 Args:
1321 ad: An Android device object.
1322 expected_ssid: SSID of the network to connect to.
1323 expected_id: Network Id of the network to connect to.
1324 tries: An integer that is the number of times to try before failing.
1325 """
1326 ad.droid.wifiStartTrackingStateChange()
1327 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001328 connect_result = _wait_for_connect_event(ad,
1329 ssid=expected_ssid,
1330 id=expected_id,
1331 tries=tries)
1332 asserts.assert_true(
1333 connect_result,
1334 "Failed to connect to Wi-Fi network %s" % expected_ssid)
Roshan Piusd1204442018-11-12 12:20:39 -08001335 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
1336 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1337 if expected_ssid:
1338 asserts.assert_equal(actual_ssid, expected_ssid,
1339 "Connected to the wrong network")
1340 actual_id = connect_result['data'][WifiEnums.NETID_KEY]
1341 if expected_id:
1342 asserts.assert_equal(actual_id, expected_id,
1343 "Connected to the wrong network")
1344 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
1345 except Empty:
1346 asserts.fail("Failed to start connection process to %s" %
1347 expected_ssid)
1348 except Exception as error:
1349 ad.log.error("Failed to connect to %s with error %s", expected_ssid,
1350 error)
1351 raise signals.TestFailure("Failed to connect to %s network" %
1352 expected_ssid)
1353 finally:
1354 ad.droid.wifiStopTrackingStateChange()
1355
1356
Oscar Shucb9af9b2019-05-02 20:01:49 +00001357def _wait_for_connect_event(ad, ssid=None, id=None, tries=1):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001358 """Wait for a connect event on queue and pop when available.
1359
1360 Args:
1361 ad: An Android device object.
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001362 ssid: SSID of the network to connect to.
1363 id: Network Id of the network to connect to.
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001364 tries: An integer that is the number of times to try before failing.
1365
1366 Returns:
1367 A dict with details of the connection data, which looks like this:
1368 {
1369 'time': 1485460337798,
1370 'name': 'WifiNetworkConnected',
1371 'data': {
1372 'rssi': -27,
1373 'is_24ghz': True,
1374 'mac_address': '02:00:00:00:00:00',
1375 'network_id': 1,
1376 'BSSID': '30:b5:c2:33:d3:fc',
1377 'ip_address': 117483712,
1378 'link_speed': 54,
1379 'supplicant_state': 'completed',
1380 'hidden_ssid': False,
1381 'SSID': 'wh_ap1_2g',
1382 'is_5ghz': False}
1383 }
1384
1385 """
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001386 conn_result = None
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001387
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001388 # If ssid and network id is None, just wait for any connect event.
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001389 if id is None and ssid is None:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001390 for i in range(tries):
1391 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001392 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
1393 30)
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001394 break
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001395 except Empty:
1396 pass
1397 else:
Omar El Ayach8c017902020-10-18 10:26:57 -07001398 # If ssid or network id is specified, wait for specific connect event.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001399 for i in range(tries):
1400 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001401 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
1402 30)
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001403 if id and conn_result['data'][WifiEnums.NETID_KEY] == id:
1404 break
1405 elif ssid and conn_result['data'][WifiEnums.SSID_KEY] == ssid:
1406 break
1407 except Empty:
1408 pass
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001409
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001410 return conn_result
1411
Bindu Mahadevff295782019-02-08 16:17:48 -08001412
Roshan Piusffc29912019-01-18 13:39:49 -08001413def wait_for_disconnect(ad, timeout=10):
1414 """Wait for a disconnect event within the specified timeout.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001415
1416 Args:
1417 ad: Android device object.
Roshan Piusffc29912019-01-18 13:39:49 -08001418 timeout: Timeout in seconds.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001419
1420 """
1421 try:
1422 ad.droid.wifiStartTrackingStateChange()
Roshan Piusffc29912019-01-18 13:39:49 -08001423 event = ad.ed.pop_event("WifiNetworkDisconnected", timeout)
Roshan Piusbf7e3982018-02-15 12:37:41 -08001424 except Empty:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001425 raise signals.TestFailure("Device did not disconnect from the network")
Roshan Piusffc29912019-01-18 13:39:49 -08001426 finally:
1427 ad.droid.wifiStopTrackingStateChange()
1428
1429
1430def ensure_no_disconnect(ad, duration=10):
1431 """Ensure that there is no disconnect for the specified duration.
1432
1433 Args:
1434 ad: Android device object.
1435 duration: Duration in seconds.
1436
1437 """
1438 try:
1439 ad.droid.wifiStartTrackingStateChange()
1440 event = ad.ed.pop_event("WifiNetworkDisconnected", duration)
1441 raise signals.TestFailure("Device disconnected from the network")
1442 except Empty:
1443 pass
1444 finally:
1445 ad.droid.wifiStopTrackingStateChange()
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001446
1447
Omar El Ayach8c017902020-10-18 10:26:57 -07001448def connect_to_wifi_network(ad,
1449 network,
1450 assert_on_fail=True,
1451 check_connectivity=True,
1452 hidden=False):
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001453 """Connection logic for open and psk wifi networks.
1454
1455 Args:
Jong Wook Kim92356922018-02-06 18:32:49 -08001456 ad: AndroidDevice to use for connection
1457 network: network info of the network to connect to
1458 assert_on_fail: If true, errors from wifi_connect will raise
1459 test failure signals.
Joe Brennan48c3f692019-04-11 08:30:16 -07001460 hidden: Is the Wifi network hidden.
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001461 """
Joe Brennan48c3f692019-04-11 08:30:16 -07001462 if hidden:
1463 start_wifi_connection_scan_and_ensure_network_not_found(
1464 ad, network[WifiEnums.SSID_KEY])
1465 else:
1466 start_wifi_connection_scan_and_ensure_network_found(
1467 ad, network[WifiEnums.SSID_KEY])
Jong Wook Kim92356922018-02-06 18:32:49 -08001468 wifi_connect(ad,
1469 network,
1470 num_of_tries=3,
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001471 assert_on_fail=assert_on_fail,
1472 check_connectivity=check_connectivity)
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001473
1474
1475def connect_to_wifi_network_with_id(ad, network_id, network_ssid):
1476 """Connect to the given network using network id and verify SSID.
1477
1478 Args:
1479 network_id: int Network Id of the network.
1480 network_ssid: string SSID of the network.
1481
1482 Returns: True if connect using network id was successful;
1483 False otherwise.
1484
1485 """
Jong Wook Kim92356922018-02-06 18:32:49 -08001486 start_wifi_connection_scan_and_ensure_network_found(ad, network_ssid)
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001487 wifi_connect_by_id(ad, network_id)
1488 connect_data = ad.droid.wifiGetConnectionInfo()
1489 connect_ssid = connect_data[WifiEnums.SSID_KEY]
1490 ad.log.debug("Expected SSID = %s Connected SSID = %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001491 (network_ssid, connect_ssid))
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001492 if connect_ssid != network_ssid:
1493 return False
1494 return True
1495
1496
Omar El Ayach8c017902020-10-18 10:26:57 -07001497def wifi_connect(ad,
1498 network,
1499 num_of_tries=1,
1500 assert_on_fail=True,
1501 check_connectivity=True):
Ang Li99d8c6d2015-12-09 15:56:13 -08001502 """Connect an Android device to a wifi network.
Ang Li73697b32015-12-03 00:41:53 +00001503
1504 Initiate connection to a wifi network, wait for the "connected" event, then
Ang Li99d8c6d2015-12-09 15:56:13 -08001505 confirm the connected ssid is the one requested.
Ang Li73697b32015-12-03 00:41:53 +00001506
Ang Li82522812016-06-02 13:57:21 -07001507 This will directly fail a test if anything goes wrong.
1508
Ang Li73697b32015-12-03 00:41:53 +00001509 Args:
1510 ad: android_device object to initiate connection on.
Ang Li99d8c6d2015-12-09 15:56:13 -08001511 network: A dictionary representing the network to connect to. The
Ang Li82522812016-06-02 13:57:21 -07001512 dictionary must have the key "SSID".
1513 num_of_tries: An integer that is the number of times to try before
1514 delaring failure. Default is 1.
1515 assert_on_fail: If True, error checks in this function will raise test
1516 failure signals.
1517
1518 Returns:
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001519 Returns a value only if assert_on_fail is false.
1520 Returns True if the connection was successful, False otherwise.
Ang Li73697b32015-12-03 00:41:53 +00001521 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001522 return _assert_on_fail_handler(_wifi_connect,
1523 assert_on_fail,
1524 ad,
1525 network,
1526 num_of_tries=num_of_tries,
1527 check_connectivity=check_connectivity)
Ang Li82522812016-06-02 13:57:21 -07001528
1529
Oscar Shucb9af9b2019-05-02 20:01:49 +00001530def _wifi_connect(ad, network, num_of_tries=1, check_connectivity=True):
Ang Li82522812016-06-02 13:57:21 -07001531 """Connect an Android device to a wifi network.
1532
1533 Initiate connection to a wifi network, wait for the "connected" event, then
1534 confirm the connected ssid is the one requested.
1535
1536 This will directly fail a test if anything goes wrong.
1537
1538 Args:
1539 ad: android_device object to initiate connection on.
1540 network: A dictionary representing the network to connect to. The
1541 dictionary must have the key "SSID".
1542 num_of_tries: An integer that is the number of times to try before
1543 delaring failure. Default is 1.
1544 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001545 asserts.assert_true(
1546 WifiEnums.SSID_KEY in network,
1547 "Key '%s' must be present in network definition." % WifiEnums.SSID_KEY)
Ang Li99d8c6d2015-12-09 15:56:13 -08001548 ad.droid.wifiStartTrackingStateChange()
Betty Zhoud35dab82016-12-06 15:24:23 -08001549 expected_ssid = network[WifiEnums.SSID_KEY]
Bindu Mahadev50374df2017-01-04 11:03:32 -08001550 ad.droid.wifiConnectByConfig(network)
1551 ad.log.info("Starting connection process to %s", expected_ssid)
Ang Li73697b32015-12-03 00:41:53 +00001552 try:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001553 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_CONFIG_SUCCESS, 30)
Omar El Ayach8c017902020-10-18 10:26:57 -07001554 connect_result = _wait_for_connect_event(ad,
1555 ssid=expected_ssid,
1556 tries=num_of_tries)
1557 asserts.assert_true(
1558 connect_result, "Failed to connect to Wi-Fi network %s on %s" %
1559 (network, ad.serial))
Ang Li31b00782016-06-21 13:04:23 -07001560 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
Ang Li99d8c6d2015-12-09 15:56:13 -08001561 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001562 asserts.assert_equal(
1563 actual_ssid, expected_ssid,
1564 "Connected to the wrong network on %s." % ad.serial)
Ang Li31b00782016-06-21 13:04:23 -07001565 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
Bindu Mahadev50374df2017-01-04 11:03:32 -08001566
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001567 if check_connectivity:
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08001568 internet = validate_connection(ad, DEFAULT_PING_ADDR)
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001569 if not internet:
Omar El Ayach8c017902020-10-18 10:26:57 -07001570 raise signals.TestFailure(
1571 "Failed to connect to internet on %s" % expected_ssid)
Bindu Mahadev50374df2017-01-04 11:03:32 -08001572 except Empty:
1573 asserts.fail("Failed to start connection process to %s on %s" %
1574 (network, ad.serial))
Bindu Mahadev4e710362016-11-17 16:17:11 -08001575 except Exception as error:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001576 ad.log.error("Failed to connect to %s with error %s", expected_ssid,
1577 error)
1578 raise signals.TestFailure("Failed to connect to %s network" % network)
1579
Ang Li73697b32015-12-03 00:41:53 +00001580 finally:
Ang Li99d8c6d2015-12-09 15:56:13 -08001581 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001582
Bindu Mahadev50374df2017-01-04 11:03:32 -08001583
Oscar Shucb9af9b2019-05-02 20:01:49 +00001584def wifi_connect_by_id(ad, network_id, num_of_tries=3, assert_on_fail=True):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001585 """Connect an Android device to a wifi network using network Id.
1586
1587 Start connection to the wifi network, with the given network Id, wait for
1588 the "connected" event, then verify the connected network is the one requested.
1589
1590 This will directly fail a test if anything goes wrong.
1591
1592 Args:
1593 ad: android_device object to initiate connection on.
1594 network_id: Integer specifying the network id of the network.
1595 num_of_tries: An integer that is the number of times to try before
1596 delaring failure. Default is 1.
1597 assert_on_fail: If True, error checks in this function will raise test
1598 failure signals.
1599
1600 Returns:
1601 Returns a value only if assert_on_fail is false.
1602 Returns True if the connection was successful, False otherwise.
1603 """
1604 _assert_on_fail_handler(_wifi_connect_by_id, assert_on_fail, ad,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001605 network_id, num_of_tries)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001606
1607
Oscar Shucb9af9b2019-05-02 20:01:49 +00001608def _wifi_connect_by_id(ad, network_id, num_of_tries=1):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001609 """Connect an Android device to a wifi network using it's network id.
1610
1611 Start connection to the wifi network, with the given network id, wait for
1612 the "connected" event, then verify the connected network is the one requested.
1613
1614 Args:
1615 ad: android_device object to initiate connection on.
1616 network_id: Integer specifying the network id of the network.
1617 num_of_tries: An integer that is the number of times to try before
1618 delaring failure. Default is 1.
1619 """
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001620 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001621 # Clear all previous events.
1622 ad.ed.clear_all_events()
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001623 ad.droid.wifiConnectByNetworkId(network_id)
1624 ad.log.info("Starting connection to network with id %d", network_id)
1625 try:
1626 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_NETID_SUCCESS, 60)
Omar El Ayach8c017902020-10-18 10:26:57 -07001627 connect_result = _wait_for_connect_event(ad,
1628 id=network_id,
1629 tries=num_of_tries)
1630 asserts.assert_true(
1631 connect_result,
1632 "Failed to connect to Wi-Fi network using network id")
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001633 ad.log.debug("Wi-Fi connection result: %s", connect_result)
1634 actual_id = connect_result['data'][WifiEnums.NETID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001635 asserts.assert_equal(
1636 actual_id, network_id, "Connected to the wrong network on %s."
1637 "Expected network id = %d, but got %d." %
1638 (ad.serial, network_id, actual_id))
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001639 expected_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1640 ad.log.info("Connected to Wi-Fi network %s with %d network id.",
Omar El Ayach8c017902020-10-18 10:26:57 -07001641 expected_ssid, network_id)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001642
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001643 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1644 if not internet:
1645 raise signals.TestFailure("Failed to connect to internet on %s" %
1646 expected_ssid)
1647 except Empty:
1648 asserts.fail("Failed to connect to network with id %d on %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001649 (network_id, ad.serial))
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001650 except Exception as error:
1651 ad.log.error("Failed to connect to network with id %d with error %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07001652 network_id, error)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001653 raise signals.TestFailure("Failed to connect to network with network"
1654 " id %d" % network_id)
1655 finally:
1656 ad.droid.wifiStopTrackingStateChange()
1657
Oscar Shu0b5ff4d2019-08-07 18:11:56 +00001658
Omar El Ayach8c017902020-10-18 10:26:57 -07001659def wifi_connect_using_network_request(ad,
1660 network,
1661 network_specifier,
Roshan Pius5561d232021-01-22 16:34:39 -08001662 num_of_tries=3):
Roshan Piusc999e5e2018-11-09 10:59:52 -08001663 """Connect an Android device to a wifi network using network request.
1664
1665 Trigger a network request with the provided network specifier,
1666 wait for the "onMatch" event, ensure that the scan results in "onMatch"
1667 event contain the specified network, then simulate the user granting the
1668 request with the specified network selected. Then wait for the "onAvailable"
1669 network callback indicating successful connection to network.
1670
1671 Args:
1672 ad: android_device object to initiate connection on.
1673 network_specifier: A dictionary representing the network specifier to
1674 use.
1675 network: A dictionary representing the network to connect to. The
1676 dictionary must have the key "SSID".
1677 num_of_tries: An integer that is the number of times to try before
1678 delaring failure.
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001679 Returns:
1680 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001681 """
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001682 key = ad.droid.connectivityRequestWifiNetwork(network_specifier, 0)
1683 ad.log.info("Sent network request %s with %s " % (key, network_specifier))
Roshan Piusc999e5e2018-11-09 10:59:52 -08001684 # Need a delay here because UI interaction should only start once wifi
1685 # starts processing the request.
1686 time.sleep(wifi_constants.NETWORK_REQUEST_CB_REGISTER_DELAY_SEC)
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001687 _wait_for_wifi_connect_after_network_request(ad, network, key, num_of_tries)
1688 return key
Roshan Piusc999e5e2018-11-09 10:59:52 -08001689
1690
Omar El Ayach8c017902020-10-18 10:26:57 -07001691def wait_for_wifi_connect_after_network_request(ad,
1692 network,
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001693 key,
Omar El Ayach8c017902020-10-18 10:26:57 -07001694 num_of_tries=3,
Roshan Piusc999e5e2018-11-09 10:59:52 -08001695 assert_on_fail=True):
1696 """
1697 Simulate and verify the connection flow after initiating the network
1698 request.
1699
1700 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1701 event contain the specified network, then simulate the user granting the
1702 request with the specified network selected. Then wait for the "onAvailable"
1703 network callback indicating successful connection to network.
1704
1705 Args:
1706 ad: android_device object to initiate connection on.
1707 network: A dictionary representing the network to connect to. The
1708 dictionary must have the key "SSID".
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001709 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001710 num_of_tries: An integer that is the number of times to try before
1711 delaring failure.
1712 assert_on_fail: If True, error checks in this function will raise test
1713 failure signals.
1714
1715 Returns:
1716 Returns a value only if assert_on_fail is false.
1717 Returns True if the connection was successful, False otherwise.
1718 """
1719 _assert_on_fail_handler(_wait_for_wifi_connect_after_network_request,
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001720 assert_on_fail, ad, network, key, num_of_tries)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001721
1722
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001723def _wait_for_wifi_connect_after_network_request(ad, network, key, num_of_tries=3):
Roshan Piusc999e5e2018-11-09 10:59:52 -08001724 """
1725 Simulate and verify the connection flow after initiating the network
1726 request.
1727
1728 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1729 event contain the specified network, then simulate the user granting the
1730 request with the specified network selected. Then wait for the "onAvailable"
1731 network callback indicating successful connection to network.
1732
1733 Args:
1734 ad: android_device object to initiate connection on.
1735 network: A dictionary representing the network to connect to. The
1736 dictionary must have the key "SSID".
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001737 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001738 num_of_tries: An integer that is the number of times to try before
1739 delaring failure.
1740 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001741 asserts.assert_true(
1742 WifiEnums.SSID_KEY in network,
1743 "Key '%s' must be present in network definition." % WifiEnums.SSID_KEY)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001744 ad.droid.wifiStartTrackingStateChange()
1745 expected_ssid = network[WifiEnums.SSID_KEY]
1746 ad.droid.wifiRegisterNetworkRequestMatchCallback()
1747 # Wait for the platform to scan and return a list of networks
1748 # matching the request
1749 try:
1750 matched_network = None
Omar El Ayach8c017902020-10-18 10:26:57 -07001751 for _ in [0, num_of_tries]:
Roshan Piusc999e5e2018-11-09 10:59:52 -08001752 on_match_event = ad.ed.pop_event(
1753 wifi_constants.WIFI_NETWORK_REQUEST_MATCH_CB_ON_MATCH, 60)
1754 asserts.assert_true(on_match_event,
1755 "Network request on match not received.")
1756 matched_scan_results = on_match_event["data"]
1757 ad.log.debug("Network request on match results %s",
1758 matched_scan_results)
1759 matched_network = match_networks(
1760 {WifiEnums.SSID_KEY: network[WifiEnums.SSID_KEY]},
1761 matched_scan_results)
Roshan Pius6cd4aaf2021-02-09 15:54:30 -08001762 ad.log.debug("Network request on match %s", matched_network)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001763 if matched_network:
Omar El Ayach8c017902020-10-18 10:26:57 -07001764 break
Roshan Piusc999e5e2018-11-09 10:59:52 -08001765
Omar El Ayach8c017902020-10-18 10:26:57 -07001766 asserts.assert_true(matched_network,
1767 "Target network %s not found" % network)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001768
1769 ad.droid.wifiSendUserSelectionForNetworkRequestMatch(network)
1770 ad.log.info("Sent user selection for network request %s",
1771 expected_ssid)
1772
1773 # Wait for the platform to connect to the network.
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001774 autils.wait_for_event_with_keys(
1775 ad, cconsts.EVENT_NETWORK_CALLBACK,
1776 60,
1777 (cconsts.NETWORK_CB_KEY_ID, key),
1778 (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_AVAILABLE))
1779 on_capabilities_changed = autils.wait_for_event_with_keys(
1780 ad, cconsts.EVENT_NETWORK_CALLBACK,
1781 10,
1782 (cconsts.NETWORK_CB_KEY_ID, key),
1783 (cconsts.NETWORK_CB_KEY_EVENT,
1784 cconsts.NETWORK_CB_CAPABILITIES_CHANGED))
Roshan Pius008fe7f2021-03-25 14:18:17 -07001785 connected_network = None
1786 # WifiInfo is attached to TransportInfo only in S.
1787 if ad.droid.isSdkAtLeastS():
1788 connected_network = (
1789 on_capabilities_changed["data"][
1790 cconsts.NETWORK_CB_KEY_TRANSPORT_INFO]
1791 )
1792 else:
1793 connected_network = ad.droid.wifiGetConnectionInfo()
Roshan Piusc999e5e2018-11-09 10:59:52 -08001794 ad.log.info("Connected to network %s", connected_network)
Omar El Ayach8c017902020-10-18 10:26:57 -07001795 asserts.assert_equal(
1796 connected_network[WifiEnums.SSID_KEY], expected_ssid,
1797 "Connected to the wrong network."
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001798 "Expected %s, but got %s."
1799 % (network, connected_network))
Roshan Piusc999e5e2018-11-09 10:59:52 -08001800 except Empty:
1801 asserts.fail("Failed to connect to %s" % expected_ssid)
1802 except Exception as error:
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001803 ad.log.error("Failed to connect to %s with error %s" %
Roshan Piusc999e5e2018-11-09 10:59:52 -08001804 (expected_ssid, error))
1805 raise signals.TestFailure("Failed to connect to %s network" % network)
1806 finally:
1807 ad.droid.wifiStopTrackingStateChange()
1808
1809
Omar El Ayach8c017902020-10-18 10:26:57 -07001810def wifi_passpoint_connect(ad,
1811 passpoint_network,
1812 num_of_tries=1,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001813 assert_on_fail=True):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001814 """Connect an Android device to a wifi network.
1815
1816 Initiate connection to a wifi network, wait for the "connected" event, then
1817 confirm the connected ssid is the one requested.
1818
1819 This will directly fail a test if anything goes wrong.
1820
1821 Args:
1822 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001823 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001824 num_of_tries: An integer that is the number of times to try before
1825 delaring failure. Default is 1.
1826 assert_on_fail: If True, error checks in this function will raise test
1827 failure signals.
1828
1829 Returns:
1830 If assert_on_fail is False, function returns network id, if the connect was
1831 successful, False otherwise. If assert_on_fail is True, no return value.
1832 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001833 _assert_on_fail_handler(_wifi_passpoint_connect,
1834 assert_on_fail,
1835 ad,
1836 passpoint_network,
1837 num_of_tries=num_of_tries)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001838
1839
Oscar Shucb9af9b2019-05-02 20:01:49 +00001840def _wifi_passpoint_connect(ad, passpoint_network, num_of_tries=1):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001841 """Connect an Android device to a wifi network.
1842
1843 Initiate connection to a wifi network, wait for the "connected" event, then
1844 confirm the connected ssid is the one requested.
1845
1846 This will directly fail a test if anything goes wrong.
1847
1848 Args:
1849 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001850 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001851 num_of_tries: An integer that is the number of times to try before
1852 delaring failure. Default is 1.
1853 """
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001854 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001855 expected_ssid = passpoint_network
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001856 ad.log.info("Starting connection process to passpoint %s", expected_ssid)
1857
1858 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001859 connect_result = _wait_for_connect_event(ad, expected_ssid,
1860 num_of_tries)
1861 asserts.assert_true(
1862 connect_result, "Failed to connect to WiFi passpoint network %s on"
1863 " %s" % (expected_ssid, ad.serial))
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001864 ad.log.info("Wi-Fi connection result: %s.", connect_result)
1865 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001866 asserts.assert_equal(
1867 actual_ssid, expected_ssid,
1868 "Connected to the wrong network on %s." % ad.serial)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001869 ad.log.info("Connected to Wi-Fi passpoint network %s.", actual_ssid)
1870
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001871 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1872 if not internet:
1873 raise signals.TestFailure("Failed to connect to internet on %s" %
1874 expected_ssid)
1875 except Exception as error:
1876 ad.log.error("Failed to connect to passpoint network %s with error %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07001877 expected_ssid, error)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001878 raise signals.TestFailure("Failed to connect to %s passpoint network" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001879 expected_ssid)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001880
1881 finally:
1882 ad.droid.wifiStopTrackingStateChange()
1883
1884
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001885def delete_passpoint(ad, fqdn):
1886 """Delete a required Passpoint configuration."""
1887 try:
1888 ad.droid.removePasspointConfig(fqdn)
1889 return True
1890 except Exception as error:
Omar El Ayach8c017902020-10-18 10:26:57 -07001891 ad.log.error(
1892 "Failed to remove passpoint configuration with FQDN=%s "
1893 "and error=%s", fqdn, error)
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001894 return False
1895
1896
Ang Li73697b32015-12-03 00:41:53 +00001897def start_wifi_single_scan(ad, scan_setting):
1898 """Starts wifi single shot scan.
1899
1900 Args:
1901 ad: android_device object to initiate connection on.
1902 scan_setting: A dict representing the settings of the scan.
1903
1904 Returns:
1905 If scan was started successfully, event data of success event is returned.
1906 """
Ang Li82522812016-06-02 13:57:21 -07001907 idx = ad.droid.wifiScannerStartScan(scan_setting)
1908 event = ad.ed.pop_event("WifiScannerScan%sonSuccess" % idx, SHORT_TIMEOUT)
Ang Li31b00782016-06-21 13:04:23 -07001909 ad.log.debug("Got event %s", event)
Ang Li73697b32015-12-03 00:41:53 +00001910 return event['data']
1911
Ang Li82522812016-06-02 13:57:21 -07001912
Ang Li73697b32015-12-03 00:41:53 +00001913def track_connection(ad, network_ssid, check_connection_count):
1914 """Track wifi connection to network changes for given number of counts
1915
1916 Args:
1917 ad: android_device object for forget network.
1918 network_ssid: network ssid to which connection would be tracked
1919 check_connection_count: Integer for maximum number network connection
Ang Li82522812016-06-02 13:57:21 -07001920 check.
Ang Li73697b32015-12-03 00:41:53 +00001921 Returns:
Ang Li73697b32015-12-03 00:41:53 +00001922 True if connection to given network happen, else return False.
1923 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001924 ad.droid.wifiStartTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001925 while check_connection_count > 0:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001926 connect_network = ad.ed.pop_event("WifiNetworkConnected", 120)
Ang Li31b00782016-06-21 13:04:23 -07001927 ad.log.info("Connected to network %s", connect_network)
Ang Li82522812016-06-02 13:57:21 -07001928 if (WifiEnums.SSID_KEY in connect_network['data'] and
1929 connect_network['data'][WifiEnums.SSID_KEY] == network_ssid):
1930 return True
Ang Li8e767182015-12-09 17:29:24 -08001931 check_connection_count -= 1
Girish Moturu40d7dc22016-11-02 12:14:56 -07001932 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001933 return False
1934
Ang Li82522812016-06-02 13:57:21 -07001935
Ang Li73697b32015-12-03 00:41:53 +00001936def get_scan_time_and_channels(wifi_chs, scan_setting, stime_channel):
1937 """Calculate the scan time required based on the band or channels in scan
1938 setting
1939
1940 Args:
1941 wifi_chs: Object of channels supported
1942 scan_setting: scan setting used for start scan
1943 stime_channel: scan time per channel
1944
1945 Returns:
1946 scan_time: time required for completing a scan
1947 scan_channels: channel used for scanning
1948 """
1949 scan_time = 0
1950 scan_channels = []
1951 if "band" in scan_setting and "channels" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001952 scan_channels = wifi_chs.band_to_freq(scan_setting["band"])
Ang Li73697b32015-12-03 00:41:53 +00001953 elif "channels" in scan_setting and "band" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001954 scan_channels = scan_setting["channels"]
Ang Li73697b32015-12-03 00:41:53 +00001955 scan_time = len(scan_channels) * stime_channel
1956 for channel in scan_channels:
Ang Li8e767182015-12-09 17:29:24 -08001957 if channel in WifiEnums.DFS_5G_FREQUENCIES:
Ang Li82522812016-06-02 13:57:21 -07001958 scan_time += 132 #passive scan time on DFS
Ang Li73697b32015-12-03 00:41:53 +00001959 return scan_time, scan_channels
1960
Ang Li82522812016-06-02 13:57:21 -07001961
Ang Li73697b32015-12-03 00:41:53 +00001962def start_wifi_track_bssid(ad, track_setting):
1963 """Start tracking Bssid for the given settings.
1964
1965 Args:
1966 ad: android_device object.
1967 track_setting: Setting for which the bssid tracking should be started
1968
1969 Returns:
1970 If tracking started successfully, event data of success event is returned.
1971 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001972 idx = ad.droid.wifiScannerStartTrackingBssids(
Ang Li82522812016-06-02 13:57:21 -07001973 track_setting["bssidInfos"], track_setting["apLostThreshold"])
Girish Moturu40d7dc22016-11-02 12:14:56 -07001974 event = ad.ed.pop_event("WifiScannerBssid{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -08001975 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +00001976 return event['data']
1977
Ang Li82522812016-06-02 13:57:21 -07001978
Ang Li73697b32015-12-03 00:41:53 +00001979def convert_pem_key_to_pkcs8(in_file, out_file):
1980 """Converts the key file generated by us to the format required by
1981 Android using openssl.
1982
1983 The input file must have the extension "pem". The output file must
1984 have the extension "der".
1985
1986 Args:
1987 in_file: The original key file.
1988 out_file: The full path to the converted key file, including
1989 filename.
1990 """
Ang Li82522812016-06-02 13:57:21 -07001991 asserts.assert_true(in_file.endswith(".pem"), "Input file has to be .pem.")
Omar El Ayach8c017902020-10-18 10:26:57 -07001992 asserts.assert_true(out_file.endswith(".der"),
1993 "Output file has to be .der.")
Ang Li73697b32015-12-03 00:41:53 +00001994 cmd = ("openssl pkcs8 -inform PEM -in {} -outform DER -out {} -nocrypt"
1995 " -topk8").format(in_file, out_file)
Ang Lifee28402016-07-13 13:43:29 -07001996 utils.exe_cmd(cmd)
Ang Li73697b32015-12-03 00:41:53 +00001997
Ang Li82522812016-06-02 13:57:21 -07001998
Omar El Ayach8c017902020-10-18 10:26:57 -07001999def validate_connection(ad,
2000 ping_addr=DEFAULT_PING_ADDR,
2001 wait_time=15,
Girish Moturu804a3492020-02-17 14:32:02 -08002002 ping_gateway=True):
Ang Li73697b32015-12-03 00:41:53 +00002003 """Validate internet connection by pinging the address provided.
2004
2005 Args:
2006 ad: android_device object.
2007 ping_addr: address on internet for pinging.
Girish Moturua2a5bf22019-08-16 09:52:29 -07002008 wait_time: wait for some time before validating connection
Ang Li73697b32015-12-03 00:41:53 +00002009
2010 Returns:
Bindu Mahadev50374df2017-01-04 11:03:32 -08002011 ping output if successful, NULL otherwise.
Ang Li73697b32015-12-03 00:41:53 +00002012 """
Girish Moturua2a5bf22019-08-16 09:52:29 -07002013 # wait_time to allow for DHCP to complete.
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08002014 for i in range(wait_time):
Girish Moturuacf35002020-11-09 23:37:35 -08002015 if ad.droid.connectivityNetworkIsConnected(
Omar El Ayach8c017902020-10-18 10:26:57 -07002016 ) and ad.droid.connectivityGetIPv4DefaultGateway():
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08002017 break
2018 time.sleep(1)
Girish Moturu804a3492020-02-17 14:32:02 -08002019 ping = False
2020 try:
2021 ping = ad.droid.httpPing(ping_addr)
2022 ad.log.info("Http ping result: %s.", ping)
2023 except:
2024 pass
2025 if not ping and ping_gateway:
2026 ad.log.info("Http ping failed. Pinging default gateway")
2027 gw = ad.droid.connectivityGetIPv4DefaultGateway()
2028 result = ad.adb.shell("ping -c 6 {}".format(gw))
2029 ad.log.info("Default gateway ping result: %s" % result)
2030 ping = False if "100% packet loss" in result else True
Ang Li73697b32015-12-03 00:41:53 +00002031 return ping
2032
Ang Li82522812016-06-02 13:57:21 -07002033
Ang Li73697b32015-12-03 00:41:53 +00002034#TODO(angli): This can only verify if an actual value is exactly the same.
2035# Would be nice to be able to verify an actual value is one of serveral.
2036def verify_wifi_connection_info(ad, expected_con):
2037 """Verifies that the information of the currently connected wifi network is
2038 as expected.
2039
2040 Args:
2041 expected_con: A dict representing expected key-value pairs for wifi
2042 connection. e.g. {"SSID": "test_wifi"}
2043 """
2044 current_con = ad.droid.wifiGetConnectionInfo()
Ang Li374d7602016-02-08 17:27:27 -08002045 case_insensitive = ["BSSID", "supplicant_state"]
Ang Li31b00782016-06-21 13:04:23 -07002046 ad.log.debug("Current connection: %s", current_con)
Ang Li73697b32015-12-03 00:41:53 +00002047 for k, expected_v in expected_con.items():
Ang Li9a66de72016-02-08 15:26:38 -08002048 # Do not verify authentication related fields.
2049 if k == "password":
2050 continue
Ang Li82522812016-06-02 13:57:21 -07002051 msg = "Field %s does not exist in wifi connection info %s." % (
2052 k, current_con)
Ang Li374d7602016-02-08 17:27:27 -08002053 if k not in current_con:
2054 raise signals.TestFailure(msg)
2055 actual_v = current_con[k]
2056 if k in case_insensitive:
2057 actual_v = actual_v.lower()
2058 expected_v = expected_v.lower()
Ang Li73697b32015-12-03 00:41:53 +00002059 msg = "Expected %s to be %s, actual %s is %s." % (k, expected_v, k,
Ang Li82522812016-06-02 13:57:21 -07002060 actual_v)
Ang Li374d7602016-02-08 17:27:27 -08002061 if actual_v != expected_v:
2062 raise signals.TestFailure(msg)
Ang Li73697b32015-12-03 00:41:53 +00002063
Ang Li82522812016-06-02 13:57:21 -07002064
Omar El Ayach8c017902020-10-18 10:26:57 -07002065def check_autoconnect_to_open_network(
2066 ad, conn_timeout=WIFI_CONNECTION_TIMEOUT_DEFAULT):
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08002067 """Connects to any open WiFI AP
2068 Args:
2069 timeout value in sec to wait for UE to connect to a WiFi AP
2070 Returns:
2071 True if UE connects to WiFi AP (supplicant_state = completed)
2072 False if UE fails to complete connection within WIFI_CONNECTION_TIMEOUT time.
2073 """
2074 if ad.droid.wifiCheckState():
2075 return True
2076 ad.droid.wifiToggleState()
2077 wifi_connection_state = None
2078 timeout = time.time() + conn_timeout
2079 while wifi_connection_state != "completed":
Omar El Ayach8c017902020-10-18 10:26:57 -07002080 wifi_connection_state = ad.droid.wifiGetConnectionInfo(
2081 )['supplicant_state']
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08002082 if time.time() > timeout:
2083 ad.log.warning("Failed to connect to WiFi AP")
2084 return False
2085 return True
2086
2087
Ang Li73697b32015-12-03 00:41:53 +00002088def expand_enterprise_config_by_phase2(config):
2089 """Take an enterprise config and generate a list of configs, each with
2090 a different phase2 auth type.
2091
2092 Args:
2093 config: A dict representing enterprise config.
2094
2095 Returns
2096 A list of enterprise configs.
2097 """
2098 results = []
Ang Li0e7e58f2016-02-22 12:15:02 -08002099 phase2_types = WifiEnums.EapPhase2
2100 if config[WifiEnums.Enterprise.EAP] == WifiEnums.Eap.PEAP:
2101 # Skip unsupported phase2 types for PEAP.
2102 phase2_types = [WifiEnums.EapPhase2.GTC, WifiEnums.EapPhase2.MSCHAPV2]
2103 for phase2_type in phase2_types:
Ang Li73697b32015-12-03 00:41:53 +00002104 # Skip a special case for passpoint TTLS.
Omar El Ayach8c017902020-10-18 10:26:57 -07002105 if (WifiEnums.Enterprise.FQDN in config
2106 and phase2_type == WifiEnums.EapPhase2.GTC):
Ang Li73697b32015-12-03 00:41:53 +00002107 continue
2108 c = dict(config)
Girish Moturu150d32f2017-02-14 12:27:07 -08002109 c[WifiEnums.Enterprise.PHASE2] = phase2_type.value
Ang Li73697b32015-12-03 00:41:53 +00002110 results.append(c)
2111 return results
Ang Li2d3fe982016-06-08 10:00:43 -07002112
2113
Girish Moturub48a13c2017-02-27 11:36:42 -08002114def generate_eap_test_name(config, ad=None):
Girish Moturu150d32f2017-02-14 12:27:07 -08002115 """ Generates a test case name based on an EAP configuration.
2116
2117 Args:
2118 config: A dict representing an EAP credential.
Girish Moturub48a13c2017-02-27 11:36:42 -08002119 ad object: Redundant but required as the same param is passed
2120 to test_func in run_generated_tests
Girish Moturu150d32f2017-02-14 12:27:07 -08002121
2122 Returns:
2123 A string representing the name of a generated EAP test case.
2124 """
2125 eap = WifiEnums.Eap
2126 eap_phase2 = WifiEnums.EapPhase2
Girish Moturub48a13c2017-02-27 11:36:42 -08002127 Ent = WifiEnums.Enterprise
Girish Moturu150d32f2017-02-14 12:27:07 -08002128 name = "test_connect-"
2129 eap_name = ""
2130 for e in eap:
2131 if e.value == config[Ent.EAP]:
2132 eap_name = e.name
2133 break
2134 if "peap0" in config[WifiEnums.SSID_KEY].lower():
2135 eap_name = "PEAP0"
2136 if "peap1" in config[WifiEnums.SSID_KEY].lower():
2137 eap_name = "PEAP1"
2138 name += eap_name
2139 if Ent.PHASE2 in config:
2140 for e in eap_phase2:
2141 if e.value == config[Ent.PHASE2]:
2142 name += "-{}".format(e.name)
2143 break
2144 return name
2145
2146
Ang Li2d3fe982016-06-08 10:00:43 -07002147def group_attenuators(attenuators):
2148 """Groups a list of attenuators into attenuator groups for backward
2149 compatibility reasons.
2150
2151 Most legacy Wi-Fi setups have two attenuators each connected to a separate
2152 AP. The new Wi-Fi setup has four attenuators, each connected to one channel
2153 on an AP, so two of them are connected to one AP.
2154
2155 To make the existing scripts work in the new setup, when the script needs
2156 to attenuate one AP, it needs to set attenuation on both attenuators
2157 connected to the same AP.
2158
2159 This function groups attenuators properly so the scripts work in both
2160 legacy and new Wi-Fi setups.
2161
2162 Args:
2163 attenuators: A list of attenuator objects, either two or four in length.
2164
2165 Raises:
2166 signals.TestFailure is raised if the attenuator list does not have two
2167 or four objects.
2168 """
2169 attn0 = attenuator.AttenuatorGroup("AP0")
2170 attn1 = attenuator.AttenuatorGroup("AP1")
2171 # Legacy testbed setup has two attenuation channels.
2172 num_of_attns = len(attenuators)
2173 if num_of_attns == 2:
2174 attn0.add(attenuators[0])
2175 attn1.add(attenuators[1])
2176 elif num_of_attns == 4:
2177 attn0.add(attenuators[0])
2178 attn0.add(attenuators[1])
2179 attn1.add(attenuators[2])
2180 attn1.add(attenuators[3])
2181 else:
2182 asserts.fail(("Either two or four attenuators are required for this "
2183 "test, but found %s") % num_of_attns)
2184 return [attn0, attn1]
Jong Wook Kim92356922018-02-06 18:32:49 -08002185
Bindu Mahadevff295782019-02-08 16:17:48 -08002186
Girish Moturu36348a32019-12-10 08:41:54 -08002187def set_attns(attenuator, attn_val_name, roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002188 """Sets attenuation values on attenuators used in this test.
2189
2190 Args:
2191 attenuator: The attenuator object.
2192 attn_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002193 roaming_attn: Dictionary specifying the attenuation params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002194 """
2195 logging.info("Set attenuation values to %s", roaming_attn[attn_val_name])
2196 try:
2197 attenuator[0].set_atten(roaming_attn[attn_val_name][0])
2198 attenuator[1].set_atten(roaming_attn[attn_val_name][1])
2199 attenuator[2].set_atten(roaming_attn[attn_val_name][2])
2200 attenuator[3].set_atten(roaming_attn[attn_val_name][3])
2201 except:
2202 logging.exception("Failed to set attenuation values %s.",
Omar El Ayach8c017902020-10-18 10:26:57 -07002203 attn_val_name)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002204 raise
2205
Omar El Ayach8c017902020-10-18 10:26:57 -07002206
Girish Moturu36348a32019-12-10 08:41:54 -08002207def set_attns_steps(attenuators,
2208 atten_val_name,
2209 roaming_attn=ROAMING_ATTN,
2210 steps=10,
2211 wait_time=12):
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002212 """Set attenuation values on attenuators used in this test. It will change
2213 the attenuation values linearly from current value to target value step by
2214 step.
2215
2216 Args:
2217 attenuators: The list of attenuator objects that you want to change
2218 their attenuation value.
2219 atten_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002220 roaming_attn: Dictionary specifying the attenuation params.
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002221 steps: Number of attenuator changes to reach the target value.
2222 wait_time: Sleep time for each change of attenuator.
2223 """
2224 logging.info("Set attenuation values to %s in %d step(s)",
Omar El Ayach8c017902020-10-18 10:26:57 -07002225 roaming_attn[atten_val_name], steps)
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002226 start_atten = [attenuator.get_atten() for attenuator in attenuators]
2227 target_atten = roaming_attn[atten_val_name]
2228 for current_step in range(steps):
2229 progress = (current_step + 1) / steps
2230 for i, attenuator in enumerate(attenuators):
2231 amount_since_start = (target_atten[i] - start_atten[i]) * progress
2232 attenuator.set_atten(round(start_atten[i] + amount_since_start))
2233 time.sleep(wait_time)
2234
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002235
Girish Moturu36348a32019-12-10 08:41:54 -08002236def trigger_roaming_and_validate(dut,
2237 attenuator,
2238 attn_val_name,
2239 expected_con,
2240 roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002241 """Sets attenuators to trigger roaming and validate the DUT connected
2242 to the BSSID expected.
2243
2244 Args:
2245 attenuator: The attenuator object.
2246 attn_val_name: Name of the attenuation value pair to use.
2247 expected_con: The network information of the expected network.
Girish Moturu36348a32019-12-10 08:41:54 -08002248 roaming_attn: Dictionary specifying the attenaution params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002249 """
2250 expected_con = {
2251 WifiEnums.SSID_KEY: expected_con[WifiEnums.SSID_KEY],
2252 WifiEnums.BSSID_KEY: expected_con["bssid"],
2253 }
Girish Moturu36348a32019-12-10 08:41:54 -08002254 set_attns_steps(attenuator, attn_val_name, roaming_attn)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002255
Hsiu-Chang Chenef856402018-09-18 12:32:49 +08002256 verify_wifi_connection_info(dut, expected_con)
2257 expected_bssid = expected_con[WifiEnums.BSSID_KEY]
2258 logging.info("Roamed to %s successfully", expected_bssid)
2259 if not validate_connection(dut):
2260 raise signals.TestFailure("Fail to connect to internet on %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07002261 expected_bssid)
2262
Jong Wook Kim92356922018-02-06 18:32:49 -08002263
2264def create_softap_config():
2265 """Create a softap config with random ssid and password."""
2266 ap_ssid = "softap_" + utils.rand_ascii_str(8)
2267 ap_password = utils.rand_ascii_str(8)
2268 logging.info("softap setup: %s %s", ap_ssid, ap_password)
2269 config = {
2270 WifiEnums.SSID_KEY: ap_ssid,
2271 WifiEnums.PWD_KEY: ap_password,
2272 }
2273 return config
Girish Moturucf4dccd2018-08-27 12:22:00 -07002274
Omar El Ayach8c017902020-10-18 10:26:57 -07002275
Bindu Mahadevff295782019-02-08 16:17:48 -08002276def start_softap_and_verify(ad, band):
2277 """Bring-up softap and verify AP mode and in scan results.
2278
2279 Args:
2280 band: The band to use for softAP.
2281
2282 Returns: dict, the softAP config.
2283
2284 """
lesl2f0fb232019-11-05 16:35:28 +08002285 # Register before start the test.
2286 callbackId = ad.dut.droid.registerSoftApCallback()
2287 # Check softap info value is default
2288 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2289 asserts.assert_true(frequency == 0, "Softap frequency is not reset")
2290 asserts.assert_true(bandwdith == 0, "Softap bandwdith is not reset")
2291
Bindu Mahadevff295782019-02-08 16:17:48 -08002292 config = create_softap_config()
2293 start_wifi_tethering(ad.dut,
2294 config[WifiEnums.SSID_KEY],
Omar El Ayach8c017902020-10-18 10:26:57 -07002295 config[WifiEnums.PWD_KEY],
2296 band=band)
Bindu Mahadevff295782019-02-08 16:17:48 -08002297 asserts.assert_true(ad.dut.droid.wifiIsApEnabled(),
Omar El Ayach8c017902020-10-18 10:26:57 -07002298 "SoftAp is not reported as running")
2299 start_wifi_connection_scan_and_ensure_network_found(
2300 ad.dut_client, config[WifiEnums.SSID_KEY])
lesl2f0fb232019-11-05 16:35:28 +08002301
2302 # Check softap info can get from callback succeed and assert value should be
2303 # valid.
2304 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2305 asserts.assert_true(frequency > 0, "Softap frequency is not valid")
2306 asserts.assert_true(bandwdith > 0, "Softap bandwdith is not valid")
2307 # Unregister callback
2308 ad.dut.droid.unregisterSoftApCallback(callbackId)
2309
Bindu Mahadevff295782019-02-08 16:17:48 -08002310 return config
2311
Omar El Ayach8c017902020-10-18 10:26:57 -07002312
lesle8e3c0a2019-02-22 17:06:04 +08002313def wait_for_expected_number_of_softap_clients(ad, callbackId,
Omar El Ayach8c017902020-10-18 10:26:57 -07002314 expected_num_of_softap_clients):
lesle8e3c0a2019-02-22 17:06:04 +08002315 """Wait for the number of softap clients to be updated as expected.
2316 Args:
2317 callbackId: Id of the callback associated with registering.
2318 expected_num_of_softap_clients: expected number of softap clients.
2319 """
2320 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002321 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
James Mattis5a5dd492020-05-14 13:09:43 -07002322 clientData = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data']
2323 clientCount = clientData[wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07002324 clientMacAddresses = clientData[
2325 wifi_constants.SOFTAP_CLIENTS_MACS_CALLBACK_KEY]
2326 asserts.assert_equal(
2327 clientCount, expected_num_of_softap_clients,
2328 "The number of softap clients doesn't match the expected number")
2329 asserts.assert_equal(
2330 len(clientMacAddresses), expected_num_of_softap_clients,
2331 "The number of mac addresses doesn't match the expected number")
James Mattis5a5dd492020-05-14 13:09:43 -07002332 for macAddress in clientMacAddresses:
Omar El Ayach8c017902020-10-18 10:26:57 -07002333 asserts.assert_true(checkMacAddress(macAddress),
2334 "An invalid mac address was returned")
2335
James Mattis5a5dd492020-05-14 13:09:43 -07002336
2337def checkMacAddress(input):
2338 """Validate whether a string is a valid mac address or not.
2339
2340 Args:
2341 input: The string to validate.
2342
2343 Returns: True/False, returns true for a valid mac address and false otherwise.
2344 """
2345 macValidationRegex = "[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$"
2346 if re.match(macValidationRegex, input.lower()):
2347 return True
2348 return False
lesle8e3c0a2019-02-22 17:06:04 +08002349
Omar El Ayach8c017902020-10-18 10:26:57 -07002350
lesle8e3c0a2019-02-22 17:06:04 +08002351def wait_for_expected_softap_state(ad, callbackId, expected_softap_state):
2352 """Wait for the expected softap state change.
2353 Args:
2354 callbackId: Id of the callback associated with registering.
2355 expected_softap_state: The expected softap state.
2356 """
2357 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002358 callbackId) + wifi_constants.SOFTAP_STATE_CHANGED
2359 asserts.assert_equal(
2360 ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data'][
2361 wifi_constants.SOFTAP_STATE_CHANGE_CALLBACK_KEY],
2362 expected_softap_state,
2363 "Softap state doesn't match with expected state")
2364
lesle8e3c0a2019-02-22 17:06:04 +08002365
2366def get_current_number_of_softap_clients(ad, callbackId):
2367 """pop up all of softap client updated event from queue.
2368 Args:
2369 callbackId: Id of the callback associated with registering.
2370
2371 Returns:
2372 If exist aleast callback, returns last updated number_of_softap_clients.
2373 Returns None when no any match callback event in queue.
2374 """
2375 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002376 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
lesle8e3c0a2019-02-22 17:06:04 +08002377 events = ad.ed.pop_all(eventStr)
2378 for event in events:
Omar El Ayach8c017902020-10-18 10:26:57 -07002379 num_of_clients = event['data'][
2380 wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
lesle8e3c0a2019-02-22 17:06:04 +08002381 if len(events) == 0:
2382 return None
2383 return num_of_clients
Bindu Mahadevff295782019-02-08 16:17:48 -08002384
Omar El Ayach8c017902020-10-18 10:26:57 -07002385
lesl67124362021-05-04 19:33:14 +08002386def get_current_softap_info(ad, callbackId, need_to_wait):
lesl2f0fb232019-11-05 16:35:28 +08002387 """pop up all of softap info changed event from queue.
2388 Args:
2389 callbackId: Id of the callback associated with registering.
lesl67124362021-05-04 19:33:14 +08002390 need_to_wait: Wait for the info callback event before pop all.
lesl2f0fb232019-11-05 16:35:28 +08002391 Returns:
2392 Returns last updated information of softap.
2393 """
2394 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002395 callbackId) + wifi_constants.SOFTAP_INFO_CHANGED
lesl67124362021-05-04 19:33:14 +08002396 ad.log.debug("softap info dump from eventStr %s", eventStr)
lesl2f0fb232019-11-05 16:35:28 +08002397 frequency = 0
2398 bandwidth = 0
lesl67124362021-05-04 19:33:14 +08002399 if (need_to_wait):
lesl2f0fb232019-11-05 16:35:28 +08002400 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
Omar El Ayach8c017902020-10-18 10:26:57 -07002401 frequency = event['data'][
2402 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2403 bandwidth = event['data'][
2404 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
lesl2f0fb232019-11-05 16:35:28 +08002405 ad.log.info("softap info updated, frequency is %s, bandwidth is %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07002406 frequency, bandwidth)
lesl2f0fb232019-11-05 16:35:28 +08002407
2408 events = ad.ed.pop_all(eventStr)
2409 for event in events:
Omar El Ayach8c017902020-10-18 10:26:57 -07002410 frequency = event['data'][
2411 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2412 bandwidth = event['data'][
2413 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
2414 ad.log.info("softap info, frequency is %s, bandwidth is %s", frequency,
2415 bandwidth)
lesl2f0fb232019-11-05 16:35:28 +08002416 return frequency, bandwidth
2417
lesl67124362021-05-04 19:33:14 +08002418def get_current_softap_infos(ad, callbackId, need_to_wait):
2419 """pop up all of softap info list changed event from queue.
2420 Args:
2421 callbackId: Id of the callback associated with registering.
2422 need_to_wait: Wait for the info callback event before pop all.
2423 Returns:
2424 Returns last updated informations of softap.
2425 """
2426 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
2427 callbackId) + wifi_constants.SOFTAP_INFOLIST_CHANGED
2428 ad.log.debug("softap info dump from eventStr %s", eventStr)
2429
2430 if (need_to_wait):
2431 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
2432 infos = event['data']
2433
2434 events = ad.ed.pop_all(eventStr)
2435 for event in events:
2436 infos = event['data']
2437
2438 for info in infos:
2439 frequency = info[
2440 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2441 bandwidth = info[
2442 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
2443 wifistandard = info[
2444 wifi_constants.SOFTAP_INFO_WIFISTANDARD_CALLBACK_KEY]
2445 bssid = info[
2446 wifi_constants.SOFTAP_INFO_BSSID_CALLBACK_KEY]
2447 ad.log.info(
2448 "softap info, freq:%s, bw:%s, wifistandard:%s, bssid:%s",
2449 frequency, bandwidth, wifistandard, bssid)
2450
2451 return infos
2452
2453def get_current_softap_capability(ad, callbackId, need_to_wait):
2454 """pop up all of softap info list changed event from queue.
2455 Args:
2456 callbackId: Id of the callback associated with registering.
2457 need_to_wait: Wait for the info callback event before pop all.
2458 Returns:
2459 Returns last updated capability of softap.
2460 """
2461 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
2462 callbackId) + wifi_constants.SOFTAP_CAPABILITY_CHANGED
2463 ad.log.debug("softap capability dump from eventStr %s", eventStr)
2464 if (need_to_wait):
2465 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
2466 capability = event['data']
2467
2468 events = ad.ed.pop_all(eventStr)
2469 for event in events:
2470 capability = event['data']
2471
2472 return capability
lesl2f0fb232019-11-05 16:35:28 +08002473
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002474def get_ssrdumps(ad):
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002475 """Pulls dumps in the ssrdump dir
2476 Args:
2477 ad: android device object.
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002478 """
2479 logs = ad.get_file_names("/data/vendor/ssrdump/")
2480 if logs:
2481 ad.log.info("Pulling ssrdumps %s", logs)
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002482 log_path = os.path.join(ad.device_log_path, "SSRDUMPS_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002483 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002484 ad.pull_files(logs, log_path)
Hsiu-Chang Chen769bef12020-10-10 06:07:52 +00002485 ad.adb.shell("find /data/vendor/ssrdump/ -type f -delete",
Omar El Ayach8c017902020-10-18 10:26:57 -07002486 ignore_status=True)
2487
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002488
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002489def start_pcap(pcap, wifi_band, test_name):
Girish Moturucf4dccd2018-08-27 12:22:00 -07002490 """Start packet capture in monitor mode.
2491
2492 Args:
2493 pcap: packet capture object
2494 wifi_band: '2g' or '5g' or 'dual'
Bindu Mahadev76551c12018-12-13 19:42:14 +00002495 test_name: test name to be used for pcap file name
2496
2497 Returns:
xianyuanjia0431ba32018-12-14 09:56:42 -08002498 Dictionary with wifi band as key and the tuple
2499 (pcap Process object, log directory) as the value
Girish Moturucf4dccd2018-08-27 12:22:00 -07002500 """
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002501 log_dir = os.path.join(
Xianyuan Jia5cd06bb2019-06-10 16:29:57 -07002502 context.get_current_context().get_full_output_path(), 'PacketCapture')
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002503 os.makedirs(log_dir, exist_ok=True)
Girish Moturucf4dccd2018-08-27 12:22:00 -07002504 if wifi_band == 'dual':
2505 bands = [BAND_2G, BAND_5G]
2506 else:
2507 bands = [wifi_band]
xianyuanjia0431ba32018-12-14 09:56:42 -08002508 procs = {}
Girish Moturucf4dccd2018-08-27 12:22:00 -07002509 for band in bands:
xianyuanjia0431ba32018-12-14 09:56:42 -08002510 proc = pcap.start_packet_capture(band, log_dir, test_name)
2511 procs[band] = (proc, os.path.join(log_dir, test_name))
2512 return procs
Girish Moturucf4dccd2018-08-27 12:22:00 -07002513
Bindu Mahadevff295782019-02-08 16:17:48 -08002514
xianyuanjia0431ba32018-12-14 09:56:42 -08002515def stop_pcap(pcap, procs, test_status=None):
Bindu Mahadev76551c12018-12-13 19:42:14 +00002516 """Stop packet capture in monitor mode.
2517
2518 Since, the pcap logs in monitor mode can be very large, we will
2519 delete them if they are not required. 'test_status' if True, will delete
2520 the pcap files. If False, we will keep them.
Girish Moturucf4dccd2018-08-27 12:22:00 -07002521
2522 Args:
2523 pcap: packet capture object
xianyuanjia0431ba32018-12-14 09:56:42 -08002524 procs: dictionary returned by start_pcap
Bindu Mahadev76551c12018-12-13 19:42:14 +00002525 test_status: status of the test case
Girish Moturucf4dccd2018-08-27 12:22:00 -07002526 """
xianyuanjia0431ba32018-12-14 09:56:42 -08002527 for proc, fname in procs.values():
2528 pcap.stop_packet_capture(proc)
Bindu Mahadev76551c12018-12-13 19:42:14 +00002529
2530 if test_status:
xianyuanjia0431ba32018-12-14 09:56:42 -08002531 shutil.rmtree(os.path.dirname(fname))
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002532
Omar El Ayach8c017902020-10-18 10:26:57 -07002533
Jaineel95887fd2019-10-16 16:19:01 -07002534def verify_mac_not_found_in_pcap(ad, mac, packets):
xshuf7267682019-06-03 14:41:56 -07002535 """Verify that a mac address is not found in the captured packets.
2536
2537 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002538 ad: android device object
xshuf7267682019-06-03 14:41:56 -07002539 mac: string representation of the mac address
2540 packets: packets obtained by rdpcap(pcap_fname)
2541 """
2542 for pkt in packets:
2543 logging.debug("Packet Summary = %s", pkt.summary())
2544 if mac in pkt.summary():
Jaineel95887fd2019-10-16 16:19:01 -07002545 asserts.fail("Device %s caught Factory MAC: %s in packet sniffer."
2546 "Packet = %s" % (ad.serial, mac, pkt.show()))
Bindu Mahadevff295782019-02-08 16:17:48 -08002547
Omar El Ayach8c017902020-10-18 10:26:57 -07002548
Jaineel95887fd2019-10-16 16:19:01 -07002549def verify_mac_is_found_in_pcap(ad, mac, packets):
Nate Jiangc2c09c62019-06-05 17:26:08 -07002550 """Verify that a mac address is found in the captured packets.
2551
2552 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002553 ad: android device object
Nate Jiangc2c09c62019-06-05 17:26:08 -07002554 mac: string representation of the mac address
2555 packets: packets obtained by rdpcap(pcap_fname)
2556 """
2557 for pkt in packets:
2558 if mac in pkt.summary():
2559 return
Jaineel95887fd2019-10-16 16:19:01 -07002560 asserts.fail("Did not find MAC = %s in packet sniffer."
2561 "for device %s" % (mac, ad.serial))
Nate Jiangc2c09c62019-06-05 17:26:08 -07002562
Omar El Ayach8c017902020-10-18 10:26:57 -07002563
Girish Moturuddc0d382020-08-24 12:08:41 -07002564def start_cnss_diags(ads, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002565 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002566 start_cnss_diag(ad, cnss_diag_file, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002567
Bindu Mahadevff295782019-02-08 16:17:48 -08002568
Girish Moturuddc0d382020-08-24 12:08:41 -07002569def start_cnss_diag(ad, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002570 """Start cnss_diag to record extra wifi logs
2571
2572 Args:
2573 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002574 cnss_diag_file: cnss diag config file to push to device.
2575 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002576 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002577 if ad.model not in pixel_models:
2578 ad.log.info("Device not supported to collect pixel logger")
2579 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002580 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2581 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2582 else:
2583 prop = wifi_constants.CNSS_DIAG_PROP
2584 if ad.adb.getprop(prop) != 'true':
Omar El Ayach8c017902020-10-18 10:26:57 -07002585 if not int(
2586 ad.adb.shell("ls -l %s%s | wc -l" %
2587 (CNSS_DIAG_CONFIG_PATH, CNSS_DIAG_CONFIG_FILE))):
Girish Moturuddc0d382020-08-24 12:08:41 -07002588 ad.adb.push("%s %s" % (cnss_diag_file, CNSS_DIAG_CONFIG_PATH))
Omar El Ayach8c017902020-10-18 10:26:57 -07002589 ad.adb.shell(
2590 "find /data/vendor/wifi/cnss_diag/wlan_logs/ -type f -delete",
2591 ignore_status=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002592 ad.adb.shell("setprop %s true" % prop, ignore_status=True)
2593
Bindu Mahadevff295782019-02-08 16:17:48 -08002594
Girish Moturuddc0d382020-08-24 12:08:41 -07002595def stop_cnss_diags(ads, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002596 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002597 stop_cnss_diag(ad, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002598
Bindu Mahadevff295782019-02-08 16:17:48 -08002599
Girish Moturuddc0d382020-08-24 12:08:41 -07002600def stop_cnss_diag(ad, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002601 """Stops cnss_diag
2602
2603 Args:
2604 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002605 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002606 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002607 if ad.model not in pixel_models:
2608 ad.log.info("Device not supported to collect pixel logger")
2609 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002610 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2611 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2612 else:
2613 prop = wifi_constants.CNSS_DIAG_PROP
2614 ad.adb.shell("setprop %s false" % prop, ignore_status=True)
2615
Bindu Mahadevff295782019-02-08 16:17:48 -08002616
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002617def get_cnss_diag_log(ad):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002618 """Pulls the cnss_diag logs in the wlan_logs dir
2619 Args:
2620 ad: android device object.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002621 """
2622 logs = ad.get_file_names("/data/vendor/wifi/cnss_diag/wlan_logs/")
2623 if logs:
2624 ad.log.info("Pulling cnss_diag logs %s", logs)
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002625 log_path = os.path.join(ad.device_log_path, "CNSS_DIAG_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002626 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002627 ad.pull_files(logs, log_path)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002628
Bindu Mahadevff295782019-02-08 16:17:48 -08002629
Omar El Ayach8c017902020-10-18 10:26:57 -07002630LinkProbeResult = namedtuple(
2631 'LinkProbeResult',
2632 ('is_success', 'stdout', 'elapsed_time', 'failure_reason'))
David Sue4cd9c22019-03-26 18:07:26 -07002633
2634
2635def send_link_probe(ad):
2636 """Sends a link probe to the currently connected AP, and returns whether the
2637 probe succeeded or not.
2638
2639 Args:
2640 ad: android device object
2641 Returns:
2642 LinkProbeResult namedtuple
2643 """
2644 stdout = ad.adb.shell('cmd wifi send-link-probe')
2645 asserts.assert_false('Error' in stdout or 'Exception' in stdout,
2646 'Exception while sending link probe: ' + stdout)
2647
2648 is_success = False
2649 elapsed_time = None
2650 failure_reason = None
2651 if 'succeeded' in stdout:
2652 is_success = True
2653 elapsed_time = next(
2654 (int(token) for token in stdout.split() if token.isdigit()), None)
2655 elif 'failed with reason' in stdout:
2656 failure_reason = next(
2657 (int(token) for token in stdout.split() if token.isdigit()), None)
2658 else:
2659 asserts.fail('Unexpected link probe result: ' + stdout)
2660
Omar El Ayach8c017902020-10-18 10:26:57 -07002661 return LinkProbeResult(is_success=is_success,
2662 stdout=stdout,
2663 elapsed_time=elapsed_time,
2664 failure_reason=failure_reason)
David Sue4cd9c22019-03-26 18:07:26 -07002665
2666
2667def send_link_probes(ad, num_probes, delay_sec):
2668 """Sends a sequence of link probes to the currently connected AP, and
2669 returns whether the probes succeeded or not.
2670
2671 Args:
2672 ad: android device object
2673 num_probes: number of probes to perform
2674 delay_sec: delay time between probes, in seconds
2675 Returns:
2676 List[LinkProbeResult] one LinkProbeResults for each probe
2677 """
2678 logging.info('Sending link probes')
2679 results = []
2680 for _ in range(num_probes):
2681 # send_link_probe() will also fail the test if it sees an exception
2682 # in the stdout of the adb shell command
2683 result = send_link_probe(ad)
2684 logging.info('link probe results: ' + str(result))
2685 results.append(result)
2686 time.sleep(delay_sec)
2687
2688 return results
2689
2690
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002691def ap_setup(test, index, ap, network, bandwidth=80, channel=6):
Omar El Ayach8c017902020-10-18 10:26:57 -07002692 """Set up the AP with provided network info.
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002693
2694 Args:
2695 test: the calling test class object.
2696 index: int, index of the AP.
2697 ap: access_point object of the AP.
2698 network: dict with information of the network, including ssid,
2699 password and bssid.
2700 bandwidth: the operation bandwidth for the AP, default 80MHz.
2701 channel: the channel number for the AP.
2702 Returns:
2703 brconfigs: the bridge interface configs
2704 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002705 bss_settings = []
2706 ssid = network[WifiEnums.SSID_KEY]
2707 test.access_points[index].close()
2708 time.sleep(5)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002709
Omar El Ayach8c017902020-10-18 10:26:57 -07002710 # Configure AP as required.
2711 if "password" in network.keys():
2712 password = network["password"]
2713 security = hostapd_security.Security(security_mode="wpa",
2714 password=password)
2715 else:
2716 security = hostapd_security.Security(security_mode=None, password=None)
2717 config = hostapd_ap_preset.create_ap_preset(channel=channel,
2718 ssid=ssid,
2719 security=security,
2720 bss_settings=bss_settings,
2721 vht_bandwidth=bandwidth,
2722 profile_name='whirlwind',
2723 iface_wlan_2g=ap.wlan_2g,
2724 iface_wlan_5g=ap.wlan_5g)
2725 ap.start_ap(config)
2726 logging.info("AP started on channel {} with SSID {}".format(channel, ssid))
Bindu Mahadevff295782019-02-08 16:17:48 -08002727
2728
2729def turn_ap_off(test, AP):
2730 """Bring down hostapd on the Access Point.
2731 Args:
2732 test: The test class object.
2733 AP: int, indicating which AP to turn OFF.
2734 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002735 hostapd_2g = test.access_points[AP - 1]._aps['wlan0'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002736 if hostapd_2g.is_alive():
2737 hostapd_2g.stop()
2738 logging.debug('Turned WLAN0 AP%d off' % AP)
Omar El Ayach8c017902020-10-18 10:26:57 -07002739 hostapd_5g = test.access_points[AP - 1]._aps['wlan1'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002740 if hostapd_5g.is_alive():
2741 hostapd_5g.stop()
2742 logging.debug('Turned WLAN1 AP%d off' % AP)
2743
2744
2745def turn_ap_on(test, AP):
2746 """Bring up hostapd on the Access Point.
2747 Args:
2748 test: The test class object.
2749 AP: int, indicating which AP to turn ON.
2750 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002751 hostapd_2g = test.access_points[AP - 1]._aps['wlan0'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002752 if not hostapd_2g.is_alive():
2753 hostapd_2g.start(hostapd_2g.config)
2754 logging.debug('Turned WLAN0 AP%d on' % AP)
Omar El Ayach8c017902020-10-18 10:26:57 -07002755 hostapd_5g = test.access_points[AP - 1]._aps['wlan1'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002756 if not hostapd_5g.is_alive():
2757 hostapd_5g.start(hostapd_5g.config)
2758 logging.debug('Turned WLAN1 AP%d on' % AP)
Joe Brennan48c3f692019-04-11 08:30:16 -07002759
2760
2761def turn_location_off_and_scan_toggle_off(ad):
2762 """Turns off wifi location scans."""
2763 utils.set_location_service(ad, False)
2764 ad.droid.wifiScannerToggleAlwaysAvailable(False)
2765 msg = "Failed to turn off location service's scan."
2766 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
Alfie Chen675be872020-06-04 10:48:14 +08002767
2768
2769def set_softap_channel(dut, ap_iface='wlan1', cs_count=10, channel=2462):
2770 """ Set SoftAP mode channel
2771
2772 Args:
2773 dut: android device object
2774 ap_iface: interface of SoftAP mode.
2775 cs_count: how many beacon frames before switch channel, default = 10
2776 channel: a wifi channel.
2777 """
2778 chan_switch_cmd = 'hostapd_cli -i {} chan_switch {} {}'
Omar El Ayach8c017902020-10-18 10:26:57 -07002779 chan_switch_cmd_show = chan_switch_cmd.format(ap_iface, cs_count, channel)
Alfie Chen675be872020-06-04 10:48:14 +08002780 dut.log.info('adb shell {}'.format(chan_switch_cmd_show))
Omar El Ayach8c017902020-10-18 10:26:57 -07002781 chan_switch_result = dut.adb.shell(
2782 chan_switch_cmd.format(ap_iface, cs_count, channel))
Alfie Chen675be872020-06-04 10:48:14 +08002783 if chan_switch_result == 'OK':
2784 dut.log.info('switch hotspot channel to {}'.format(channel))
2785 return chan_switch_result
2786
2787 asserts.fail("Failed to switch hotspot channel")
Alfie Chen310f7ff2021-01-26 20:36:09 +08002788
2789def get_wlan0_link(dut):
2790 """ get wlan0 interface status"""
2791 get_wlan0 = 'wpa_cli -iwlan0 -g@android:wpa_wlan0 IFNAME=wlan0 status'
2792 out = dut.adb.shell(get_wlan0)
2793 out = dict(re.findall(r'(\S+)=(".*?"|\S+)', out))
2794 asserts.assert_true("ssid" in out,
2795 "Client doesn't connect to any network")
Alfie Chenb3263dd2021-02-04 18:54:34 +08002796 return out