blob: d5e2733d53ad91e14bbdd9879574fc711246c025 [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"
84 AP_MAXCLIENTS_KEY = "MaxNumberOfClients"
85 AP_SHUTDOWNTIMEOUT_KEY = "ShutdownTimeoutMillis"
86 AP_SHUTDOWNTIMEOUTENABLE_KEY = "AutoShutdownEnabled"
87 AP_CLIENTCONTROL_KEY = "ClientControlByUserEnabled"
88 AP_ALLOWEDLIST_KEY = "AllowedClientList"
89 AP_BLOCKEDLIST_KEY = "BlockedClientList"
90
leslce9cf6d2020-02-19 16:37:07 +080091 WIFI_CONFIG_SOFTAP_BAND_2G = 1
92 WIFI_CONFIG_SOFTAP_BAND_5G = 2
93 WIFI_CONFIG_SOFTAP_BAND_2G_5G = 3
94 WIFI_CONFIG_SOFTAP_BAND_6G = 4
95 WIFI_CONFIG_SOFTAP_BAND_2G_6G = 5
96 WIFI_CONFIG_SOFTAP_BAND_5G_6G = 6
97 WIFI_CONFIG_SOFTAP_BAND_ANY = 7
98
99 # DO NOT USE IT for new test case! Replaced by WIFI_CONFIG_SOFTAP_BAND_
100 WIFI_CONFIG_APBAND_2G = WIFI_CONFIG_SOFTAP_BAND_2G
101 WIFI_CONFIG_APBAND_5G = WIFI_CONFIG_SOFTAP_BAND_5G
102 WIFI_CONFIG_APBAND_AUTO = WIFI_CONFIG_SOFTAP_BAND_2G_5G
103
104 WIFI_CONFIG_APBAND_2G_OLD = 0
105 WIFI_CONFIG_APBAND_5G_OLD = 1
106 WIFI_CONFIG_APBAND_AUTO_OLD = -1
Ang Li73697b32015-12-03 00:41:53 +0000107
Ang Li82522812016-06-02 13:57:21 -0700108 WIFI_WPS_INFO_PBC = 0
109 WIFI_WPS_INFO_DISPLAY = 1
110 WIFI_WPS_INFO_KEYPAD = 2
111 WIFI_WPS_INFO_LABEL = 3
112 WIFI_WPS_INFO_INVALID = 4
Ang Li73697b32015-12-03 00:41:53 +0000113
lesl6d30a172020-03-05 15:05:22 +0800114 class SoftApSecurityType():
115 OPEN = "NONE"
116 WPA2 = "WPA2_PSK"
117 WPA3_SAE_TRANSITION = "WPA3_SAE_TRANSITION"
118 WPA3_SAE = "WPA3_SAE"
119
Ang Li73697b32015-12-03 00:41:53 +0000120 class CountryCode():
Girish Moturue648b6a2021-03-04 13:52:15 -0800121 AUSTRALIA = "AU"
Ang Li73697b32015-12-03 00:41:53 +0000122 CHINA = "CN"
Girish Moturua5ef35d2020-10-19 14:58:01 -0700123 GERMANY = "DE"
Ang Li73697b32015-12-03 00:41:53 +0000124 JAPAN = "JP"
125 UK = "GB"
126 US = "US"
127 UNKNOWN = "UNKNOWN"
128
129 # Start of Macros for EAP
130 # EAP types
131 class Eap(IntEnum):
132 NONE = -1
133 PEAP = 0
Ang Li82522812016-06-02 13:57:21 -0700134 TLS = 1
Ang Li73697b32015-12-03 00:41:53 +0000135 TTLS = 2
Ang Li82522812016-06-02 13:57:21 -0700136 PWD = 3
137 SIM = 4
138 AKA = 5
139 AKA_PRIME = 6
140 UNAUTH_TLS = 7
Ang Li73697b32015-12-03 00:41:53 +0000141
142 # EAP Phase2 types
143 class EapPhase2(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700144 NONE = 0
145 PAP = 1
146 MSCHAP = 2
147 MSCHAPV2 = 3
148 GTC = 4
Ang Li73697b32015-12-03 00:41:53 +0000149
150 class Enterprise:
Ang Li82522812016-06-02 13:57:21 -0700151 # Enterprise Config Macros
152 EMPTY_VALUE = "NULL"
153 EAP = "eap"
154 PHASE2 = "phase2"
155 IDENTITY = "identity"
156 ANON_IDENTITY = "anonymous_identity"
157 PASSWORD = "password"
158 SUBJECT_MATCH = "subject_match"
Ang Li73697b32015-12-03 00:41:53 +0000159 ALTSUBJECT_MATCH = "altsubject_match"
160 DOM_SUFFIX_MATCH = "domain_suffix_match"
Ang Li82522812016-06-02 13:57:21 -0700161 CLIENT_CERT = "client_cert"
162 CA_CERT = "ca_cert"
163 ENGINE = "engine"
164 ENGINE_ID = "engine_id"
165 PRIVATE_KEY_ID = "key_id"
166 REALM = "realm"
167 PLMN = "plmn"
168 FQDN = "FQDN"
169 FRIENDLY_NAME = "providerFriendlyName"
170 ROAMING_IDS = "roamingConsortiumIds"
Jimmy Chen7baec622020-06-23 19:00:33 +0800171 OCSP = "ocsp"
Omar El Ayach8c017902020-10-18 10:26:57 -0700172
Ang Li73697b32015-12-03 00:41:53 +0000173 # End of Macros for EAP
174
175 # Macros for wifi p2p.
176 WIFI_P2P_SERVICE_TYPE_ALL = 0
177 WIFI_P2P_SERVICE_TYPE_BONJOUR = 1
178 WIFI_P2P_SERVICE_TYPE_UPNP = 2
179 WIFI_P2P_SERVICE_TYPE_VENDOR_SPECIFIC = 255
180
181 class ScanResult:
182 CHANNEL_WIDTH_20MHZ = 0
183 CHANNEL_WIDTH_40MHZ = 1
184 CHANNEL_WIDTH_80MHZ = 2
185 CHANNEL_WIDTH_160MHZ = 3
186 CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4
187
188 # Macros for wifi rtt.
189 class RttType(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700190 TYPE_ONE_SIDED = 1
191 TYPE_TWO_SIDED = 2
Ang Li73697b32015-12-03 00:41:53 +0000192
193 class RttPeerType(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700194 PEER_TYPE_AP = 1
195 PEER_TYPE_STA = 2 # Requires NAN.
196 PEER_P2P_GO = 3
197 PEER_P2P_CLIENT = 4
198 PEER_NAN = 5
Ang Li73697b32015-12-03 00:41:53 +0000199
200 class RttPreamble(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700201 PREAMBLE_LEGACY = 0x01
202 PREAMBLE_HT = 0x02
203 PREAMBLE_VHT = 0x04
Ang Li73697b32015-12-03 00:41:53 +0000204
205 class RttBW(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700206 BW_5_SUPPORT = 0x01
207 BW_10_SUPPORT = 0x02
208 BW_20_SUPPORT = 0x04
209 BW_40_SUPPORT = 0x08
210 BW_80_SUPPORT = 0x10
Ang Li73697b32015-12-03 00:41:53 +0000211 BW_160_SUPPORT = 0x20
212
213 class Rtt(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700214 STATUS_SUCCESS = 0
215 STATUS_FAILURE = 1
216 STATUS_FAIL_NO_RSP = 2
217 STATUS_FAIL_REJECTED = 3
218 STATUS_FAIL_NOT_SCHEDULED_YET = 4
219 STATUS_FAIL_TM_TIMEOUT = 5
220 STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6
221 STATUS_FAIL_NO_CAPABILITY = 7
222 STATUS_ABORTED = 8
223 STATUS_FAIL_INVALID_TS = 9
224 STATUS_FAIL_PROTOCOL = 10
225 STATUS_FAIL_SCHEDULE = 11
226 STATUS_FAIL_BUSY_TRY_LATER = 12
227 STATUS_INVALID_REQ = 13
228 STATUS_NO_WIFI = 14
229 STATUS_FAIL_FTM_PARAM_OVERRIDE = 15
Ang Li73697b32015-12-03 00:41:53 +0000230
Ang Li82522812016-06-02 13:57:21 -0700231 REASON_UNSPECIFIED = -1
232 REASON_NOT_AVAILABLE = -2
233 REASON_INVALID_LISTENER = -3
234 REASON_INVALID_REQUEST = -4
Ang Li73697b32015-12-03 00:41:53 +0000235
236 class RttParam:
237 device_type = "deviceType"
238 request_type = "requestType"
239 BSSID = "bssid"
240 channel_width = "channelWidth"
241 frequency = "frequency"
242 center_freq0 = "centerFreq0"
243 center_freq1 = "centerFreq1"
244 number_burst = "numberBurst"
245 interval = "interval"
246 num_samples_per_burst = "numSamplesPerBurst"
247 num_retries_per_measurement_frame = "numRetriesPerMeasurementFrame"
248 num_retries_per_FTMR = "numRetriesPerFTMR"
249 lci_request = "LCIRequest"
250 lcr_request = "LCRRequest"
251 burst_timeout = "burstTimeout"
252 preamble = "preamble"
253 bandwidth = "bandwidth"
254 margin = "margin"
255
256 RTT_MARGIN_OF_ERROR = {
257 RttBW.BW_80_SUPPORT: 2,
258 RttBW.BW_40_SUPPORT: 5,
259 RttBW.BW_20_SUPPORT: 5
260 }
261
262 # Macros as specified in the WifiScanner code.
Ang Li82522812016-06-02 13:57:21 -0700263 WIFI_BAND_UNSPECIFIED = 0 # not specified
264 WIFI_BAND_24_GHZ = 1 # 2.4 GHz band
265 WIFI_BAND_5_GHZ = 2 # 5 GHz band without DFS channels
266 WIFI_BAND_5_GHZ_DFS_ONLY = 4 # 5 GHz band with DFS channels
267 WIFI_BAND_5_GHZ_WITH_DFS = 6 # 5 GHz band with DFS channels
268 WIFI_BAND_BOTH = 3 # both bands without DFS channels
269 WIFI_BAND_BOTH_WITH_DFS = 7 # both bands with DFS channels
Ang Li73697b32015-12-03 00:41:53 +0000270
271 REPORT_EVENT_AFTER_BUFFER_FULL = 0
272 REPORT_EVENT_AFTER_EACH_SCAN = 1
273 REPORT_EVENT_FULL_SCAN_RESULT = 2
274
xshuaabcfeb2018-02-14 11:43:24 -0800275 SCAN_TYPE_LOW_LATENCY = 0
276 SCAN_TYPE_LOW_POWER = 1
277 SCAN_TYPE_HIGH_ACCURACY = 2
278
Ang Li73697b32015-12-03 00:41:53 +0000279 # US Wifi frequencies
Omar El Ayach8c017902020-10-18 10:26:57 -0700280 ALL_2G_FREQUENCIES = [
281 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462
282 ]
283 DFS_5G_FREQUENCIES = [
284 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640,
285 5660, 5680, 5700, 5720
286 ]
287 NONE_DFS_5G_FREQUENCIES = [
288 5180, 5200, 5220, 5240, 5745, 5765, 5785, 5805, 5825
289 ]
Ang Li73697b32015-12-03 00:41:53 +0000290 ALL_5G_FREQUENCIES = DFS_5G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES
291
292 band_to_frequencies = {
Ang Li82522812016-06-02 13:57:21 -0700293 WIFI_BAND_24_GHZ: ALL_2G_FREQUENCIES,
294 WIFI_BAND_5_GHZ: NONE_DFS_5G_FREQUENCIES,
295 WIFI_BAND_5_GHZ_DFS_ONLY: DFS_5G_FREQUENCIES,
296 WIFI_BAND_5_GHZ_WITH_DFS: ALL_5G_FREQUENCIES,
297 WIFI_BAND_BOTH: ALL_2G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES,
298 WIFI_BAND_BOTH_WITH_DFS: ALL_5G_FREQUENCIES + ALL_2G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000299 }
300
301 # All Wifi frequencies to channels lookup.
302 freq_to_channel = {
303 2412: 1,
304 2417: 2,
305 2422: 3,
306 2427: 4,
307 2432: 5,
308 2437: 6,
309 2442: 7,
310 2447: 8,
311 2452: 9,
312 2457: 10,
313 2462: 11,
314 2467: 12,
315 2472: 13,
316 2484: 14,
317 4915: 183,
318 4920: 184,
319 4925: 185,
320 4935: 187,
321 4940: 188,
322 4945: 189,
323 4960: 192,
324 4980: 196,
325 5035: 7,
326 5040: 8,
327 5045: 9,
328 5055: 11,
329 5060: 12,
330 5080: 16,
331 5170: 34,
332 5180: 36,
333 5190: 38,
334 5200: 40,
335 5210: 42,
336 5220: 44,
337 5230: 46,
338 5240: 48,
339 5260: 52,
340 5280: 56,
341 5300: 60,
342 5320: 64,
343 5500: 100,
344 5520: 104,
345 5540: 108,
346 5560: 112,
347 5580: 116,
348 5600: 120,
349 5620: 124,
350 5640: 128,
351 5660: 132,
352 5680: 136,
353 5700: 140,
354 5745: 149,
355 5765: 153,
356 5785: 157,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700357 5795: 159,
Ang Li73697b32015-12-03 00:41:53 +0000358 5805: 161,
359 5825: 165,
360 }
361
362 # All Wifi channels to frequencies lookup.
363 channel_2G_to_freq = {
364 1: 2412,
365 2: 2417,
366 3: 2422,
367 4: 2427,
368 5: 2432,
369 6: 2437,
370 7: 2442,
371 8: 2447,
372 9: 2452,
373 10: 2457,
374 11: 2462,
375 12: 2467,
376 13: 2472,
377 14: 2484
378 }
379
380 channel_5G_to_freq = {
381 183: 4915,
382 184: 4920,
383 185: 4925,
384 187: 4935,
385 188: 4940,
386 189: 4945,
387 192: 4960,
388 196: 4980,
389 7: 5035,
390 8: 5040,
391 9: 5045,
392 11: 5055,
393 12: 5060,
394 16: 5080,
395 34: 5170,
396 36: 5180,
397 38: 5190,
398 40: 5200,
399 42: 5210,
400 44: 5220,
401 46: 5230,
402 48: 5240,
Omar El Ayach8c017902020-10-18 10:26:57 -0700403 50: 5250,
Ang Li73697b32015-12-03 00:41:53 +0000404 52: 5260,
405 56: 5280,
406 60: 5300,
407 64: 5320,
408 100: 5500,
409 104: 5520,
410 108: 5540,
411 112: 5560,
412 116: 5580,
413 120: 5600,
414 124: 5620,
415 128: 5640,
416 132: 5660,
417 136: 5680,
418 140: 5700,
419 149: 5745,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700420 151: 5755,
Ang Li73697b32015-12-03 00:41:53 +0000421 153: 5765,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700422 155: 5775,
Ang Li73697b32015-12-03 00:41:53 +0000423 157: 5785,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700424 159: 5795,
Ang Li73697b32015-12-03 00:41:53 +0000425 161: 5805,
426 165: 5825
427 }
428
Ang Li82522812016-06-02 13:57:21 -0700429
Ang Li73697b32015-12-03 00:41:53 +0000430class WifiChannelBase:
431 ALL_2G_FREQUENCIES = []
432 DFS_5G_FREQUENCIES = []
433 NONE_DFS_5G_FREQUENCIES = []
434 ALL_5G_FREQUENCIES = DFS_5G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES
435 MIX_CHANNEL_SCAN = []
436
437 def band_to_freq(self, band):
438 _band_to_frequencies = {
Omar El Ayach8c017902020-10-18 10:26:57 -0700439 WifiEnums.WIFI_BAND_24_GHZ:
440 self.ALL_2G_FREQUENCIES,
441 WifiEnums.WIFI_BAND_5_GHZ:
442 self.NONE_DFS_5G_FREQUENCIES,
443 WifiEnums.WIFI_BAND_5_GHZ_DFS_ONLY:
444 self.DFS_5G_FREQUENCIES,
445 WifiEnums.WIFI_BAND_5_GHZ_WITH_DFS:
446 self.ALL_5G_FREQUENCIES,
Ang Li82522812016-06-02 13:57:21 -0700447 WifiEnums.WIFI_BAND_BOTH:
448 self.ALL_2G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES,
449 WifiEnums.WIFI_BAND_BOTH_WITH_DFS:
450 self.ALL_5G_FREQUENCIES + self.ALL_2G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000451 }
452 return _band_to_frequencies[band]
453
Ang Li82522812016-06-02 13:57:21 -0700454
Ang Li73697b32015-12-03 00:41:53 +0000455class WifiChannelUS(WifiChannelBase):
456 # US Wifi frequencies
Omar El Ayach8c017902020-10-18 10:26:57 -0700457 ALL_2G_FREQUENCIES = [
458 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462
459 ]
460 NONE_DFS_5G_FREQUENCIES = [
461 5180, 5200, 5220, 5240, 5745, 5765, 5785, 5805, 5825
462 ]
463 MIX_CHANNEL_SCAN = [
464 2412, 2437, 2462, 5180, 5200, 5280, 5260, 5300, 5500, 5320, 5520, 5560,
465 5700, 5745, 5805
466 ]
Ang Li73697b32015-12-03 00:41:53 +0000467
468 def __init__(self, model=None):
Omar El Ayach8c017902020-10-18 10:26:57 -0700469 self.DFS_5G_FREQUENCIES = [
470 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620,
471 5640, 5660, 5680, 5700, 5720
472 ]
Girish Moturu0c567b02017-08-11 16:20:01 -0700473 self.ALL_5G_FREQUENCIES = self.DFS_5G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000474
Bindu Mahadevff295782019-02-08 16:17:48 -0800475
Girish Moturuf02fa1d2017-05-21 09:51:23 +0530476class WifiReferenceNetworks:
477 """ Class to parse and return networks of different band and
478 auth type from reference_networks
479 """
480 def __init__(self, obj):
481 self.reference_networks = obj
482 self.WIFI_2G = "2g"
483 self.WIFI_5G = "5g"
484
485 self.secure_networks_2g = []
486 self.secure_networks_5g = []
487 self.open_networks_2g = []
488 self.open_networks_5g = []
489 self._parse_networks()
490
491 def _parse_networks(self):
492 for network in self.reference_networks:
493 for key in network:
494 if key == self.WIFI_2G:
495 if "password" in network[key]:
496 self.secure_networks_2g.append(network[key])
497 else:
498 self.open_networks_2g.append(network[key])
499 else:
500 if "password" in network[key]:
501 self.secure_networks_5g.append(network[key])
502 else:
503 self.open_networks_5g.append(network[key])
504
505 def return_2g_secure_networks(self):
506 return self.secure_networks_2g
507
508 def return_5g_secure_networks(self):
509 return self.secure_networks_5g
510
511 def return_2g_open_networks(self):
512 return self.open_networks_2g
513
514 def return_5g_open_networks(self):
515 return self.open_networks_5g
516
517 def return_secure_networks(self):
518 return self.secure_networks_2g + self.secure_networks_5g
519
520 def return_open_networks(self):
521 return self.open_networks_2g + self.open_networks_5g
522
Ang Li82522812016-06-02 13:57:21 -0700523
524def _assert_on_fail_handler(func, assert_on_fail, *args, **kwargs):
525 """Wrapper function that handles the bahevior of assert_on_fail.
526
527 When assert_on_fail is True, let all test signals through, which can
528 terminate test cases directly. When assert_on_fail is False, the wrapper
529 raises no test signals and reports operation status by returning True or
530 False.
531
532 Args:
533 func: The function to wrap. This function reports operation status by
534 raising test signals.
535 assert_on_fail: A boolean that specifies if the output of the wrapper
536 is test signal based or return value based.
537 args: Positional args for func.
538 kwargs: Name args for func.
539
540 Returns:
541 If assert_on_fail is True, returns True/False to signal operation
542 status, otherwise return nothing.
543 """
544 try:
545 func(*args, **kwargs)
546 if not assert_on_fail:
547 return True
548 except signals.TestSignal:
549 if assert_on_fail:
550 raise
551 return False
552
553
554def assert_network_in_list(target, network_list):
555 """Makes sure a specified target Wi-Fi network exists in a list of Wi-Fi
556 networks.
557
558 Args:
559 target: A dict representing a Wi-Fi network.
560 E.g. {WifiEnums.SSID_KEY: "SomeNetwork"}
561 network_list: A list of dicts, each representing a Wi-Fi network.
562 """
563 match_results = match_networks(target, network_list)
564 asserts.assert_true(
565 match_results, "Target network %s, does not exist in network list %s" %
566 (target, network_list))
567
568
Ang Li73697b32015-12-03 00:41:53 +0000569def match_networks(target_params, networks):
570 """Finds the WiFi networks that match a given set of parameters in a list
571 of WiFi networks.
572
Girish Moturubc48d9f2016-11-01 13:24:14 -0700573 To be considered a match, the network should contain every key-value pair
574 of target_params
Ang Li73697b32015-12-03 00:41:53 +0000575
576 Args:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700577 target_params: A dict with 1 or more key-value pairs representing a Wi-Fi network.
578 E.g { 'SSID': 'wh_ap1_5g', 'BSSID': '30:b5:c2:33:e4:47' }
Ang Li73697b32015-12-03 00:41:53 +0000579 networks: A list of dict objects representing WiFi networks.
580
581 Returns:
582 The networks that match the target parameters.
583 """
584 results = []
Betty Zhou3caa0982017-02-22 19:26:20 -0800585 asserts.assert_true(target_params,
586 "Expected networks object 'target_params' is empty")
Ang Li73697b32015-12-03 00:41:53 +0000587 for n in networks:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700588 add_network = 1
Ang Li9a66de72016-02-08 15:26:38 -0800589 for k, v in target_params.items():
590 if k not in n:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700591 add_network = 0
592 break
Ang Li9a66de72016-02-08 15:26:38 -0800593 if n[k] != v:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700594 add_network = 0
595 break
596 if add_network:
Ang Li73697b32015-12-03 00:41:53 +0000597 results.append(n)
598 return results
599
Bindu Mahadevff295782019-02-08 16:17:48 -0800600
Roshan Pius93b519c2018-05-09 12:07:11 -0700601def wait_for_wifi_state(ad, state, assert_on_fail=True):
602 """Waits for the device to transition to the specified wifi state
603
604 Args:
605 ad: An AndroidDevice object.
606 state: Wifi state to wait for.
607 assert_on_fail: If True, error checks in this function will raise test
608 failure signals.
609
610 Returns:
611 If assert_on_fail is False, function returns True if the device transitions
612 to the specified state, False otherwise. If assert_on_fail is True, no return value.
613 """
Omar El Ayach8c017902020-10-18 10:26:57 -0700614 return _assert_on_fail_handler(_wait_for_wifi_state,
615 assert_on_fail,
616 ad,
617 state=state)
Roshan Pius93b519c2018-05-09 12:07:11 -0700618
619
620def _wait_for_wifi_state(ad, state):
621 """Toggles the state of wifi.
622
623 TestFailure signals are raised when something goes wrong.
624
625 Args:
626 ad: An AndroidDevice object.
627 state: Wifi state to wait for.
628 """
629 if state == ad.droid.wifiCheckState():
630 # Check if the state is already achieved, so we don't wait for the
631 # state change event by mistake.
632 return
633 ad.droid.wifiStartTrackingStateChange()
Omar El Ayach8c017902020-10-18 10:26:57 -0700634 fail_msg = "Device did not transition to Wi-Fi state to %s on %s." % (
635 state, ad.serial)
Roshan Pius93b519c2018-05-09 12:07:11 -0700636 try:
637 ad.ed.wait_for_event(wifi_constants.WIFI_STATE_CHANGED,
638 lambda x: x["data"]["enabled"] == state,
639 SHORT_TIMEOUT)
640 except Empty:
641 asserts.assert_equal(state, ad.droid.wifiCheckState(), fail_msg)
642 finally:
643 ad.droid.wifiStopTrackingStateChange()
Ang Li82522812016-06-02 13:57:21 -0700644
Bindu Mahadevff295782019-02-08 16:17:48 -0800645
Ang Li82522812016-06-02 13:57:21 -0700646def wifi_toggle_state(ad, new_state=None, assert_on_fail=True):
Ang Li6b557182015-11-11 17:19:17 -0800647 """Toggles the state of wifi.
Ang Li73697b32015-12-03 00:41:53 +0000648
Ang Li6b557182015-11-11 17:19:17 -0800649 Args:
650 ad: An AndroidDevice object.
651 new_state: Wifi state to set to. If None, opposite of the current state.
Ang Li82522812016-06-02 13:57:21 -0700652 assert_on_fail: If True, error checks in this function will raise test
653 failure signals.
Ang Li73697b32015-12-03 00:41:53 +0000654
Ang Li6b557182015-11-11 17:19:17 -0800655 Returns:
Ang Li82522812016-06-02 13:57:21 -0700656 If assert_on_fail is False, function returns True if the toggle was
657 successful, False otherwise. If assert_on_fail is True, no return value.
658 """
Omar El Ayach8c017902020-10-18 10:26:57 -0700659 return _assert_on_fail_handler(_wifi_toggle_state,
660 assert_on_fail,
661 ad,
662 new_state=new_state)
Ang Li82522812016-06-02 13:57:21 -0700663
664
665def _wifi_toggle_state(ad, new_state=None):
666 """Toggles the state of wifi.
667
668 TestFailure signals are raised when something goes wrong.
669
670 Args:
671 ad: An AndroidDevice object.
672 new_state: The state to set Wi-Fi to. If None, opposite of the current
673 state will be set.
Ang Li6b557182015-11-11 17:19:17 -0800674 """
Ang Li31b00782016-06-21 13:04:23 -0700675 if new_state is None:
676 new_state = not ad.droid.wifiCheckState()
Ang Lie5c85c92016-07-27 15:38:09 -0700677 elif new_state == ad.droid.wifiCheckState():
678 # Check if the new_state is already achieved, so we don't wait for the
679 # state change event by mistake.
680 return
681 ad.droid.wifiStartTrackingStateChange()
Ang Li31b00782016-06-21 13:04:23 -0700682 ad.log.info("Setting Wi-Fi state to %s.", new_state)
Roshan Pius5a027fa2018-05-04 13:59:38 -0700683 ad.ed.clear_all_events()
Ang Li31b00782016-06-21 13:04:23 -0700684 # Setting wifi state.
Ang Li6b557182015-11-11 17:19:17 -0800685 ad.droid.wifiToggleState(new_state)
Jaineel3bd9bea2019-12-13 12:44:17 -0800686 time.sleep(2)
Ang Lie2e93a22016-06-22 16:43:28 -0700687 fail_msg = "Failed to set Wi-Fi state to %s on %s." % (new_state,
688 ad.serial)
Ang Li73697b32015-12-03 00:41:53 +0000689 try:
Roshan Pius5a027fa2018-05-04 13:59:38 -0700690 ad.ed.wait_for_event(wifi_constants.WIFI_STATE_CHANGED,
691 lambda x: x["data"]["enabled"] == new_state,
692 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +0000693 except Empty:
Ang Li82522812016-06-02 13:57:21 -0700694 asserts.assert_equal(new_state, ad.droid.wifiCheckState(), fail_msg)
Ang Li6b557182015-11-11 17:19:17 -0800695 finally:
696 ad.droid.wifiStopTrackingStateChange()
697
Ang Li82522812016-06-02 13:57:21 -0700698
Ang Li6b557182015-11-11 17:19:17 -0800699def reset_wifi(ad):
Ang Li1179fa72016-06-16 09:44:06 -0700700 """Clears all saved Wi-Fi networks on a device.
701
702 This will turn Wi-Fi on.
Ang Li6b557182015-11-11 17:19:17 -0800703
704 Args:
705 ad: An AndroidDevice object.
706
Ang Li6b557182015-11-11 17:19:17 -0800707 """
Ang Li6b557182015-11-11 17:19:17 -0800708 networks = ad.droid.wifiGetConfiguredNetworks()
709 if not networks:
710 return
711 for n in networks:
712 ad.droid.wifiForgetNetwork(n['networkId'])
713 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800714 event = ad.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS,
Ang Li82522812016-06-02 13:57:21 -0700715 SHORT_TIMEOUT)
Ang Li6b557182015-11-11 17:19:17 -0800716 except Empty:
Ang Li1179fa72016-06-16 09:44:06 -0700717 logging.warning("Could not confirm the removal of network %s.", n)
718 # Check again to see if there's any network left.
Betty Zhou3caa0982017-02-22 19:26:20 -0800719 asserts.assert_true(
720 not ad.droid.wifiGetConfiguredNetworks(),
721 "Failed to remove these configured Wi-Fi networks: %s" % networks)
Ang Li82522812016-06-02 13:57:21 -0700722
Ang Li73697b32015-12-03 00:41:53 +0000723
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700724def toggle_airplane_mode_on_and_off(ad):
725 """Turn ON and OFF Airplane mode.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800726
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700727 ad: An AndroidDevice object.
728 Returns: Assert if turning on/off Airplane mode fails.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800729
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700730 """
731 ad.log.debug("Toggling Airplane mode ON.")
Omar El Ayach8c017902020-10-18 10:26:57 -0700732 asserts.assert_true(utils.force_airplane_mode(ad, True),
733 "Can not turn on airplane mode on: %s" % ad.serial)
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700734 time.sleep(DEFAULT_TIMEOUT)
735 ad.log.debug("Toggling Airplane mode OFF.")
Omar El Ayach8c017902020-10-18 10:26:57 -0700736 asserts.assert_true(utils.force_airplane_mode(ad, False),
737 "Can not turn on airplane mode on: %s" % ad.serial)
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700738 time.sleep(DEFAULT_TIMEOUT)
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800739
740
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700741def toggle_wifi_off_and_on(ad):
742 """Turn OFF and ON WiFi.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800743
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700744 ad: An AndroidDevice object.
745 Returns: Assert if turning off/on WiFi fails.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800746
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700747 """
748 ad.log.debug("Toggling wifi OFF.")
749 wifi_toggle_state(ad, False)
750 time.sleep(DEFAULT_TIMEOUT)
751 ad.log.debug("Toggling wifi ON.")
752 wifi_toggle_state(ad, True)
753 time.sleep(DEFAULT_TIMEOUT)
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800754
755
Ang Li73697b32015-12-03 00:41:53 +0000756def wifi_forget_network(ad, net_ssid):
Ang Li8e767182015-12-09 17:29:24 -0800757 """Remove configured Wifi network on an android device.
Ang Li73697b32015-12-03 00:41:53 +0000758
Ang Li8e767182015-12-09 17:29:24 -0800759 Args:
760 ad: android_device object for forget network.
761 net_ssid: ssid of network to be forget
Ang Li73697b32015-12-03 00:41:53 +0000762
Ang Li8e767182015-12-09 17:29:24 -0800763 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700764 networks = ad.droid.wifiGetConfiguredNetworks()
Ang Li8e767182015-12-09 17:29:24 -0800765 if not networks:
766 return
767 for n in networks:
768 if net_ssid in n[WifiEnums.SSID_KEY]:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700769 ad.droid.wifiForgetNetwork(n['networkId'])
Ang Li8e767182015-12-09 17:29:24 -0800770 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800771 event = ad.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS,
Betty Zhou3caa0982017-02-22 19:26:20 -0800772 SHORT_TIMEOUT)
Ang Li8e767182015-12-09 17:29:24 -0800773 except Empty:
Girish Moturu1bf82302016-11-01 13:27:00 -0700774 asserts.fail("Failed to remove network %s." % n)
Ang Li73697b32015-12-03 00:41:53 +0000775
Ang Li82522812016-06-02 13:57:21 -0700776
Ang Li73697b32015-12-03 00:41:53 +0000777def wifi_test_device_init(ad):
778 """Initializes an android device for wifi testing.
779
780 0. Make sure SL4A connection is established on the android device.
781 1. Disable location service's WiFi scan.
782 2. Turn WiFi on.
783 3. Clear all saved networks.
784 4. Set country code to US.
785 5. Enable WiFi verbose logging.
786 6. Sync device time with computer time.
787 7. Turn off cellular data.
Ang Lifee28402016-07-13 13:43:29 -0700788 8. Turn off ambient display.
Ang Li73697b32015-12-03 00:41:53 +0000789 """
Ang Lifee28402016-07-13 13:43:29 -0700790 utils.require_sl4a((ad, ))
Ang Li73697b32015-12-03 00:41:53 +0000791 ad.droid.wifiScannerToggleAlwaysAvailable(False)
792 msg = "Failed to turn off location service's scan."
Ang Li82522812016-06-02 13:57:21 -0700793 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
794 wifi_toggle_state(ad, True)
Ang Li6b557182015-11-11 17:19:17 -0800795 reset_wifi(ad)
Ang Li73697b32015-12-03 00:41:53 +0000796 ad.droid.wifiEnableVerboseLogging(1)
Ang Li8e767182015-12-09 17:29:24 -0800797 msg = "Failed to enable WiFi verbose logging."
Ang Li82522812016-06-02 13:57:21 -0700798 asserts.assert_equal(ad.droid.wifiGetVerboseLoggingLevel(), 1, msg)
Ang Li73697b32015-12-03 00:41:53 +0000799 # We don't verify the following settings since they are not critical.
Ang Lie2e93a22016-06-22 16:43:28 -0700800 # Set wpa_supplicant log level to EXCESSIVE.
Omar El Ayach8c017902020-10-18 10:26:57 -0700801 output = ad.adb.shell(
802 "wpa_cli -i wlan0 -p -g@android:wpa_wlan0 IFNAME="
803 "wlan0 log_level EXCESSIVE",
804 ignore_status=True)
Ang Lie2e93a22016-06-22 16:43:28 -0700805 ad.log.info("wpa_supplicant log change status: %s", output)
Ang Lifee28402016-07-13 13:43:29 -0700806 utils.sync_device_time(ad)
Ang Li0bf8e022016-01-04 17:34:48 -0800807 ad.droid.telephonyToggleDataConnection(False)
Roshan Pius48df08c2019-09-13 08:07:30 -0700808 set_wifi_country_code(ad, WifiEnums.CountryCode.US)
Ang Lifee28402016-07-13 13:43:29 -0700809 utils.set_ambient_display(ad, False)
Ang Li73697b32015-12-03 00:41:53 +0000810
Omar El Ayach8c017902020-10-18 10:26:57 -0700811
Roshan Pius48df08c2019-09-13 08:07:30 -0700812def set_wifi_country_code(ad, country_code):
813 """Sets the wifi country code on the device.
814
815 Args:
816 ad: An AndroidDevice object.
817 country_code: 2 letter ISO country code
codycaldwell35b87182020-01-16 14:08:01 -0800818
819 Raises:
820 An RpcException if unable to set the country code.
Roshan Pius48df08c2019-09-13 08:07:30 -0700821 """
Jaineelc5b56a62019-10-10 17:12:02 -0700822 try:
codycaldwell35b87182020-01-16 14:08:01 -0800823 ad.adb.shell("cmd wifi force-country-code enabled %s" % country_code)
Jaineel Mehtacbad5cc2020-11-19 21:38:18 +0000824 except Exception as e:
Jaineelc5b56a62019-10-10 17:12:02 -0700825 ad.droid.wifiSetCountryCode(WifiEnums.CountryCode.US)
Roshan Pius48df08c2019-09-13 08:07:30 -0700826
Ang Li82522812016-06-02 13:57:21 -0700827
Ang Li6b557182015-11-11 17:19:17 -0800828def start_wifi_connection_scan(ad):
Ang Li73697b32015-12-03 00:41:53 +0000829 """Starts a wifi connection scan and wait for results to become available.
830
831 Args:
Ang Li6b557182015-11-11 17:19:17 -0800832 ad: An AndroidDevice object.
Ang Li73697b32015-12-03 00:41:53 +0000833 """
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800834 ad.ed.clear_all_events()
Ang Li6b557182015-11-11 17:19:17 -0800835 ad.droid.wifiStartScan()
Ang Li82522812016-06-02 13:57:21 -0700836 try:
837 ad.ed.pop_event("WifiManagerScanResultsAvailable", 60)
838 except Empty:
839 asserts.fail("Wi-Fi results did not become available within 60s.")
840
Ang Li73697b32015-12-03 00:41:53 +0000841
Roshan Piuscb9bc482018-02-01 14:27:09 -0800842def start_wifi_connection_scan_and_return_status(ad):
843 """
844 Starts a wifi connection scan and wait for results to become available
845 or a scan failure to be reported.
846
847 Args:
848 ad: An AndroidDevice object.
849 Returns:
850 True: if scan succeeded & results are available
851 False: if scan failed
852 """
853 ad.ed.clear_all_events()
854 ad.droid.wifiStartScan()
855 try:
Omar El Ayach8c017902020-10-18 10:26:57 -0700856 events = ad.ed.pop_events("WifiManagerScan(ResultsAvailable|Failure)",
857 60)
Roshan Piuscb9bc482018-02-01 14:27:09 -0800858 except Empty:
859 asserts.fail(
860 "Wi-Fi scan results/failure did not become available within 60s.")
861 # If there are multiple matches, we check for atleast one success.
862 for event in events:
863 if event["name"] == "WifiManagerScanResultsAvailable":
864 return True
865 elif event["name"] == "WifiManagerScanFailure":
866 ad.log.debug("Scan failure received")
867 return False
868
869
Omar El Ayach8c017902020-10-18 10:26:57 -0700870def start_wifi_connection_scan_and_check_for_network(ad,
871 network_ssid,
Roshan Piuscb9bc482018-02-01 14:27:09 -0800872 max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800873 """
874 Start connectivity scans & checks if the |network_ssid| is seen in
875 scan results. The method performs a max of |max_tries| connectivity scans
876 to find the network.
877
878 Args:
879 ad: An AndroidDevice object.
880 network_ssid: SSID of the network we are looking for.
881 max_tries: Number of scans to try.
882 Returns:
883 True: if network_ssid is found in scan results.
884 False: if network_ssid is not found in scan results.
885 """
886 for num_tries in range(max_tries):
Roshan Piuscb9bc482018-02-01 14:27:09 -0800887 if start_wifi_connection_scan_and_return_status(ad):
888 scan_results = ad.droid.wifiGetScanResults()
Omar El Ayach8c017902020-10-18 10:26:57 -0700889 match_results = match_networks({WifiEnums.SSID_KEY: network_ssid},
890 scan_results)
Roshan Piuscb9bc482018-02-01 14:27:09 -0800891 if len(match_results) > 0:
892 return True
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800893 return False
894
895
Omar El Ayach8c017902020-10-18 10:26:57 -0700896def start_wifi_connection_scan_and_ensure_network_found(
897 ad, network_ssid, max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800898 """
899 Start connectivity scans & ensure the |network_ssid| is seen in
900 scan results. The method performs a max of |max_tries| connectivity scans
901 to find the network.
902 This method asserts on failure!
903
904 Args:
905 ad: An AndroidDevice object.
906 network_ssid: SSID of the network we are looking for.
907 max_tries: Number of scans to try.
908 """
909 ad.log.info("Starting scans to ensure %s is present", network_ssid)
910 assert_msg = "Failed to find " + network_ssid + " in scan results" \
911 " after " + str(max_tries) + " tries"
Omar El Ayach8c017902020-10-18 10:26:57 -0700912 asserts.assert_true(
913 start_wifi_connection_scan_and_check_for_network(
914 ad, network_ssid, max_tries), assert_msg)
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800915
916
Omar El Ayach8c017902020-10-18 10:26:57 -0700917def start_wifi_connection_scan_and_ensure_network_not_found(
918 ad, network_ssid, max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800919 """
920 Start connectivity scans & ensure the |network_ssid| is not seen in
921 scan results. The method performs a max of |max_tries| connectivity scans
922 to find the network.
923 This method asserts on failure!
924
925 Args:
926 ad: An AndroidDevice object.
927 network_ssid: SSID of the network we are looking for.
928 max_tries: Number of scans to try.
929 """
930 ad.log.info("Starting scans to ensure %s is not present", network_ssid)
931 assert_msg = "Found " + network_ssid + " in scan results" \
932 " after " + str(max_tries) + " tries"
Omar El Ayach8c017902020-10-18 10:26:57 -0700933 asserts.assert_false(
934 start_wifi_connection_scan_and_check_for_network(
935 ad, network_ssid, max_tries), assert_msg)
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800936
937
Ang Li73697b32015-12-03 00:41:53 +0000938def start_wifi_background_scan(ad, scan_setting):
939 """Starts wifi background scan.
940
941 Args:
942 ad: android_device object to initiate connection on.
943 scan_setting: A dict representing the settings of the scan.
944
945 Returns:
946 If scan was started successfully, event data of success event is returned.
947 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700948 idx = ad.droid.wifiScannerStartBackgroundScan(scan_setting)
949 event = ad.ed.pop_event("WifiScannerScan{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -0800950 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +0000951 return event['data']
952
Ang Li82522812016-06-02 13:57:21 -0700953
Girish Moturu38b993c2021-03-25 13:03:50 -0700954def start_wifi_tethering(ad, ssid, password, band=None, hidden=None,
955 security=None):
Ang Li73697b32015-12-03 00:41:53 +0000956 """Starts wifi tethering on an android_device.
957
958 Args:
959 ad: android_device to start wifi tethering on.
960 ssid: The SSID the soft AP should broadcast.
961 password: The password the soft AP should use.
962 band: The band the soft AP should be set on. It should be either
963 WifiEnums.WIFI_CONFIG_APBAND_2G or WifiEnums.WIFI_CONFIG_APBAND_5G.
Roshan Piusce821342018-01-10 11:03:04 -0800964 hidden: boolean to indicate if the AP needs to be hidden or not.
Girish Moturu38b993c2021-03-25 13:03:50 -0700965 security: security type of softap.
Ang Li73697b32015-12-03 00:41:53 +0000966
967 Returns:
Girish Moturu3581d612016-11-02 15:08:51 -0700968 No return value. Error checks in this function will raise test failure signals
Ang Li73697b32015-12-03 00:41:53 +0000969 """
Ang Li82522812016-06-02 13:57:21 -0700970 config = {WifiEnums.SSID_KEY: ssid}
Ang Li73697b32015-12-03 00:41:53 +0000971 if password:
972 config[WifiEnums.PWD_KEY] = password
973 if band:
lesl6d30a172020-03-05 15:05:22 +0800974 config[WifiEnums.AP_BAND_KEY] = band
Roshan Piusce821342018-01-10 11:03:04 -0800975 if hidden:
Omar El Ayach8c017902020-10-18 10:26:57 -0700976 config[WifiEnums.HIDDEN_KEY] = hidden
Girish Moturu38b993c2021-03-25 13:03:50 -0700977 if security:
978 config[WifiEnums.SECURITY] = security
Omar El Ayach8c017902020-10-18 10:26:57 -0700979 asserts.assert_true(ad.droid.wifiSetWifiApConfiguration(config),
980 "Failed to update WifiAp Configuration")
Girish Moturu40d7dc22016-11-02 12:14:56 -0700981 ad.droid.wifiStartTrackingTetherStateChange()
982 ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
Rebecca Silbersteina2889852016-08-11 00:48:53 -0700983 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700984 ad.ed.pop_event("ConnectivityManagerOnTetheringStarted")
985 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -0800986 lambda x: x["data"]["ACTIVE_TETHER"], 30)
Ang Li76216d12016-09-20 14:51:57 -0700987 ad.log.debug("Tethering started successfully.")
Rebecca Silbersteina2889852016-08-11 00:48:53 -0700988 except Empty:
989 msg = "Failed to receive confirmation of wifi tethering starting"
990 asserts.fail(msg)
991 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700992 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li73697b32015-12-03 00:41:53 +0000993
Bindu Mahadevff295782019-02-08 16:17:48 -0800994
Omar El Ayach8c017902020-10-18 10:26:57 -0700995def save_wifi_soft_ap_config(ad,
996 wifi_config,
997 band=None,
998 hidden=None,
999 security=None,
1000 password=None,
1001 channel=None,
1002 max_clients=None,
lesl6d30a172020-03-05 15:05:22 +08001003 shutdown_timeout_enable=None,
1004 shutdown_timeout_millis=None,
1005 client_control_enable=None,
Omar El Ayach8c017902020-10-18 10:26:57 -07001006 allowedList=None,
1007 blockedList=None):
lesl6d30a172020-03-05 15:05:22 +08001008 """ Save a soft ap configuration and verified
1009 Args:
1010 ad: android_device to set soft ap configuration.
1011 wifi_config: a soft ap configuration object, at least include SSID.
1012 band: specifies the band for the soft ap.
1013 hidden: specifies the soft ap need to broadcast its SSID or not.
1014 security: specifies the security type for the soft ap.
1015 password: specifies the password for the soft ap.
1016 channel: specifies the channel for the soft ap.
1017 max_clients: specifies the maximum connected client number.
1018 shutdown_timeout_enable: specifies the auto shut down enable or not.
1019 shutdown_timeout_millis: specifies the shut down timeout value.
1020 client_control_enable: specifies the client control enable or not.
1021 allowedList: specifies allowed clients list.
1022 blockedList: specifies blocked clients list.
1023 """
1024 if security and password:
Omar El Ayach8c017902020-10-18 10:26:57 -07001025 wifi_config[WifiEnums.SECURITY] = security
1026 wifi_config[WifiEnums.PWD_KEY] = password
Girish Moturu528b5442018-06-07 10:48:14 -07001027 if band:
lesl6d30a172020-03-05 15:05:22 +08001028 wifi_config[WifiEnums.AP_BAND_KEY] = band
Girish Moturu528b5442018-06-07 10:48:14 -07001029 if hidden:
1030 wifi_config[WifiEnums.HIDDEN_KEY] = hidden
lesl6d30a172020-03-05 15:05:22 +08001031 if channel and band:
1032 wifi_config[WifiEnums.AP_BAND_KEY] = band
1033 wifi_config[WifiEnums.AP_CHANNEL_KEY] = channel
1034 if max_clients:
1035 wifi_config[WifiEnums.AP_MAXCLIENTS_KEY] = max_clients
1036 if shutdown_timeout_enable:
1037 wifi_config[
1038 WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] = shutdown_timeout_enable
1039 if shutdown_timeout_millis:
Omar El Ayach8c017902020-10-18 10:26:57 -07001040 wifi_config[WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] = shutdown_timeout_millis
lesl6d30a172020-03-05 15:05:22 +08001041 if client_control_enable:
1042 wifi_config[WifiEnums.AP_CLIENTCONTROL_KEY] = client_control_enable
1043 if allowedList:
1044 wifi_config[WifiEnums.AP_ALLOWEDLIST_KEY] = allowedList
1045 if blockedList:
1046 wifi_config[WifiEnums.AP_BLOCKEDLIST_KEY] = blockedList
1047
1048 if WifiEnums.AP_CHANNEL_KEY in wifi_config and wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001049 WifiEnums.AP_CHANNEL_KEY] == 0:
lesl6d30a172020-03-05 15:05:22 +08001050 del wifi_config[WifiEnums.AP_CHANNEL_KEY]
1051
1052 if WifiEnums.SECURITY in wifi_config and wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001053 WifiEnums.SECURITY] == WifiEnums.SoftApSecurityType.OPEN:
lesl6d30a172020-03-05 15:05:22 +08001054 del wifi_config[WifiEnums.SECURITY]
1055 del wifi_config[WifiEnums.PWD_KEY]
1056
Girish Moturu528b5442018-06-07 10:48:14 -07001057 asserts.assert_true(ad.droid.wifiSetWifiApConfiguration(wifi_config),
1058 "Failed to set WifiAp Configuration")
1059
1060 wifi_ap = ad.droid.wifiGetApConfiguration()
1061 asserts.assert_true(
1062 wifi_ap[WifiEnums.SSID_KEY] == wifi_config[WifiEnums.SSID_KEY],
lesl6d30a172020-03-05 15:05:22 +08001063 "Hotspot SSID doesn't match")
1064 if WifiEnums.SECURITY in wifi_config:
1065 asserts.assert_true(
1066 wifi_ap[WifiEnums.SECURITY] == wifi_config[WifiEnums.SECURITY],
1067 "Hotspot Security doesn't match")
1068 if WifiEnums.PWD_KEY in wifi_config:
1069 asserts.assert_true(
1070 wifi_ap[WifiEnums.PWD_KEY] == wifi_config[WifiEnums.PWD_KEY],
1071 "Hotspot Password doesn't match")
Girish Moturu528b5442018-06-07 10:48:14 -07001072
lesl6d30a172020-03-05 15:05:22 +08001073 if WifiEnums.HIDDEN_KEY in wifi_config:
1074 asserts.assert_true(
1075 wifi_ap[WifiEnums.HIDDEN_KEY] == wifi_config[WifiEnums.HIDDEN_KEY],
1076 "Hotspot hidden setting doesn't match")
1077
1078 if WifiEnums.AP_BAND_KEY in wifi_config:
1079 asserts.assert_true(
Omar El Ayach8c017902020-10-18 10:26:57 -07001080 wifi_ap[WifiEnums.AP_BAND_KEY] == wifi_config[
1081 WifiEnums.AP_BAND_KEY], "Hotspot Band doesn't match")
lesl6d30a172020-03-05 15:05:22 +08001082 if WifiEnums.AP_CHANNEL_KEY in wifi_config:
1083 asserts.assert_true(
1084 wifi_ap[WifiEnums.AP_CHANNEL_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001085 WifiEnums.AP_CHANNEL_KEY], "Hotspot Channel doesn't match")
lesl6d30a172020-03-05 15:05:22 +08001086 if WifiEnums.AP_MAXCLIENTS_KEY in wifi_config:
1087 asserts.assert_true(
1088 wifi_ap[WifiEnums.AP_MAXCLIENTS_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001089 WifiEnums.AP_MAXCLIENTS_KEY],
1090 "Hotspot Max Clients doesn't match")
lesl6d30a172020-03-05 15:05:22 +08001091 if WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY in wifi_config:
1092 asserts.assert_true(
1093 wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001094 WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY],
lesl6d30a172020-03-05 15:05:22 +08001095 "Hotspot ShutDown feature flag doesn't match")
1096 if WifiEnums.AP_SHUTDOWNTIMEOUT_KEY in wifi_config:
1097 asserts.assert_true(
1098 wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001099 WifiEnums.AP_SHUTDOWNTIMEOUT_KEY],
lesl6d30a172020-03-05 15:05:22 +08001100 "Hotspot ShutDown timeout setting doesn't match")
1101 if WifiEnums.AP_CLIENTCONTROL_KEY in wifi_config:
1102 asserts.assert_true(
1103 wifi_ap[WifiEnums.AP_CLIENTCONTROL_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001104 WifiEnums.AP_CLIENTCONTROL_KEY],
lesl6d30a172020-03-05 15:05:22 +08001105 "Hotspot Client control flag doesn't match")
1106 if WifiEnums.AP_ALLOWEDLIST_KEY in wifi_config:
1107 asserts.assert_true(
1108 wifi_ap[WifiEnums.AP_ALLOWEDLIST_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001109 WifiEnums.AP_ALLOWEDLIST_KEY],
lesl6d30a172020-03-05 15:05:22 +08001110 "Hotspot Allowed List doesn't match")
1111 if WifiEnums.AP_BLOCKEDLIST_KEY in wifi_config:
1112 asserts.assert_true(
1113 wifi_ap[WifiEnums.AP_BLOCKEDLIST_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001114 WifiEnums.AP_BLOCKEDLIST_KEY],
lesl6d30a172020-03-05 15:05:22 +08001115 "Hotspot Blocked List doesn't match")
Bindu Mahadevff295782019-02-08 16:17:48 -08001116
Omar El Ayach8c017902020-10-18 10:26:57 -07001117
Girish Moturu528b5442018-06-07 10:48:14 -07001118def start_wifi_tethering_saved_config(ad):
1119 """ Turn on wifi hotspot with a config that is already saved """
1120 ad.droid.wifiStartTrackingTetherStateChange()
1121 ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
1122 try:
1123 ad.ed.pop_event("ConnectivityManagerOnTetheringStarted")
1124 ad.ed.wait_for_event("TetherStateChanged",
1125 lambda x: x["data"]["ACTIVE_TETHER"], 30)
1126 except:
1127 asserts.fail("Didn't receive wifi tethering starting confirmation")
1128 finally:
1129 ad.droid.wifiStopTrackingTetherStateChange()
Betty Zhou3caa0982017-02-22 19:26:20 -08001130
Bindu Mahadevff295782019-02-08 16:17:48 -08001131
Ang Li73697b32015-12-03 00:41:53 +00001132def stop_wifi_tethering(ad):
1133 """Stops wifi tethering on an android_device.
Ang Li73697b32015-12-03 00:41:53 +00001134 Args:
1135 ad: android_device to stop wifi tethering on.
1136 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001137 ad.droid.wifiStartTrackingTetherStateChange()
1138 ad.droid.connectivityStopTethering(tel_defines.TETHERING_WIFI)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001139 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001140 ad.ed.pop_event("WifiManagerApDisabled", 30)
1141 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -08001142 lambda x: not x["data"]["ACTIVE_TETHER"], 30)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001143 except Empty:
1144 msg = "Failed to receive confirmation of wifi tethering stopping"
1145 asserts.fail(msg)
1146 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001147 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li82522812016-06-02 13:57:21 -07001148
Ang Li76216d12016-09-20 14:51:57 -07001149
Roshan Pius58916a32016-06-16 16:26:44 -07001150def toggle_wifi_and_wait_for_reconnection(ad,
1151 network,
1152 num_of_tries=1,
1153 assert_on_fail=True):
1154 """Toggle wifi state and then wait for Android device to reconnect to
1155 the provided wifi network.
1156
1157 This expects the device to be already connected to the provided network.
1158
1159 Logic steps are
1160 1. Ensure that we're connected to the network.
1161 2. Turn wifi off.
1162 3. Wait for 10 seconds.
1163 4. Turn wifi on.
1164 5. Wait for the "connected" event, then confirm the connected ssid is the
1165 one requested.
1166
1167 Args:
1168 ad: android_device object to initiate connection on.
1169 network: A dictionary representing the network to await connection. The
1170 dictionary must have the key "SSID".
1171 num_of_tries: An integer that is the number of times to try before
1172 delaring failure. Default is 1.
1173 assert_on_fail: If True, error checks in this function will raise test
1174 failure signals.
1175
1176 Returns:
1177 If assert_on_fail is False, function returns True if the toggle was
1178 successful, False otherwise. If assert_on_fail is True, no return value.
1179 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001180 return _assert_on_fail_handler(_toggle_wifi_and_wait_for_reconnection,
1181 assert_on_fail,
1182 ad,
1183 network,
1184 num_of_tries=num_of_tries)
Roshan Pius58916a32016-06-16 16:26:44 -07001185
1186
Girish Moturu5d9f4202019-12-03 15:29:21 -08001187def _toggle_wifi_and_wait_for_reconnection(ad, network, num_of_tries=3):
Roshan Pius58916a32016-06-16 16:26:44 -07001188 """Toggle wifi state and then wait for Android device to reconnect to
1189 the provided wifi network.
1190
1191 This expects the device to be already connected to the provided network.
1192
1193 Logic steps are
1194 1. Ensure that we're connected to the network.
1195 2. Turn wifi off.
1196 3. Wait for 10 seconds.
1197 4. Turn wifi on.
1198 5. Wait for the "connected" event, then confirm the connected ssid is the
1199 one requested.
1200
1201 This will directly fail a test if anything goes wrong.
1202
1203 Args:
1204 ad: android_device object to initiate connection on.
1205 network: A dictionary representing the network to await connection. The
1206 dictionary must have the key "SSID".
1207 num_of_tries: An integer that is the number of times to try before
1208 delaring failure. Default is 1.
1209 """
Roshan Pius58916a32016-06-16 16:26:44 -07001210 expected_ssid = network[WifiEnums.SSID_KEY]
1211 # First ensure that we're already connected to the provided network.
1212 verify_con = {WifiEnums.SSID_KEY: expected_ssid}
1213 verify_wifi_connection_info(ad, verify_con)
1214 # Now toggle wifi state and wait for the connection event.
1215 wifi_toggle_state(ad, False)
1216 time.sleep(10)
1217 wifi_toggle_state(ad, True)
1218 ad.droid.wifiStartTrackingStateChange()
1219 try:
1220 connect_result = None
1221 for i in range(num_of_tries):
1222 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -08001223 connect_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
Roshan Pius58916a32016-06-16 16:26:44 -07001224 30)
1225 break
1226 except Empty:
1227 pass
Omar El Ayach8c017902020-10-18 10:26:57 -07001228 asserts.assert_true(
1229 connect_result, "Failed to connect to Wi-Fi network %s on %s" %
1230 (network, ad.serial))
Betty Zhou3caa0982017-02-22 19:26:20 -08001231 logging.debug("Connection result on %s: %s.", ad.serial,
1232 connect_result)
Roshan Pius58916a32016-06-16 16:26:44 -07001233 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001234 asserts.assert_equal(
1235 actual_ssid, expected_ssid, "Connected to the wrong network on %s."
1236 "Expected %s, but got %s." %
1237 (ad.serial, expected_ssid, actual_ssid))
Betty Zhou3caa0982017-02-22 19:26:20 -08001238 logging.info("Connected to Wi-Fi network %s on %s", actual_ssid,
1239 ad.serial)
Roshan Pius58916a32016-06-16 16:26:44 -07001240 finally:
1241 ad.droid.wifiStopTrackingStateChange()
1242
1243
Omar El Ayach8c017902020-10-18 10:26:57 -07001244def wait_for_connect(ad,
1245 expected_ssid=None,
1246 expected_id=None,
1247 tries=2,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001248 assert_on_fail=True):
Roshan Piusd1204442018-11-12 12:20:39 -08001249 """Wait for a connect event.
1250
1251 This will directly fail a test if anything goes wrong.
1252
1253 Args:
1254 ad: An Android device object.
1255 expected_ssid: SSID of the network to connect to.
1256 expected_id: Network Id of the network to connect to.
1257 tries: An integer that is the number of times to try before failing.
1258 assert_on_fail: If True, error checks in this function will raise test
1259 failure signals.
1260
1261 Returns:
1262 Returns a value only if assert_on_fail is false.
1263 Returns True if the connection was successful, False otherwise.
1264 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001265 return _assert_on_fail_handler(_wait_for_connect, assert_on_fail, ad,
1266 expected_ssid, expected_id, tries)
Roshan Piusd1204442018-11-12 12:20:39 -08001267
1268
Oscar Shucb9af9b2019-05-02 20:01:49 +00001269def _wait_for_connect(ad, expected_ssid=None, expected_id=None, tries=2):
Roshan Piusd1204442018-11-12 12:20:39 -08001270 """Wait for a connect event.
1271
1272 Args:
1273 ad: An Android device object.
1274 expected_ssid: SSID of the network to connect to.
1275 expected_id: Network Id of the network to connect to.
1276 tries: An integer that is the number of times to try before failing.
1277 """
1278 ad.droid.wifiStartTrackingStateChange()
1279 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001280 connect_result = _wait_for_connect_event(ad,
1281 ssid=expected_ssid,
1282 id=expected_id,
1283 tries=tries)
1284 asserts.assert_true(
1285 connect_result,
1286 "Failed to connect to Wi-Fi network %s" % expected_ssid)
Roshan Piusd1204442018-11-12 12:20:39 -08001287 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
1288 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1289 if expected_ssid:
1290 asserts.assert_equal(actual_ssid, expected_ssid,
1291 "Connected to the wrong network")
1292 actual_id = connect_result['data'][WifiEnums.NETID_KEY]
1293 if expected_id:
1294 asserts.assert_equal(actual_id, expected_id,
1295 "Connected to the wrong network")
1296 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
1297 except Empty:
1298 asserts.fail("Failed to start connection process to %s" %
1299 expected_ssid)
1300 except Exception as error:
1301 ad.log.error("Failed to connect to %s with error %s", expected_ssid,
1302 error)
1303 raise signals.TestFailure("Failed to connect to %s network" %
1304 expected_ssid)
1305 finally:
1306 ad.droid.wifiStopTrackingStateChange()
1307
1308
Oscar Shucb9af9b2019-05-02 20:01:49 +00001309def _wait_for_connect_event(ad, ssid=None, id=None, tries=1):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001310 """Wait for a connect event on queue and pop when available.
1311
1312 Args:
1313 ad: An Android device object.
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001314 ssid: SSID of the network to connect to.
1315 id: Network Id of the network to connect to.
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001316 tries: An integer that is the number of times to try before failing.
1317
1318 Returns:
1319 A dict with details of the connection data, which looks like this:
1320 {
1321 'time': 1485460337798,
1322 'name': 'WifiNetworkConnected',
1323 'data': {
1324 'rssi': -27,
1325 'is_24ghz': True,
1326 'mac_address': '02:00:00:00:00:00',
1327 'network_id': 1,
1328 'BSSID': '30:b5:c2:33:d3:fc',
1329 'ip_address': 117483712,
1330 'link_speed': 54,
1331 'supplicant_state': 'completed',
1332 'hidden_ssid': False,
1333 'SSID': 'wh_ap1_2g',
1334 'is_5ghz': False}
1335 }
1336
1337 """
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001338 conn_result = None
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001339
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001340 # If ssid and network id is None, just wait for any connect event.
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001341 if id is None and ssid is None:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001342 for i in range(tries):
1343 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001344 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
1345 30)
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001346 break
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001347 except Empty:
1348 pass
1349 else:
Omar El Ayach8c017902020-10-18 10:26:57 -07001350 # If ssid or network id is specified, wait for specific connect event.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001351 for i in range(tries):
1352 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001353 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
1354 30)
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001355 if id and conn_result['data'][WifiEnums.NETID_KEY] == id:
1356 break
1357 elif ssid and conn_result['data'][WifiEnums.SSID_KEY] == ssid:
1358 break
1359 except Empty:
1360 pass
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001361
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001362 return conn_result
1363
Bindu Mahadevff295782019-02-08 16:17:48 -08001364
Roshan Piusffc29912019-01-18 13:39:49 -08001365def wait_for_disconnect(ad, timeout=10):
1366 """Wait for a disconnect event within the specified timeout.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001367
1368 Args:
1369 ad: Android device object.
Roshan Piusffc29912019-01-18 13:39:49 -08001370 timeout: Timeout in seconds.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001371
1372 """
1373 try:
1374 ad.droid.wifiStartTrackingStateChange()
Roshan Piusffc29912019-01-18 13:39:49 -08001375 event = ad.ed.pop_event("WifiNetworkDisconnected", timeout)
Roshan Piusbf7e3982018-02-15 12:37:41 -08001376 except Empty:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001377 raise signals.TestFailure("Device did not disconnect from the network")
Roshan Piusffc29912019-01-18 13:39:49 -08001378 finally:
1379 ad.droid.wifiStopTrackingStateChange()
1380
1381
1382def ensure_no_disconnect(ad, duration=10):
1383 """Ensure that there is no disconnect for the specified duration.
1384
1385 Args:
1386 ad: Android device object.
1387 duration: Duration in seconds.
1388
1389 """
1390 try:
1391 ad.droid.wifiStartTrackingStateChange()
1392 event = ad.ed.pop_event("WifiNetworkDisconnected", duration)
1393 raise signals.TestFailure("Device disconnected from the network")
1394 except Empty:
1395 pass
1396 finally:
1397 ad.droid.wifiStopTrackingStateChange()
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001398
1399
Omar El Ayach8c017902020-10-18 10:26:57 -07001400def connect_to_wifi_network(ad,
1401 network,
1402 assert_on_fail=True,
1403 check_connectivity=True,
1404 hidden=False):
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001405 """Connection logic for open and psk wifi networks.
1406
1407 Args:
Jong Wook Kim92356922018-02-06 18:32:49 -08001408 ad: AndroidDevice to use for connection
1409 network: network info of the network to connect to
1410 assert_on_fail: If true, errors from wifi_connect will raise
1411 test failure signals.
Joe Brennan48c3f692019-04-11 08:30:16 -07001412 hidden: Is the Wifi network hidden.
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001413 """
Joe Brennan48c3f692019-04-11 08:30:16 -07001414 if hidden:
1415 start_wifi_connection_scan_and_ensure_network_not_found(
1416 ad, network[WifiEnums.SSID_KEY])
1417 else:
1418 start_wifi_connection_scan_and_ensure_network_found(
1419 ad, network[WifiEnums.SSID_KEY])
Jong Wook Kim92356922018-02-06 18:32:49 -08001420 wifi_connect(ad,
1421 network,
1422 num_of_tries=3,
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001423 assert_on_fail=assert_on_fail,
1424 check_connectivity=check_connectivity)
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001425
1426
1427def connect_to_wifi_network_with_id(ad, network_id, network_ssid):
1428 """Connect to the given network using network id and verify SSID.
1429
1430 Args:
1431 network_id: int Network Id of the network.
1432 network_ssid: string SSID of the network.
1433
1434 Returns: True if connect using network id was successful;
1435 False otherwise.
1436
1437 """
Jong Wook Kim92356922018-02-06 18:32:49 -08001438 start_wifi_connection_scan_and_ensure_network_found(ad, network_ssid)
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001439 wifi_connect_by_id(ad, network_id)
1440 connect_data = ad.droid.wifiGetConnectionInfo()
1441 connect_ssid = connect_data[WifiEnums.SSID_KEY]
1442 ad.log.debug("Expected SSID = %s Connected SSID = %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001443 (network_ssid, connect_ssid))
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001444 if connect_ssid != network_ssid:
1445 return False
1446 return True
1447
1448
Omar El Ayach8c017902020-10-18 10:26:57 -07001449def wifi_connect(ad,
1450 network,
1451 num_of_tries=1,
1452 assert_on_fail=True,
1453 check_connectivity=True):
Ang Li99d8c6d2015-12-09 15:56:13 -08001454 """Connect an Android device to a wifi network.
Ang Li73697b32015-12-03 00:41:53 +00001455
1456 Initiate connection to a wifi network, wait for the "connected" event, then
Ang Li99d8c6d2015-12-09 15:56:13 -08001457 confirm the connected ssid is the one requested.
Ang Li73697b32015-12-03 00:41:53 +00001458
Ang Li82522812016-06-02 13:57:21 -07001459 This will directly fail a test if anything goes wrong.
1460
Ang Li73697b32015-12-03 00:41:53 +00001461 Args:
1462 ad: android_device object to initiate connection on.
Ang Li99d8c6d2015-12-09 15:56:13 -08001463 network: A dictionary representing the network to connect to. The
Ang Li82522812016-06-02 13:57:21 -07001464 dictionary must have the key "SSID".
1465 num_of_tries: An integer that is the number of times to try before
1466 delaring failure. Default is 1.
1467 assert_on_fail: If True, error checks in this function will raise test
1468 failure signals.
1469
1470 Returns:
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001471 Returns a value only if assert_on_fail is false.
1472 Returns True if the connection was successful, False otherwise.
Ang Li73697b32015-12-03 00:41:53 +00001473 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001474 return _assert_on_fail_handler(_wifi_connect,
1475 assert_on_fail,
1476 ad,
1477 network,
1478 num_of_tries=num_of_tries,
1479 check_connectivity=check_connectivity)
Ang Li82522812016-06-02 13:57:21 -07001480
1481
Oscar Shucb9af9b2019-05-02 20:01:49 +00001482def _wifi_connect(ad, network, num_of_tries=1, check_connectivity=True):
Ang Li82522812016-06-02 13:57:21 -07001483 """Connect an Android device to a wifi network.
1484
1485 Initiate connection to a wifi network, wait for the "connected" event, then
1486 confirm the connected ssid is the one requested.
1487
1488 This will directly fail a test if anything goes wrong.
1489
1490 Args:
1491 ad: android_device object to initiate connection on.
1492 network: A dictionary representing the network to connect to. The
1493 dictionary must have the key "SSID".
1494 num_of_tries: An integer that is the number of times to try before
1495 delaring failure. Default is 1.
1496 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001497 asserts.assert_true(
1498 WifiEnums.SSID_KEY in network,
1499 "Key '%s' must be present in network definition." % WifiEnums.SSID_KEY)
Ang Li99d8c6d2015-12-09 15:56:13 -08001500 ad.droid.wifiStartTrackingStateChange()
Betty Zhoud35dab82016-12-06 15:24:23 -08001501 expected_ssid = network[WifiEnums.SSID_KEY]
Bindu Mahadev50374df2017-01-04 11:03:32 -08001502 ad.droid.wifiConnectByConfig(network)
1503 ad.log.info("Starting connection process to %s", expected_ssid)
Ang Li73697b32015-12-03 00:41:53 +00001504 try:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001505 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_CONFIG_SUCCESS, 30)
Omar El Ayach8c017902020-10-18 10:26:57 -07001506 connect_result = _wait_for_connect_event(ad,
1507 ssid=expected_ssid,
1508 tries=num_of_tries)
1509 asserts.assert_true(
1510 connect_result, "Failed to connect to Wi-Fi network %s on %s" %
1511 (network, ad.serial))
Ang Li31b00782016-06-21 13:04:23 -07001512 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
Ang Li99d8c6d2015-12-09 15:56:13 -08001513 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001514 asserts.assert_equal(
1515 actual_ssid, expected_ssid,
1516 "Connected to the wrong network on %s." % ad.serial)
Ang Li31b00782016-06-21 13:04:23 -07001517 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
Bindu Mahadev50374df2017-01-04 11:03:32 -08001518
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001519 if check_connectivity:
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08001520 internet = validate_connection(ad, DEFAULT_PING_ADDR)
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001521 if not internet:
Omar El Ayach8c017902020-10-18 10:26:57 -07001522 raise signals.TestFailure(
1523 "Failed to connect to internet on %s" % expected_ssid)
Bindu Mahadev50374df2017-01-04 11:03:32 -08001524 except Empty:
1525 asserts.fail("Failed to start connection process to %s on %s" %
1526 (network, ad.serial))
Bindu Mahadev4e710362016-11-17 16:17:11 -08001527 except Exception as error:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001528 ad.log.error("Failed to connect to %s with error %s", expected_ssid,
1529 error)
1530 raise signals.TestFailure("Failed to connect to %s network" % network)
1531
Ang Li73697b32015-12-03 00:41:53 +00001532 finally:
Ang Li99d8c6d2015-12-09 15:56:13 -08001533 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001534
Bindu Mahadev50374df2017-01-04 11:03:32 -08001535
Oscar Shucb9af9b2019-05-02 20:01:49 +00001536def wifi_connect_by_id(ad, network_id, num_of_tries=3, assert_on_fail=True):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001537 """Connect an Android device to a wifi network using network Id.
1538
1539 Start connection to the wifi network, with the given network Id, wait for
1540 the "connected" event, then verify the connected network is the one requested.
1541
1542 This will directly fail a test if anything goes wrong.
1543
1544 Args:
1545 ad: android_device object to initiate connection on.
1546 network_id: Integer specifying the network id of the network.
1547 num_of_tries: An integer that is the number of times to try before
1548 delaring failure. Default is 1.
1549 assert_on_fail: If True, error checks in this function will raise test
1550 failure signals.
1551
1552 Returns:
1553 Returns a value only if assert_on_fail is false.
1554 Returns True if the connection was successful, False otherwise.
1555 """
1556 _assert_on_fail_handler(_wifi_connect_by_id, assert_on_fail, ad,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001557 network_id, num_of_tries)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001558
1559
Oscar Shucb9af9b2019-05-02 20:01:49 +00001560def _wifi_connect_by_id(ad, network_id, num_of_tries=1):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001561 """Connect an Android device to a wifi network using it's network id.
1562
1563 Start connection to the wifi network, with the given network id, wait for
1564 the "connected" event, then verify the connected network is the one requested.
1565
1566 Args:
1567 ad: android_device object to initiate connection on.
1568 network_id: Integer specifying the network id of the network.
1569 num_of_tries: An integer that is the number of times to try before
1570 delaring failure. Default is 1.
1571 """
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001572 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001573 # Clear all previous events.
1574 ad.ed.clear_all_events()
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001575 ad.droid.wifiConnectByNetworkId(network_id)
1576 ad.log.info("Starting connection to network with id %d", network_id)
1577 try:
1578 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_NETID_SUCCESS, 60)
Omar El Ayach8c017902020-10-18 10:26:57 -07001579 connect_result = _wait_for_connect_event(ad,
1580 id=network_id,
1581 tries=num_of_tries)
1582 asserts.assert_true(
1583 connect_result,
1584 "Failed to connect to Wi-Fi network using network id")
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001585 ad.log.debug("Wi-Fi connection result: %s", connect_result)
1586 actual_id = connect_result['data'][WifiEnums.NETID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001587 asserts.assert_equal(
1588 actual_id, network_id, "Connected to the wrong network on %s."
1589 "Expected network id = %d, but got %d." %
1590 (ad.serial, network_id, actual_id))
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001591 expected_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1592 ad.log.info("Connected to Wi-Fi network %s with %d network id.",
Omar El Ayach8c017902020-10-18 10:26:57 -07001593 expected_ssid, network_id)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001594
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001595 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1596 if not internet:
1597 raise signals.TestFailure("Failed to connect to internet on %s" %
1598 expected_ssid)
1599 except Empty:
1600 asserts.fail("Failed to connect to network with id %d on %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001601 (network_id, ad.serial))
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001602 except Exception as error:
1603 ad.log.error("Failed to connect to network with id %d with error %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07001604 network_id, error)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001605 raise signals.TestFailure("Failed to connect to network with network"
1606 " id %d" % network_id)
1607 finally:
1608 ad.droid.wifiStopTrackingStateChange()
1609
Oscar Shu0b5ff4d2019-08-07 18:11:56 +00001610
Omar El Ayach8c017902020-10-18 10:26:57 -07001611def wifi_connect_using_network_request(ad,
1612 network,
1613 network_specifier,
Roshan Pius5561d232021-01-22 16:34:39 -08001614 num_of_tries=3):
Roshan Piusc999e5e2018-11-09 10:59:52 -08001615 """Connect an Android device to a wifi network using network request.
1616
1617 Trigger a network request with the provided network specifier,
1618 wait for the "onMatch" event, ensure that the scan results in "onMatch"
1619 event contain the specified network, then simulate the user granting the
1620 request with the specified network selected. Then wait for the "onAvailable"
1621 network callback indicating successful connection to network.
1622
1623 Args:
1624 ad: android_device object to initiate connection on.
1625 network_specifier: A dictionary representing the network specifier to
1626 use.
1627 network: A dictionary representing the network to connect to. The
1628 dictionary must have the key "SSID".
1629 num_of_tries: An integer that is the number of times to try before
1630 delaring failure.
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001631 Returns:
1632 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001633 """
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001634 key = ad.droid.connectivityRequestWifiNetwork(network_specifier, 0)
1635 ad.log.info("Sent network request %s with %s " % (key, network_specifier))
Roshan Piusc999e5e2018-11-09 10:59:52 -08001636 # Need a delay here because UI interaction should only start once wifi
1637 # starts processing the request.
1638 time.sleep(wifi_constants.NETWORK_REQUEST_CB_REGISTER_DELAY_SEC)
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001639 _wait_for_wifi_connect_after_network_request(ad, network, key, num_of_tries)
1640 return key
Roshan Piusc999e5e2018-11-09 10:59:52 -08001641
1642
Omar El Ayach8c017902020-10-18 10:26:57 -07001643def wait_for_wifi_connect_after_network_request(ad,
1644 network,
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001645 key,
Omar El Ayach8c017902020-10-18 10:26:57 -07001646 num_of_tries=3,
Roshan Piusc999e5e2018-11-09 10:59:52 -08001647 assert_on_fail=True):
1648 """
1649 Simulate and verify the connection flow after initiating the network
1650 request.
1651
1652 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1653 event contain the specified network, then simulate the user granting the
1654 request with the specified network selected. Then wait for the "onAvailable"
1655 network callback indicating successful connection to network.
1656
1657 Args:
1658 ad: android_device object to initiate connection on.
1659 network: A dictionary representing the network to connect to. The
1660 dictionary must have the key "SSID".
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001661 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001662 num_of_tries: An integer that is the number of times to try before
1663 delaring failure.
1664 assert_on_fail: If True, error checks in this function will raise test
1665 failure signals.
1666
1667 Returns:
1668 Returns a value only if assert_on_fail is false.
1669 Returns True if the connection was successful, False otherwise.
1670 """
1671 _assert_on_fail_handler(_wait_for_wifi_connect_after_network_request,
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001672 assert_on_fail, ad, network, key, num_of_tries)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001673
1674
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001675def _wait_for_wifi_connect_after_network_request(ad, network, key, num_of_tries=3):
Roshan Piusc999e5e2018-11-09 10:59:52 -08001676 """
1677 Simulate and verify the connection flow after initiating the network
1678 request.
1679
1680 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1681 event contain the specified network, then simulate the user granting the
1682 request with the specified network selected. Then wait for the "onAvailable"
1683 network callback indicating successful connection to network.
1684
1685 Args:
1686 ad: android_device object to initiate connection on.
1687 network: A dictionary representing the network to connect to. The
1688 dictionary must have the key "SSID".
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001689 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001690 num_of_tries: An integer that is the number of times to try before
1691 delaring failure.
1692 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001693 asserts.assert_true(
1694 WifiEnums.SSID_KEY in network,
1695 "Key '%s' must be present in network definition." % WifiEnums.SSID_KEY)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001696 ad.droid.wifiStartTrackingStateChange()
1697 expected_ssid = network[WifiEnums.SSID_KEY]
1698 ad.droid.wifiRegisterNetworkRequestMatchCallback()
1699 # Wait for the platform to scan and return a list of networks
1700 # matching the request
1701 try:
1702 matched_network = None
Omar El Ayach8c017902020-10-18 10:26:57 -07001703 for _ in [0, num_of_tries]:
Roshan Piusc999e5e2018-11-09 10:59:52 -08001704 on_match_event = ad.ed.pop_event(
1705 wifi_constants.WIFI_NETWORK_REQUEST_MATCH_CB_ON_MATCH, 60)
1706 asserts.assert_true(on_match_event,
1707 "Network request on match not received.")
1708 matched_scan_results = on_match_event["data"]
1709 ad.log.debug("Network request on match results %s",
1710 matched_scan_results)
1711 matched_network = match_networks(
1712 {WifiEnums.SSID_KEY: network[WifiEnums.SSID_KEY]},
1713 matched_scan_results)
Roshan Pius6cd4aaf2021-02-09 15:54:30 -08001714 ad.log.debug("Network request on match %s", matched_network)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001715 if matched_network:
Omar El Ayach8c017902020-10-18 10:26:57 -07001716 break
Roshan Piusc999e5e2018-11-09 10:59:52 -08001717
Omar El Ayach8c017902020-10-18 10:26:57 -07001718 asserts.assert_true(matched_network,
1719 "Target network %s not found" % network)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001720
1721 ad.droid.wifiSendUserSelectionForNetworkRequestMatch(network)
1722 ad.log.info("Sent user selection for network request %s",
1723 expected_ssid)
1724
1725 # Wait for the platform to connect to the network.
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001726 autils.wait_for_event_with_keys(
1727 ad, cconsts.EVENT_NETWORK_CALLBACK,
1728 60,
1729 (cconsts.NETWORK_CB_KEY_ID, key),
1730 (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_AVAILABLE))
1731 on_capabilities_changed = autils.wait_for_event_with_keys(
1732 ad, cconsts.EVENT_NETWORK_CALLBACK,
1733 10,
1734 (cconsts.NETWORK_CB_KEY_ID, key),
1735 (cconsts.NETWORK_CB_KEY_EVENT,
1736 cconsts.NETWORK_CB_CAPABILITIES_CHANGED))
Roshan Pius008fe7f2021-03-25 14:18:17 -07001737 connected_network = None
1738 # WifiInfo is attached to TransportInfo only in S.
1739 if ad.droid.isSdkAtLeastS():
1740 connected_network = (
1741 on_capabilities_changed["data"][
1742 cconsts.NETWORK_CB_KEY_TRANSPORT_INFO]
1743 )
1744 else:
1745 connected_network = ad.droid.wifiGetConnectionInfo()
Roshan Piusc999e5e2018-11-09 10:59:52 -08001746 ad.log.info("Connected to network %s", connected_network)
Omar El Ayach8c017902020-10-18 10:26:57 -07001747 asserts.assert_equal(
1748 connected_network[WifiEnums.SSID_KEY], expected_ssid,
1749 "Connected to the wrong network."
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001750 "Expected %s, but got %s."
1751 % (network, connected_network))
Roshan Piusc999e5e2018-11-09 10:59:52 -08001752 except Empty:
1753 asserts.fail("Failed to connect to %s" % expected_ssid)
1754 except Exception as error:
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001755 ad.log.error("Failed to connect to %s with error %s" %
Roshan Piusc999e5e2018-11-09 10:59:52 -08001756 (expected_ssid, error))
1757 raise signals.TestFailure("Failed to connect to %s network" % network)
1758 finally:
1759 ad.droid.wifiStopTrackingStateChange()
1760
1761
Omar El Ayach8c017902020-10-18 10:26:57 -07001762def wifi_passpoint_connect(ad,
1763 passpoint_network,
1764 num_of_tries=1,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001765 assert_on_fail=True):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001766 """Connect an Android device to a wifi network.
1767
1768 Initiate connection to a wifi network, wait for the "connected" event, then
1769 confirm the connected ssid is the one requested.
1770
1771 This will directly fail a test if anything goes wrong.
1772
1773 Args:
1774 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001775 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001776 num_of_tries: An integer that is the number of times to try before
1777 delaring failure. Default is 1.
1778 assert_on_fail: If True, error checks in this function will raise test
1779 failure signals.
1780
1781 Returns:
1782 If assert_on_fail is False, function returns network id, if the connect was
1783 successful, False otherwise. If assert_on_fail is True, no return value.
1784 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001785 _assert_on_fail_handler(_wifi_passpoint_connect,
1786 assert_on_fail,
1787 ad,
1788 passpoint_network,
1789 num_of_tries=num_of_tries)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001790
1791
Oscar Shucb9af9b2019-05-02 20:01:49 +00001792def _wifi_passpoint_connect(ad, passpoint_network, num_of_tries=1):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001793 """Connect an Android device to a wifi network.
1794
1795 Initiate connection to a wifi network, wait for the "connected" event, then
1796 confirm the connected ssid is the one requested.
1797
1798 This will directly fail a test if anything goes wrong.
1799
1800 Args:
1801 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001802 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001803 num_of_tries: An integer that is the number of times to try before
1804 delaring failure. Default is 1.
1805 """
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001806 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001807 expected_ssid = passpoint_network
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001808 ad.log.info("Starting connection process to passpoint %s", expected_ssid)
1809
1810 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001811 connect_result = _wait_for_connect_event(ad, expected_ssid,
1812 num_of_tries)
1813 asserts.assert_true(
1814 connect_result, "Failed to connect to WiFi passpoint network %s on"
1815 " %s" % (expected_ssid, ad.serial))
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001816 ad.log.info("Wi-Fi connection result: %s.", connect_result)
1817 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001818 asserts.assert_equal(
1819 actual_ssid, expected_ssid,
1820 "Connected to the wrong network on %s." % ad.serial)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001821 ad.log.info("Connected to Wi-Fi passpoint network %s.", actual_ssid)
1822
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001823 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1824 if not internet:
1825 raise signals.TestFailure("Failed to connect to internet on %s" %
1826 expected_ssid)
1827 except Exception as error:
1828 ad.log.error("Failed to connect to passpoint network %s with error %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07001829 expected_ssid, error)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001830 raise signals.TestFailure("Failed to connect to %s passpoint network" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001831 expected_ssid)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001832
1833 finally:
1834 ad.droid.wifiStopTrackingStateChange()
1835
1836
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001837def delete_passpoint(ad, fqdn):
1838 """Delete a required Passpoint configuration."""
1839 try:
1840 ad.droid.removePasspointConfig(fqdn)
1841 return True
1842 except Exception as error:
Omar El Ayach8c017902020-10-18 10:26:57 -07001843 ad.log.error(
1844 "Failed to remove passpoint configuration with FQDN=%s "
1845 "and error=%s", fqdn, error)
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001846 return False
1847
1848
Ang Li73697b32015-12-03 00:41:53 +00001849def start_wifi_single_scan(ad, scan_setting):
1850 """Starts wifi single shot scan.
1851
1852 Args:
1853 ad: android_device object to initiate connection on.
1854 scan_setting: A dict representing the settings of the scan.
1855
1856 Returns:
1857 If scan was started successfully, event data of success event is returned.
1858 """
Ang Li82522812016-06-02 13:57:21 -07001859 idx = ad.droid.wifiScannerStartScan(scan_setting)
1860 event = ad.ed.pop_event("WifiScannerScan%sonSuccess" % idx, SHORT_TIMEOUT)
Ang Li31b00782016-06-21 13:04:23 -07001861 ad.log.debug("Got event %s", event)
Ang Li73697b32015-12-03 00:41:53 +00001862 return event['data']
1863
Ang Li82522812016-06-02 13:57:21 -07001864
Ang Li73697b32015-12-03 00:41:53 +00001865def track_connection(ad, network_ssid, check_connection_count):
1866 """Track wifi connection to network changes for given number of counts
1867
1868 Args:
1869 ad: android_device object for forget network.
1870 network_ssid: network ssid to which connection would be tracked
1871 check_connection_count: Integer for maximum number network connection
Ang Li82522812016-06-02 13:57:21 -07001872 check.
Ang Li73697b32015-12-03 00:41:53 +00001873 Returns:
Ang Li73697b32015-12-03 00:41:53 +00001874 True if connection to given network happen, else return False.
1875 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001876 ad.droid.wifiStartTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001877 while check_connection_count > 0:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001878 connect_network = ad.ed.pop_event("WifiNetworkConnected", 120)
Ang Li31b00782016-06-21 13:04:23 -07001879 ad.log.info("Connected to network %s", connect_network)
Ang Li82522812016-06-02 13:57:21 -07001880 if (WifiEnums.SSID_KEY in connect_network['data'] and
1881 connect_network['data'][WifiEnums.SSID_KEY] == network_ssid):
1882 return True
Ang Li8e767182015-12-09 17:29:24 -08001883 check_connection_count -= 1
Girish Moturu40d7dc22016-11-02 12:14:56 -07001884 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001885 return False
1886
Ang Li82522812016-06-02 13:57:21 -07001887
Ang Li73697b32015-12-03 00:41:53 +00001888def get_scan_time_and_channels(wifi_chs, scan_setting, stime_channel):
1889 """Calculate the scan time required based on the band or channels in scan
1890 setting
1891
1892 Args:
1893 wifi_chs: Object of channels supported
1894 scan_setting: scan setting used for start scan
1895 stime_channel: scan time per channel
1896
1897 Returns:
1898 scan_time: time required for completing a scan
1899 scan_channels: channel used for scanning
1900 """
1901 scan_time = 0
1902 scan_channels = []
1903 if "band" in scan_setting and "channels" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001904 scan_channels = wifi_chs.band_to_freq(scan_setting["band"])
Ang Li73697b32015-12-03 00:41:53 +00001905 elif "channels" in scan_setting and "band" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001906 scan_channels = scan_setting["channels"]
Ang Li73697b32015-12-03 00:41:53 +00001907 scan_time = len(scan_channels) * stime_channel
1908 for channel in scan_channels:
Ang Li8e767182015-12-09 17:29:24 -08001909 if channel in WifiEnums.DFS_5G_FREQUENCIES:
Ang Li82522812016-06-02 13:57:21 -07001910 scan_time += 132 #passive scan time on DFS
Ang Li73697b32015-12-03 00:41:53 +00001911 return scan_time, scan_channels
1912
Ang Li82522812016-06-02 13:57:21 -07001913
Ang Li73697b32015-12-03 00:41:53 +00001914def start_wifi_track_bssid(ad, track_setting):
1915 """Start tracking Bssid for the given settings.
1916
1917 Args:
1918 ad: android_device object.
1919 track_setting: Setting for which the bssid tracking should be started
1920
1921 Returns:
1922 If tracking started successfully, event data of success event is returned.
1923 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001924 idx = ad.droid.wifiScannerStartTrackingBssids(
Ang Li82522812016-06-02 13:57:21 -07001925 track_setting["bssidInfos"], track_setting["apLostThreshold"])
Girish Moturu40d7dc22016-11-02 12:14:56 -07001926 event = ad.ed.pop_event("WifiScannerBssid{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -08001927 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +00001928 return event['data']
1929
Ang Li82522812016-06-02 13:57:21 -07001930
Ang Li73697b32015-12-03 00:41:53 +00001931def convert_pem_key_to_pkcs8(in_file, out_file):
1932 """Converts the key file generated by us to the format required by
1933 Android using openssl.
1934
1935 The input file must have the extension "pem". The output file must
1936 have the extension "der".
1937
1938 Args:
1939 in_file: The original key file.
1940 out_file: The full path to the converted key file, including
1941 filename.
1942 """
Ang Li82522812016-06-02 13:57:21 -07001943 asserts.assert_true(in_file.endswith(".pem"), "Input file has to be .pem.")
Omar El Ayach8c017902020-10-18 10:26:57 -07001944 asserts.assert_true(out_file.endswith(".der"),
1945 "Output file has to be .der.")
Ang Li73697b32015-12-03 00:41:53 +00001946 cmd = ("openssl pkcs8 -inform PEM -in {} -outform DER -out {} -nocrypt"
1947 " -topk8").format(in_file, out_file)
Ang Lifee28402016-07-13 13:43:29 -07001948 utils.exe_cmd(cmd)
Ang Li73697b32015-12-03 00:41:53 +00001949
Ang Li82522812016-06-02 13:57:21 -07001950
Omar El Ayach8c017902020-10-18 10:26:57 -07001951def validate_connection(ad,
1952 ping_addr=DEFAULT_PING_ADDR,
1953 wait_time=15,
Girish Moturu804a3492020-02-17 14:32:02 -08001954 ping_gateway=True):
Ang Li73697b32015-12-03 00:41:53 +00001955 """Validate internet connection by pinging the address provided.
1956
1957 Args:
1958 ad: android_device object.
1959 ping_addr: address on internet for pinging.
Girish Moturua2a5bf22019-08-16 09:52:29 -07001960 wait_time: wait for some time before validating connection
Ang Li73697b32015-12-03 00:41:53 +00001961
1962 Returns:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001963 ping output if successful, NULL otherwise.
Ang Li73697b32015-12-03 00:41:53 +00001964 """
Girish Moturua2a5bf22019-08-16 09:52:29 -07001965 # wait_time to allow for DHCP to complete.
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08001966 for i in range(wait_time):
Girish Moturuacf35002020-11-09 23:37:35 -08001967 if ad.droid.connectivityNetworkIsConnected(
Omar El Ayach8c017902020-10-18 10:26:57 -07001968 ) and ad.droid.connectivityGetIPv4DefaultGateway():
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08001969 break
1970 time.sleep(1)
Girish Moturu804a3492020-02-17 14:32:02 -08001971 ping = False
1972 try:
1973 ping = ad.droid.httpPing(ping_addr)
1974 ad.log.info("Http ping result: %s.", ping)
1975 except:
1976 pass
1977 if not ping and ping_gateway:
1978 ad.log.info("Http ping failed. Pinging default gateway")
1979 gw = ad.droid.connectivityGetIPv4DefaultGateway()
1980 result = ad.adb.shell("ping -c 6 {}".format(gw))
1981 ad.log.info("Default gateway ping result: %s" % result)
1982 ping = False if "100% packet loss" in result else True
Ang Li73697b32015-12-03 00:41:53 +00001983 return ping
1984
Ang Li82522812016-06-02 13:57:21 -07001985
Ang Li73697b32015-12-03 00:41:53 +00001986#TODO(angli): This can only verify if an actual value is exactly the same.
1987# Would be nice to be able to verify an actual value is one of serveral.
1988def verify_wifi_connection_info(ad, expected_con):
1989 """Verifies that the information of the currently connected wifi network is
1990 as expected.
1991
1992 Args:
1993 expected_con: A dict representing expected key-value pairs for wifi
1994 connection. e.g. {"SSID": "test_wifi"}
1995 """
1996 current_con = ad.droid.wifiGetConnectionInfo()
Ang Li374d7602016-02-08 17:27:27 -08001997 case_insensitive = ["BSSID", "supplicant_state"]
Ang Li31b00782016-06-21 13:04:23 -07001998 ad.log.debug("Current connection: %s", current_con)
Ang Li73697b32015-12-03 00:41:53 +00001999 for k, expected_v in expected_con.items():
Ang Li9a66de72016-02-08 15:26:38 -08002000 # Do not verify authentication related fields.
2001 if k == "password":
2002 continue
Ang Li82522812016-06-02 13:57:21 -07002003 msg = "Field %s does not exist in wifi connection info %s." % (
2004 k, current_con)
Ang Li374d7602016-02-08 17:27:27 -08002005 if k not in current_con:
2006 raise signals.TestFailure(msg)
2007 actual_v = current_con[k]
2008 if k in case_insensitive:
2009 actual_v = actual_v.lower()
2010 expected_v = expected_v.lower()
Ang Li73697b32015-12-03 00:41:53 +00002011 msg = "Expected %s to be %s, actual %s is %s." % (k, expected_v, k,
Ang Li82522812016-06-02 13:57:21 -07002012 actual_v)
Ang Li374d7602016-02-08 17:27:27 -08002013 if actual_v != expected_v:
2014 raise signals.TestFailure(msg)
Ang Li73697b32015-12-03 00:41:53 +00002015
Ang Li82522812016-06-02 13:57:21 -07002016
Omar El Ayach8c017902020-10-18 10:26:57 -07002017def check_autoconnect_to_open_network(
2018 ad, conn_timeout=WIFI_CONNECTION_TIMEOUT_DEFAULT):
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08002019 """Connects to any open WiFI AP
2020 Args:
2021 timeout value in sec to wait for UE to connect to a WiFi AP
2022 Returns:
2023 True if UE connects to WiFi AP (supplicant_state = completed)
2024 False if UE fails to complete connection within WIFI_CONNECTION_TIMEOUT time.
2025 """
2026 if ad.droid.wifiCheckState():
2027 return True
2028 ad.droid.wifiToggleState()
2029 wifi_connection_state = None
2030 timeout = time.time() + conn_timeout
2031 while wifi_connection_state != "completed":
Omar El Ayach8c017902020-10-18 10:26:57 -07002032 wifi_connection_state = ad.droid.wifiGetConnectionInfo(
2033 )['supplicant_state']
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08002034 if time.time() > timeout:
2035 ad.log.warning("Failed to connect to WiFi AP")
2036 return False
2037 return True
2038
2039
Ang Li73697b32015-12-03 00:41:53 +00002040def expand_enterprise_config_by_phase2(config):
2041 """Take an enterprise config and generate a list of configs, each with
2042 a different phase2 auth type.
2043
2044 Args:
2045 config: A dict representing enterprise config.
2046
2047 Returns
2048 A list of enterprise configs.
2049 """
2050 results = []
Ang Li0e7e58f2016-02-22 12:15:02 -08002051 phase2_types = WifiEnums.EapPhase2
2052 if config[WifiEnums.Enterprise.EAP] == WifiEnums.Eap.PEAP:
2053 # Skip unsupported phase2 types for PEAP.
2054 phase2_types = [WifiEnums.EapPhase2.GTC, WifiEnums.EapPhase2.MSCHAPV2]
2055 for phase2_type in phase2_types:
Ang Li73697b32015-12-03 00:41:53 +00002056 # Skip a special case for passpoint TTLS.
Omar El Ayach8c017902020-10-18 10:26:57 -07002057 if (WifiEnums.Enterprise.FQDN in config
2058 and phase2_type == WifiEnums.EapPhase2.GTC):
Ang Li73697b32015-12-03 00:41:53 +00002059 continue
2060 c = dict(config)
Girish Moturu150d32f2017-02-14 12:27:07 -08002061 c[WifiEnums.Enterprise.PHASE2] = phase2_type.value
Ang Li73697b32015-12-03 00:41:53 +00002062 results.append(c)
2063 return results
Ang Li2d3fe982016-06-08 10:00:43 -07002064
2065
Girish Moturub48a13c2017-02-27 11:36:42 -08002066def generate_eap_test_name(config, ad=None):
Girish Moturu150d32f2017-02-14 12:27:07 -08002067 """ Generates a test case name based on an EAP configuration.
2068
2069 Args:
2070 config: A dict representing an EAP credential.
Girish Moturub48a13c2017-02-27 11:36:42 -08002071 ad object: Redundant but required as the same param is passed
2072 to test_func in run_generated_tests
Girish Moturu150d32f2017-02-14 12:27:07 -08002073
2074 Returns:
2075 A string representing the name of a generated EAP test case.
2076 """
2077 eap = WifiEnums.Eap
2078 eap_phase2 = WifiEnums.EapPhase2
Girish Moturub48a13c2017-02-27 11:36:42 -08002079 Ent = WifiEnums.Enterprise
Girish Moturu150d32f2017-02-14 12:27:07 -08002080 name = "test_connect-"
2081 eap_name = ""
2082 for e in eap:
2083 if e.value == config[Ent.EAP]:
2084 eap_name = e.name
2085 break
2086 if "peap0" in config[WifiEnums.SSID_KEY].lower():
2087 eap_name = "PEAP0"
2088 if "peap1" in config[WifiEnums.SSID_KEY].lower():
2089 eap_name = "PEAP1"
2090 name += eap_name
2091 if Ent.PHASE2 in config:
2092 for e in eap_phase2:
2093 if e.value == config[Ent.PHASE2]:
2094 name += "-{}".format(e.name)
2095 break
2096 return name
2097
2098
Ang Li2d3fe982016-06-08 10:00:43 -07002099def group_attenuators(attenuators):
2100 """Groups a list of attenuators into attenuator groups for backward
2101 compatibility reasons.
2102
2103 Most legacy Wi-Fi setups have two attenuators each connected to a separate
2104 AP. The new Wi-Fi setup has four attenuators, each connected to one channel
2105 on an AP, so two of them are connected to one AP.
2106
2107 To make the existing scripts work in the new setup, when the script needs
2108 to attenuate one AP, it needs to set attenuation on both attenuators
2109 connected to the same AP.
2110
2111 This function groups attenuators properly so the scripts work in both
2112 legacy and new Wi-Fi setups.
2113
2114 Args:
2115 attenuators: A list of attenuator objects, either two or four in length.
2116
2117 Raises:
2118 signals.TestFailure is raised if the attenuator list does not have two
2119 or four objects.
2120 """
2121 attn0 = attenuator.AttenuatorGroup("AP0")
2122 attn1 = attenuator.AttenuatorGroup("AP1")
2123 # Legacy testbed setup has two attenuation channels.
2124 num_of_attns = len(attenuators)
2125 if num_of_attns == 2:
2126 attn0.add(attenuators[0])
2127 attn1.add(attenuators[1])
2128 elif num_of_attns == 4:
2129 attn0.add(attenuators[0])
2130 attn0.add(attenuators[1])
2131 attn1.add(attenuators[2])
2132 attn1.add(attenuators[3])
2133 else:
2134 asserts.fail(("Either two or four attenuators are required for this "
2135 "test, but found %s") % num_of_attns)
2136 return [attn0, attn1]
Jong Wook Kim92356922018-02-06 18:32:49 -08002137
Bindu Mahadevff295782019-02-08 16:17:48 -08002138
Girish Moturu36348a32019-12-10 08:41:54 -08002139def set_attns(attenuator, attn_val_name, roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002140 """Sets attenuation values on attenuators used in this test.
2141
2142 Args:
2143 attenuator: The attenuator object.
2144 attn_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002145 roaming_attn: Dictionary specifying the attenuation params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002146 """
2147 logging.info("Set attenuation values to %s", roaming_attn[attn_val_name])
2148 try:
2149 attenuator[0].set_atten(roaming_attn[attn_val_name][0])
2150 attenuator[1].set_atten(roaming_attn[attn_val_name][1])
2151 attenuator[2].set_atten(roaming_attn[attn_val_name][2])
2152 attenuator[3].set_atten(roaming_attn[attn_val_name][3])
2153 except:
2154 logging.exception("Failed to set attenuation values %s.",
Omar El Ayach8c017902020-10-18 10:26:57 -07002155 attn_val_name)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002156 raise
2157
Omar El Ayach8c017902020-10-18 10:26:57 -07002158
Girish Moturu36348a32019-12-10 08:41:54 -08002159def set_attns_steps(attenuators,
2160 atten_val_name,
2161 roaming_attn=ROAMING_ATTN,
2162 steps=10,
2163 wait_time=12):
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002164 """Set attenuation values on attenuators used in this test. It will change
2165 the attenuation values linearly from current value to target value step by
2166 step.
2167
2168 Args:
2169 attenuators: The list of attenuator objects that you want to change
2170 their attenuation value.
2171 atten_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002172 roaming_attn: Dictionary specifying the attenuation params.
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002173 steps: Number of attenuator changes to reach the target value.
2174 wait_time: Sleep time for each change of attenuator.
2175 """
2176 logging.info("Set attenuation values to %s in %d step(s)",
Omar El Ayach8c017902020-10-18 10:26:57 -07002177 roaming_attn[atten_val_name], steps)
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002178 start_atten = [attenuator.get_atten() for attenuator in attenuators]
2179 target_atten = roaming_attn[atten_val_name]
2180 for current_step in range(steps):
2181 progress = (current_step + 1) / steps
2182 for i, attenuator in enumerate(attenuators):
2183 amount_since_start = (target_atten[i] - start_atten[i]) * progress
2184 attenuator.set_atten(round(start_atten[i] + amount_since_start))
2185 time.sleep(wait_time)
2186
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002187
Girish Moturu36348a32019-12-10 08:41:54 -08002188def trigger_roaming_and_validate(dut,
2189 attenuator,
2190 attn_val_name,
2191 expected_con,
2192 roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002193 """Sets attenuators to trigger roaming and validate the DUT connected
2194 to the BSSID expected.
2195
2196 Args:
2197 attenuator: The attenuator object.
2198 attn_val_name: Name of the attenuation value pair to use.
2199 expected_con: The network information of the expected network.
Girish Moturu36348a32019-12-10 08:41:54 -08002200 roaming_attn: Dictionary specifying the attenaution params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002201 """
2202 expected_con = {
2203 WifiEnums.SSID_KEY: expected_con[WifiEnums.SSID_KEY],
2204 WifiEnums.BSSID_KEY: expected_con["bssid"],
2205 }
Girish Moturu36348a32019-12-10 08:41:54 -08002206 set_attns_steps(attenuator, attn_val_name, roaming_attn)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002207
Hsiu-Chang Chenef856402018-09-18 12:32:49 +08002208 verify_wifi_connection_info(dut, expected_con)
2209 expected_bssid = expected_con[WifiEnums.BSSID_KEY]
2210 logging.info("Roamed to %s successfully", expected_bssid)
2211 if not validate_connection(dut):
2212 raise signals.TestFailure("Fail to connect to internet on %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07002213 expected_bssid)
2214
Jong Wook Kim92356922018-02-06 18:32:49 -08002215
2216def create_softap_config():
2217 """Create a softap config with random ssid and password."""
2218 ap_ssid = "softap_" + utils.rand_ascii_str(8)
2219 ap_password = utils.rand_ascii_str(8)
2220 logging.info("softap setup: %s %s", ap_ssid, ap_password)
2221 config = {
2222 WifiEnums.SSID_KEY: ap_ssid,
2223 WifiEnums.PWD_KEY: ap_password,
2224 }
2225 return config
Girish Moturucf4dccd2018-08-27 12:22:00 -07002226
Omar El Ayach8c017902020-10-18 10:26:57 -07002227
Bindu Mahadevff295782019-02-08 16:17:48 -08002228def start_softap_and_verify(ad, band):
2229 """Bring-up softap and verify AP mode and in scan results.
2230
2231 Args:
2232 band: The band to use for softAP.
2233
2234 Returns: dict, the softAP config.
2235
2236 """
lesl2f0fb232019-11-05 16:35:28 +08002237 # Register before start the test.
2238 callbackId = ad.dut.droid.registerSoftApCallback()
2239 # Check softap info value is default
2240 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2241 asserts.assert_true(frequency == 0, "Softap frequency is not reset")
2242 asserts.assert_true(bandwdith == 0, "Softap bandwdith is not reset")
2243
Bindu Mahadevff295782019-02-08 16:17:48 -08002244 config = create_softap_config()
2245 start_wifi_tethering(ad.dut,
2246 config[WifiEnums.SSID_KEY],
Omar El Ayach8c017902020-10-18 10:26:57 -07002247 config[WifiEnums.PWD_KEY],
2248 band=band)
Bindu Mahadevff295782019-02-08 16:17:48 -08002249 asserts.assert_true(ad.dut.droid.wifiIsApEnabled(),
Omar El Ayach8c017902020-10-18 10:26:57 -07002250 "SoftAp is not reported as running")
2251 start_wifi_connection_scan_and_ensure_network_found(
2252 ad.dut_client, config[WifiEnums.SSID_KEY])
lesl2f0fb232019-11-05 16:35:28 +08002253
2254 # Check softap info can get from callback succeed and assert value should be
2255 # valid.
2256 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2257 asserts.assert_true(frequency > 0, "Softap frequency is not valid")
2258 asserts.assert_true(bandwdith > 0, "Softap bandwdith is not valid")
2259 # Unregister callback
2260 ad.dut.droid.unregisterSoftApCallback(callbackId)
2261
Bindu Mahadevff295782019-02-08 16:17:48 -08002262 return config
2263
Omar El Ayach8c017902020-10-18 10:26:57 -07002264
lesle8e3c0a2019-02-22 17:06:04 +08002265def wait_for_expected_number_of_softap_clients(ad, callbackId,
Omar El Ayach8c017902020-10-18 10:26:57 -07002266 expected_num_of_softap_clients):
lesle8e3c0a2019-02-22 17:06:04 +08002267 """Wait for the number of softap clients to be updated as expected.
2268 Args:
2269 callbackId: Id of the callback associated with registering.
2270 expected_num_of_softap_clients: expected number of softap clients.
2271 """
2272 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002273 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
James Mattis5a5dd492020-05-14 13:09:43 -07002274 clientData = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data']
2275 clientCount = clientData[wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07002276 clientMacAddresses = clientData[
2277 wifi_constants.SOFTAP_CLIENTS_MACS_CALLBACK_KEY]
2278 asserts.assert_equal(
2279 clientCount, expected_num_of_softap_clients,
2280 "The number of softap clients doesn't match the expected number")
2281 asserts.assert_equal(
2282 len(clientMacAddresses), expected_num_of_softap_clients,
2283 "The number of mac addresses doesn't match the expected number")
James Mattis5a5dd492020-05-14 13:09:43 -07002284 for macAddress in clientMacAddresses:
Omar El Ayach8c017902020-10-18 10:26:57 -07002285 asserts.assert_true(checkMacAddress(macAddress),
2286 "An invalid mac address was returned")
2287
James Mattis5a5dd492020-05-14 13:09:43 -07002288
2289def checkMacAddress(input):
2290 """Validate whether a string is a valid mac address or not.
2291
2292 Args:
2293 input: The string to validate.
2294
2295 Returns: True/False, returns true for a valid mac address and false otherwise.
2296 """
2297 macValidationRegex = "[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$"
2298 if re.match(macValidationRegex, input.lower()):
2299 return True
2300 return False
lesle8e3c0a2019-02-22 17:06:04 +08002301
Omar El Ayach8c017902020-10-18 10:26:57 -07002302
lesle8e3c0a2019-02-22 17:06:04 +08002303def wait_for_expected_softap_state(ad, callbackId, expected_softap_state):
2304 """Wait for the expected softap state change.
2305 Args:
2306 callbackId: Id of the callback associated with registering.
2307 expected_softap_state: The expected softap state.
2308 """
2309 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002310 callbackId) + wifi_constants.SOFTAP_STATE_CHANGED
2311 asserts.assert_equal(
2312 ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data'][
2313 wifi_constants.SOFTAP_STATE_CHANGE_CALLBACK_KEY],
2314 expected_softap_state,
2315 "Softap state doesn't match with expected state")
2316
lesle8e3c0a2019-02-22 17:06:04 +08002317
2318def get_current_number_of_softap_clients(ad, callbackId):
2319 """pop up all of softap client updated event from queue.
2320 Args:
2321 callbackId: Id of the callback associated with registering.
2322
2323 Returns:
2324 If exist aleast callback, returns last updated number_of_softap_clients.
2325 Returns None when no any match callback event in queue.
2326 """
2327 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002328 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
lesle8e3c0a2019-02-22 17:06:04 +08002329 events = ad.ed.pop_all(eventStr)
2330 for event in events:
Omar El Ayach8c017902020-10-18 10:26:57 -07002331 num_of_clients = event['data'][
2332 wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
lesle8e3c0a2019-02-22 17:06:04 +08002333 if len(events) == 0:
2334 return None
2335 return num_of_clients
Bindu Mahadevff295782019-02-08 16:17:48 -08002336
Omar El Ayach8c017902020-10-18 10:26:57 -07002337
lesl2f0fb232019-11-05 16:35:28 +08002338def get_current_softap_info(ad, callbackId, least_one):
2339 """pop up all of softap info changed event from queue.
2340 Args:
2341 callbackId: Id of the callback associated with registering.
2342 least_one: Wait for the info callback event before pop all.
2343 Returns:
2344 Returns last updated information of softap.
2345 """
2346 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002347 callbackId) + wifi_constants.SOFTAP_INFO_CHANGED
2348 ad.log.info("softap info dump from eventStr %s", eventStr)
lesl2f0fb232019-11-05 16:35:28 +08002349 frequency = 0
2350 bandwidth = 0
2351 if (least_one):
2352 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
Omar El Ayach8c017902020-10-18 10:26:57 -07002353 frequency = event['data'][
2354 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2355 bandwidth = event['data'][
2356 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
lesl2f0fb232019-11-05 16:35:28 +08002357 ad.log.info("softap info updated, frequency is %s, bandwidth is %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07002358 frequency, bandwidth)
lesl2f0fb232019-11-05 16:35:28 +08002359
2360 events = ad.ed.pop_all(eventStr)
2361 for event in events:
Omar El Ayach8c017902020-10-18 10:26:57 -07002362 frequency = event['data'][
2363 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2364 bandwidth = event['data'][
2365 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
2366 ad.log.info("softap info, frequency is %s, bandwidth is %s", frequency,
2367 bandwidth)
lesl2f0fb232019-11-05 16:35:28 +08002368 return frequency, bandwidth
2369
2370
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002371def get_ssrdumps(ad):
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002372 """Pulls dumps in the ssrdump dir
2373 Args:
2374 ad: android device object.
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002375 """
2376 logs = ad.get_file_names("/data/vendor/ssrdump/")
2377 if logs:
2378 ad.log.info("Pulling ssrdumps %s", logs)
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002379 log_path = os.path.join(ad.device_log_path, "SSRDUMPS_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002380 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002381 ad.pull_files(logs, log_path)
Hsiu-Chang Chen769bef12020-10-10 06:07:52 +00002382 ad.adb.shell("find /data/vendor/ssrdump/ -type f -delete",
Omar El Ayach8c017902020-10-18 10:26:57 -07002383 ignore_status=True)
2384
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002385
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002386def start_pcap(pcap, wifi_band, test_name):
Girish Moturucf4dccd2018-08-27 12:22:00 -07002387 """Start packet capture in monitor mode.
2388
2389 Args:
2390 pcap: packet capture object
2391 wifi_band: '2g' or '5g' or 'dual'
Bindu Mahadev76551c12018-12-13 19:42:14 +00002392 test_name: test name to be used for pcap file name
2393
2394 Returns:
xianyuanjia0431ba32018-12-14 09:56:42 -08002395 Dictionary with wifi band as key and the tuple
2396 (pcap Process object, log directory) as the value
Girish Moturucf4dccd2018-08-27 12:22:00 -07002397 """
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002398 log_dir = os.path.join(
Xianyuan Jia5cd06bb2019-06-10 16:29:57 -07002399 context.get_current_context().get_full_output_path(), 'PacketCapture')
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002400 os.makedirs(log_dir, exist_ok=True)
Girish Moturucf4dccd2018-08-27 12:22:00 -07002401 if wifi_band == 'dual':
2402 bands = [BAND_2G, BAND_5G]
2403 else:
2404 bands = [wifi_band]
xianyuanjia0431ba32018-12-14 09:56:42 -08002405 procs = {}
Girish Moturucf4dccd2018-08-27 12:22:00 -07002406 for band in bands:
xianyuanjia0431ba32018-12-14 09:56:42 -08002407 proc = pcap.start_packet_capture(band, log_dir, test_name)
2408 procs[band] = (proc, os.path.join(log_dir, test_name))
2409 return procs
Girish Moturucf4dccd2018-08-27 12:22:00 -07002410
Bindu Mahadevff295782019-02-08 16:17:48 -08002411
xianyuanjia0431ba32018-12-14 09:56:42 -08002412def stop_pcap(pcap, procs, test_status=None):
Bindu Mahadev76551c12018-12-13 19:42:14 +00002413 """Stop packet capture in monitor mode.
2414
2415 Since, the pcap logs in monitor mode can be very large, we will
2416 delete them if they are not required. 'test_status' if True, will delete
2417 the pcap files. If False, we will keep them.
Girish Moturucf4dccd2018-08-27 12:22:00 -07002418
2419 Args:
2420 pcap: packet capture object
xianyuanjia0431ba32018-12-14 09:56:42 -08002421 procs: dictionary returned by start_pcap
Bindu Mahadev76551c12018-12-13 19:42:14 +00002422 test_status: status of the test case
Girish Moturucf4dccd2018-08-27 12:22:00 -07002423 """
xianyuanjia0431ba32018-12-14 09:56:42 -08002424 for proc, fname in procs.values():
2425 pcap.stop_packet_capture(proc)
Bindu Mahadev76551c12018-12-13 19:42:14 +00002426
2427 if test_status:
xianyuanjia0431ba32018-12-14 09:56:42 -08002428 shutil.rmtree(os.path.dirname(fname))
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002429
Omar El Ayach8c017902020-10-18 10:26:57 -07002430
Jaineel95887fd2019-10-16 16:19:01 -07002431def verify_mac_not_found_in_pcap(ad, mac, packets):
xshuf7267682019-06-03 14:41:56 -07002432 """Verify that a mac address is not found in the captured packets.
2433
2434 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002435 ad: android device object
xshuf7267682019-06-03 14:41:56 -07002436 mac: string representation of the mac address
2437 packets: packets obtained by rdpcap(pcap_fname)
2438 """
2439 for pkt in packets:
2440 logging.debug("Packet Summary = %s", pkt.summary())
2441 if mac in pkt.summary():
Jaineel95887fd2019-10-16 16:19:01 -07002442 asserts.fail("Device %s caught Factory MAC: %s in packet sniffer."
2443 "Packet = %s" % (ad.serial, mac, pkt.show()))
Bindu Mahadevff295782019-02-08 16:17:48 -08002444
Omar El Ayach8c017902020-10-18 10:26:57 -07002445
Jaineel95887fd2019-10-16 16:19:01 -07002446def verify_mac_is_found_in_pcap(ad, mac, packets):
Nate Jiangc2c09c62019-06-05 17:26:08 -07002447 """Verify that a mac address is found in the captured packets.
2448
2449 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002450 ad: android device object
Nate Jiangc2c09c62019-06-05 17:26:08 -07002451 mac: string representation of the mac address
2452 packets: packets obtained by rdpcap(pcap_fname)
2453 """
2454 for pkt in packets:
2455 if mac in pkt.summary():
2456 return
Jaineel95887fd2019-10-16 16:19:01 -07002457 asserts.fail("Did not find MAC = %s in packet sniffer."
2458 "for device %s" % (mac, ad.serial))
Nate Jiangc2c09c62019-06-05 17:26:08 -07002459
Omar El Ayach8c017902020-10-18 10:26:57 -07002460
Girish Moturuddc0d382020-08-24 12:08:41 -07002461def start_cnss_diags(ads, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002462 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002463 start_cnss_diag(ad, cnss_diag_file, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002464
Bindu Mahadevff295782019-02-08 16:17:48 -08002465
Girish Moturuddc0d382020-08-24 12:08:41 -07002466def start_cnss_diag(ad, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002467 """Start cnss_diag to record extra wifi logs
2468
2469 Args:
2470 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002471 cnss_diag_file: cnss diag config file to push to device.
2472 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002473 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002474 if ad.model not in pixel_models:
2475 ad.log.info("Device not supported to collect pixel logger")
2476 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002477 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2478 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2479 else:
2480 prop = wifi_constants.CNSS_DIAG_PROP
2481 if ad.adb.getprop(prop) != 'true':
Omar El Ayach8c017902020-10-18 10:26:57 -07002482 if not int(
2483 ad.adb.shell("ls -l %s%s | wc -l" %
2484 (CNSS_DIAG_CONFIG_PATH, CNSS_DIAG_CONFIG_FILE))):
Girish Moturuddc0d382020-08-24 12:08:41 -07002485 ad.adb.push("%s %s" % (cnss_diag_file, CNSS_DIAG_CONFIG_PATH))
Omar El Ayach8c017902020-10-18 10:26:57 -07002486 ad.adb.shell(
2487 "find /data/vendor/wifi/cnss_diag/wlan_logs/ -type f -delete",
2488 ignore_status=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002489 ad.adb.shell("setprop %s true" % prop, ignore_status=True)
2490
Bindu Mahadevff295782019-02-08 16:17:48 -08002491
Girish Moturuddc0d382020-08-24 12:08:41 -07002492def stop_cnss_diags(ads, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002493 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002494 stop_cnss_diag(ad, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002495
Bindu Mahadevff295782019-02-08 16:17:48 -08002496
Girish Moturuddc0d382020-08-24 12:08:41 -07002497def stop_cnss_diag(ad, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002498 """Stops cnss_diag
2499
2500 Args:
2501 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002502 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002503 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002504 if ad.model not in pixel_models:
2505 ad.log.info("Device not supported to collect pixel logger")
2506 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002507 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2508 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2509 else:
2510 prop = wifi_constants.CNSS_DIAG_PROP
2511 ad.adb.shell("setprop %s false" % prop, ignore_status=True)
2512
Bindu Mahadevff295782019-02-08 16:17:48 -08002513
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002514def get_cnss_diag_log(ad):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002515 """Pulls the cnss_diag logs in the wlan_logs dir
2516 Args:
2517 ad: android device object.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002518 """
2519 logs = ad.get_file_names("/data/vendor/wifi/cnss_diag/wlan_logs/")
2520 if logs:
2521 ad.log.info("Pulling cnss_diag logs %s", logs)
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002522 log_path = os.path.join(ad.device_log_path, "CNSS_DIAG_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002523 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002524 ad.pull_files(logs, log_path)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002525
Bindu Mahadevff295782019-02-08 16:17:48 -08002526
Omar El Ayach8c017902020-10-18 10:26:57 -07002527LinkProbeResult = namedtuple(
2528 'LinkProbeResult',
2529 ('is_success', 'stdout', 'elapsed_time', 'failure_reason'))
David Sue4cd9c22019-03-26 18:07:26 -07002530
2531
2532def send_link_probe(ad):
2533 """Sends a link probe to the currently connected AP, and returns whether the
2534 probe succeeded or not.
2535
2536 Args:
2537 ad: android device object
2538 Returns:
2539 LinkProbeResult namedtuple
2540 """
2541 stdout = ad.adb.shell('cmd wifi send-link-probe')
2542 asserts.assert_false('Error' in stdout or 'Exception' in stdout,
2543 'Exception while sending link probe: ' + stdout)
2544
2545 is_success = False
2546 elapsed_time = None
2547 failure_reason = None
2548 if 'succeeded' in stdout:
2549 is_success = True
2550 elapsed_time = next(
2551 (int(token) for token in stdout.split() if token.isdigit()), None)
2552 elif 'failed with reason' in stdout:
2553 failure_reason = next(
2554 (int(token) for token in stdout.split() if token.isdigit()), None)
2555 else:
2556 asserts.fail('Unexpected link probe result: ' + stdout)
2557
Omar El Ayach8c017902020-10-18 10:26:57 -07002558 return LinkProbeResult(is_success=is_success,
2559 stdout=stdout,
2560 elapsed_time=elapsed_time,
2561 failure_reason=failure_reason)
David Sue4cd9c22019-03-26 18:07:26 -07002562
2563
2564def send_link_probes(ad, num_probes, delay_sec):
2565 """Sends a sequence of link probes to the currently connected AP, and
2566 returns whether the probes succeeded or not.
2567
2568 Args:
2569 ad: android device object
2570 num_probes: number of probes to perform
2571 delay_sec: delay time between probes, in seconds
2572 Returns:
2573 List[LinkProbeResult] one LinkProbeResults for each probe
2574 """
2575 logging.info('Sending link probes')
2576 results = []
2577 for _ in range(num_probes):
2578 # send_link_probe() will also fail the test if it sees an exception
2579 # in the stdout of the adb shell command
2580 result = send_link_probe(ad)
2581 logging.info('link probe results: ' + str(result))
2582 results.append(result)
2583 time.sleep(delay_sec)
2584
2585 return results
2586
2587
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002588def ap_setup(test, index, ap, network, bandwidth=80, channel=6):
Omar El Ayach8c017902020-10-18 10:26:57 -07002589 """Set up the AP with provided network info.
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002590
2591 Args:
2592 test: the calling test class object.
2593 index: int, index of the AP.
2594 ap: access_point object of the AP.
2595 network: dict with information of the network, including ssid,
2596 password and bssid.
2597 bandwidth: the operation bandwidth for the AP, default 80MHz.
2598 channel: the channel number for the AP.
2599 Returns:
2600 brconfigs: the bridge interface configs
2601 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002602 bss_settings = []
2603 ssid = network[WifiEnums.SSID_KEY]
2604 test.access_points[index].close()
2605 time.sleep(5)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002606
Omar El Ayach8c017902020-10-18 10:26:57 -07002607 # Configure AP as required.
2608 if "password" in network.keys():
2609 password = network["password"]
2610 security = hostapd_security.Security(security_mode="wpa",
2611 password=password)
2612 else:
2613 security = hostapd_security.Security(security_mode=None, password=None)
2614 config = hostapd_ap_preset.create_ap_preset(channel=channel,
2615 ssid=ssid,
2616 security=security,
2617 bss_settings=bss_settings,
2618 vht_bandwidth=bandwidth,
2619 profile_name='whirlwind',
2620 iface_wlan_2g=ap.wlan_2g,
2621 iface_wlan_5g=ap.wlan_5g)
2622 ap.start_ap(config)
2623 logging.info("AP started on channel {} with SSID {}".format(channel, ssid))
Bindu Mahadevff295782019-02-08 16:17:48 -08002624
2625
2626def turn_ap_off(test, AP):
2627 """Bring down hostapd on the Access Point.
2628 Args:
2629 test: The test class object.
2630 AP: int, indicating which AP to turn OFF.
2631 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002632 hostapd_2g = test.access_points[AP - 1]._aps['wlan0'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002633 if hostapd_2g.is_alive():
2634 hostapd_2g.stop()
2635 logging.debug('Turned WLAN0 AP%d off' % AP)
Omar El Ayach8c017902020-10-18 10:26:57 -07002636 hostapd_5g = test.access_points[AP - 1]._aps['wlan1'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002637 if hostapd_5g.is_alive():
2638 hostapd_5g.stop()
2639 logging.debug('Turned WLAN1 AP%d off' % AP)
2640
2641
2642def turn_ap_on(test, AP):
2643 """Bring up hostapd on the Access Point.
2644 Args:
2645 test: The test class object.
2646 AP: int, indicating which AP to turn ON.
2647 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002648 hostapd_2g = test.access_points[AP - 1]._aps['wlan0'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002649 if not hostapd_2g.is_alive():
2650 hostapd_2g.start(hostapd_2g.config)
2651 logging.debug('Turned WLAN0 AP%d on' % AP)
Omar El Ayach8c017902020-10-18 10:26:57 -07002652 hostapd_5g = test.access_points[AP - 1]._aps['wlan1'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002653 if not hostapd_5g.is_alive():
2654 hostapd_5g.start(hostapd_5g.config)
2655 logging.debug('Turned WLAN1 AP%d on' % AP)
Joe Brennan48c3f692019-04-11 08:30:16 -07002656
2657
2658def turn_location_off_and_scan_toggle_off(ad):
2659 """Turns off wifi location scans."""
2660 utils.set_location_service(ad, False)
2661 ad.droid.wifiScannerToggleAlwaysAvailable(False)
2662 msg = "Failed to turn off location service's scan."
2663 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
Alfie Chen675be872020-06-04 10:48:14 +08002664
2665
2666def set_softap_channel(dut, ap_iface='wlan1', cs_count=10, channel=2462):
2667 """ Set SoftAP mode channel
2668
2669 Args:
2670 dut: android device object
2671 ap_iface: interface of SoftAP mode.
2672 cs_count: how many beacon frames before switch channel, default = 10
2673 channel: a wifi channel.
2674 """
2675 chan_switch_cmd = 'hostapd_cli -i {} chan_switch {} {}'
Omar El Ayach8c017902020-10-18 10:26:57 -07002676 chan_switch_cmd_show = chan_switch_cmd.format(ap_iface, cs_count, channel)
Alfie Chen675be872020-06-04 10:48:14 +08002677 dut.log.info('adb shell {}'.format(chan_switch_cmd_show))
Omar El Ayach8c017902020-10-18 10:26:57 -07002678 chan_switch_result = dut.adb.shell(
2679 chan_switch_cmd.format(ap_iface, cs_count, channel))
Alfie Chen675be872020-06-04 10:48:14 +08002680 if chan_switch_result == 'OK':
2681 dut.log.info('switch hotspot channel to {}'.format(channel))
2682 return chan_switch_result
2683
2684 asserts.fail("Failed to switch hotspot channel")
Alfie Chen310f7ff2021-01-26 20:36:09 +08002685
2686def get_wlan0_link(dut):
2687 """ get wlan0 interface status"""
2688 get_wlan0 = 'wpa_cli -iwlan0 -g@android:wpa_wlan0 IFNAME=wlan0 status'
2689 out = dut.adb.shell(get_wlan0)
2690 out = dict(re.findall(r'(\S+)=(".*?"|\S+)', out))
2691 asserts.assert_true("ssid" in out,
2692 "Client doesn't connect to any network")
2693 return out