blob: 42948c61b0a14da72be913dd11733a5913e155b0 [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():
121 CHINA = "CN"
Girish Moturua5ef35d2020-10-19 14:58:01 -0700122 GERMANY = "DE"
Ang Li73697b32015-12-03 00:41:53 +0000123 JAPAN = "JP"
124 UK = "GB"
125 US = "US"
126 UNKNOWN = "UNKNOWN"
127
128 # Start of Macros for EAP
129 # EAP types
130 class Eap(IntEnum):
131 NONE = -1
132 PEAP = 0
Ang Li82522812016-06-02 13:57:21 -0700133 TLS = 1
Ang Li73697b32015-12-03 00:41:53 +0000134 TTLS = 2
Ang Li82522812016-06-02 13:57:21 -0700135 PWD = 3
136 SIM = 4
137 AKA = 5
138 AKA_PRIME = 6
139 UNAUTH_TLS = 7
Ang Li73697b32015-12-03 00:41:53 +0000140
141 # EAP Phase2 types
142 class EapPhase2(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700143 NONE = 0
144 PAP = 1
145 MSCHAP = 2
146 MSCHAPV2 = 3
147 GTC = 4
Ang Li73697b32015-12-03 00:41:53 +0000148
149 class Enterprise:
Ang Li82522812016-06-02 13:57:21 -0700150 # Enterprise Config Macros
151 EMPTY_VALUE = "NULL"
152 EAP = "eap"
153 PHASE2 = "phase2"
154 IDENTITY = "identity"
155 ANON_IDENTITY = "anonymous_identity"
156 PASSWORD = "password"
157 SUBJECT_MATCH = "subject_match"
Ang Li73697b32015-12-03 00:41:53 +0000158 ALTSUBJECT_MATCH = "altsubject_match"
159 DOM_SUFFIX_MATCH = "domain_suffix_match"
Ang Li82522812016-06-02 13:57:21 -0700160 CLIENT_CERT = "client_cert"
161 CA_CERT = "ca_cert"
162 ENGINE = "engine"
163 ENGINE_ID = "engine_id"
164 PRIVATE_KEY_ID = "key_id"
165 REALM = "realm"
166 PLMN = "plmn"
167 FQDN = "FQDN"
168 FRIENDLY_NAME = "providerFriendlyName"
169 ROAMING_IDS = "roamingConsortiumIds"
Jimmy Chen7baec622020-06-23 19:00:33 +0800170 OCSP = "ocsp"
Omar El Ayach8c017902020-10-18 10:26:57 -0700171
Ang Li73697b32015-12-03 00:41:53 +0000172 # End of Macros for EAP
173
174 # Macros for wifi p2p.
175 WIFI_P2P_SERVICE_TYPE_ALL = 0
176 WIFI_P2P_SERVICE_TYPE_BONJOUR = 1
177 WIFI_P2P_SERVICE_TYPE_UPNP = 2
178 WIFI_P2P_SERVICE_TYPE_VENDOR_SPECIFIC = 255
179
180 class ScanResult:
181 CHANNEL_WIDTH_20MHZ = 0
182 CHANNEL_WIDTH_40MHZ = 1
183 CHANNEL_WIDTH_80MHZ = 2
184 CHANNEL_WIDTH_160MHZ = 3
185 CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4
186
187 # Macros for wifi rtt.
188 class RttType(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700189 TYPE_ONE_SIDED = 1
190 TYPE_TWO_SIDED = 2
Ang Li73697b32015-12-03 00:41:53 +0000191
192 class RttPeerType(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700193 PEER_TYPE_AP = 1
194 PEER_TYPE_STA = 2 # Requires NAN.
195 PEER_P2P_GO = 3
196 PEER_P2P_CLIENT = 4
197 PEER_NAN = 5
Ang Li73697b32015-12-03 00:41:53 +0000198
199 class RttPreamble(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700200 PREAMBLE_LEGACY = 0x01
201 PREAMBLE_HT = 0x02
202 PREAMBLE_VHT = 0x04
Ang Li73697b32015-12-03 00:41:53 +0000203
204 class RttBW(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700205 BW_5_SUPPORT = 0x01
206 BW_10_SUPPORT = 0x02
207 BW_20_SUPPORT = 0x04
208 BW_40_SUPPORT = 0x08
209 BW_80_SUPPORT = 0x10
Ang Li73697b32015-12-03 00:41:53 +0000210 BW_160_SUPPORT = 0x20
211
212 class Rtt(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700213 STATUS_SUCCESS = 0
214 STATUS_FAILURE = 1
215 STATUS_FAIL_NO_RSP = 2
216 STATUS_FAIL_REJECTED = 3
217 STATUS_FAIL_NOT_SCHEDULED_YET = 4
218 STATUS_FAIL_TM_TIMEOUT = 5
219 STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6
220 STATUS_FAIL_NO_CAPABILITY = 7
221 STATUS_ABORTED = 8
222 STATUS_FAIL_INVALID_TS = 9
223 STATUS_FAIL_PROTOCOL = 10
224 STATUS_FAIL_SCHEDULE = 11
225 STATUS_FAIL_BUSY_TRY_LATER = 12
226 STATUS_INVALID_REQ = 13
227 STATUS_NO_WIFI = 14
228 STATUS_FAIL_FTM_PARAM_OVERRIDE = 15
Ang Li73697b32015-12-03 00:41:53 +0000229
Ang Li82522812016-06-02 13:57:21 -0700230 REASON_UNSPECIFIED = -1
231 REASON_NOT_AVAILABLE = -2
232 REASON_INVALID_LISTENER = -3
233 REASON_INVALID_REQUEST = -4
Ang Li73697b32015-12-03 00:41:53 +0000234
235 class RttParam:
236 device_type = "deviceType"
237 request_type = "requestType"
238 BSSID = "bssid"
239 channel_width = "channelWidth"
240 frequency = "frequency"
241 center_freq0 = "centerFreq0"
242 center_freq1 = "centerFreq1"
243 number_burst = "numberBurst"
244 interval = "interval"
245 num_samples_per_burst = "numSamplesPerBurst"
246 num_retries_per_measurement_frame = "numRetriesPerMeasurementFrame"
247 num_retries_per_FTMR = "numRetriesPerFTMR"
248 lci_request = "LCIRequest"
249 lcr_request = "LCRRequest"
250 burst_timeout = "burstTimeout"
251 preamble = "preamble"
252 bandwidth = "bandwidth"
253 margin = "margin"
254
255 RTT_MARGIN_OF_ERROR = {
256 RttBW.BW_80_SUPPORT: 2,
257 RttBW.BW_40_SUPPORT: 5,
258 RttBW.BW_20_SUPPORT: 5
259 }
260
261 # Macros as specified in the WifiScanner code.
Ang Li82522812016-06-02 13:57:21 -0700262 WIFI_BAND_UNSPECIFIED = 0 # not specified
263 WIFI_BAND_24_GHZ = 1 # 2.4 GHz band
264 WIFI_BAND_5_GHZ = 2 # 5 GHz band without DFS channels
265 WIFI_BAND_5_GHZ_DFS_ONLY = 4 # 5 GHz band with DFS channels
266 WIFI_BAND_5_GHZ_WITH_DFS = 6 # 5 GHz band with DFS channels
267 WIFI_BAND_BOTH = 3 # both bands without DFS channels
268 WIFI_BAND_BOTH_WITH_DFS = 7 # both bands with DFS channels
Ang Li73697b32015-12-03 00:41:53 +0000269
270 REPORT_EVENT_AFTER_BUFFER_FULL = 0
271 REPORT_EVENT_AFTER_EACH_SCAN = 1
272 REPORT_EVENT_FULL_SCAN_RESULT = 2
273
xshuaabcfeb2018-02-14 11:43:24 -0800274 SCAN_TYPE_LOW_LATENCY = 0
275 SCAN_TYPE_LOW_POWER = 1
276 SCAN_TYPE_HIGH_ACCURACY = 2
277
Ang Li73697b32015-12-03 00:41:53 +0000278 # US Wifi frequencies
Omar El Ayach8c017902020-10-18 10:26:57 -0700279 ALL_2G_FREQUENCIES = [
280 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462
281 ]
282 DFS_5G_FREQUENCIES = [
283 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640,
284 5660, 5680, 5700, 5720
285 ]
286 NONE_DFS_5G_FREQUENCIES = [
287 5180, 5200, 5220, 5240, 5745, 5765, 5785, 5805, 5825
288 ]
Ang Li73697b32015-12-03 00:41:53 +0000289 ALL_5G_FREQUENCIES = DFS_5G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES
290
291 band_to_frequencies = {
Ang Li82522812016-06-02 13:57:21 -0700292 WIFI_BAND_24_GHZ: ALL_2G_FREQUENCIES,
293 WIFI_BAND_5_GHZ: NONE_DFS_5G_FREQUENCIES,
294 WIFI_BAND_5_GHZ_DFS_ONLY: DFS_5G_FREQUENCIES,
295 WIFI_BAND_5_GHZ_WITH_DFS: ALL_5G_FREQUENCIES,
296 WIFI_BAND_BOTH: ALL_2G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES,
297 WIFI_BAND_BOTH_WITH_DFS: ALL_5G_FREQUENCIES + ALL_2G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000298 }
299
300 # All Wifi frequencies to channels lookup.
301 freq_to_channel = {
302 2412: 1,
303 2417: 2,
304 2422: 3,
305 2427: 4,
306 2432: 5,
307 2437: 6,
308 2442: 7,
309 2447: 8,
310 2452: 9,
311 2457: 10,
312 2462: 11,
313 2467: 12,
314 2472: 13,
315 2484: 14,
316 4915: 183,
317 4920: 184,
318 4925: 185,
319 4935: 187,
320 4940: 188,
321 4945: 189,
322 4960: 192,
323 4980: 196,
324 5035: 7,
325 5040: 8,
326 5045: 9,
327 5055: 11,
328 5060: 12,
329 5080: 16,
330 5170: 34,
331 5180: 36,
332 5190: 38,
333 5200: 40,
334 5210: 42,
335 5220: 44,
336 5230: 46,
337 5240: 48,
338 5260: 52,
339 5280: 56,
340 5300: 60,
341 5320: 64,
342 5500: 100,
343 5520: 104,
344 5540: 108,
345 5560: 112,
346 5580: 116,
347 5600: 120,
348 5620: 124,
349 5640: 128,
350 5660: 132,
351 5680: 136,
352 5700: 140,
353 5745: 149,
354 5765: 153,
355 5785: 157,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700356 5795: 159,
Ang Li73697b32015-12-03 00:41:53 +0000357 5805: 161,
358 5825: 165,
359 }
360
361 # All Wifi channels to frequencies lookup.
362 channel_2G_to_freq = {
363 1: 2412,
364 2: 2417,
365 3: 2422,
366 4: 2427,
367 5: 2432,
368 6: 2437,
369 7: 2442,
370 8: 2447,
371 9: 2452,
372 10: 2457,
373 11: 2462,
374 12: 2467,
375 13: 2472,
376 14: 2484
377 }
378
379 channel_5G_to_freq = {
380 183: 4915,
381 184: 4920,
382 185: 4925,
383 187: 4935,
384 188: 4940,
385 189: 4945,
386 192: 4960,
387 196: 4980,
388 7: 5035,
389 8: 5040,
390 9: 5045,
391 11: 5055,
392 12: 5060,
393 16: 5080,
394 34: 5170,
395 36: 5180,
396 38: 5190,
397 40: 5200,
398 42: 5210,
399 44: 5220,
400 46: 5230,
401 48: 5240,
Omar El Ayach8c017902020-10-18 10:26:57 -0700402 50: 5250,
Ang Li73697b32015-12-03 00:41:53 +0000403 52: 5260,
404 56: 5280,
405 60: 5300,
406 64: 5320,
407 100: 5500,
408 104: 5520,
409 108: 5540,
410 112: 5560,
411 116: 5580,
412 120: 5600,
413 124: 5620,
414 128: 5640,
415 132: 5660,
416 136: 5680,
417 140: 5700,
418 149: 5745,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700419 151: 5755,
Ang Li73697b32015-12-03 00:41:53 +0000420 153: 5765,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700421 155: 5775,
Ang Li73697b32015-12-03 00:41:53 +0000422 157: 5785,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700423 159: 5795,
Ang Li73697b32015-12-03 00:41:53 +0000424 161: 5805,
425 165: 5825
426 }
427
Ang Li82522812016-06-02 13:57:21 -0700428
Ang Li73697b32015-12-03 00:41:53 +0000429class WifiChannelBase:
430 ALL_2G_FREQUENCIES = []
431 DFS_5G_FREQUENCIES = []
432 NONE_DFS_5G_FREQUENCIES = []
433 ALL_5G_FREQUENCIES = DFS_5G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES
434 MIX_CHANNEL_SCAN = []
435
436 def band_to_freq(self, band):
437 _band_to_frequencies = {
Omar El Ayach8c017902020-10-18 10:26:57 -0700438 WifiEnums.WIFI_BAND_24_GHZ:
439 self.ALL_2G_FREQUENCIES,
440 WifiEnums.WIFI_BAND_5_GHZ:
441 self.NONE_DFS_5G_FREQUENCIES,
442 WifiEnums.WIFI_BAND_5_GHZ_DFS_ONLY:
443 self.DFS_5G_FREQUENCIES,
444 WifiEnums.WIFI_BAND_5_GHZ_WITH_DFS:
445 self.ALL_5G_FREQUENCIES,
Ang Li82522812016-06-02 13:57:21 -0700446 WifiEnums.WIFI_BAND_BOTH:
447 self.ALL_2G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES,
448 WifiEnums.WIFI_BAND_BOTH_WITH_DFS:
449 self.ALL_5G_FREQUENCIES + self.ALL_2G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000450 }
451 return _band_to_frequencies[band]
452
Ang Li82522812016-06-02 13:57:21 -0700453
Ang Li73697b32015-12-03 00:41:53 +0000454class WifiChannelUS(WifiChannelBase):
455 # US Wifi frequencies
Omar El Ayach8c017902020-10-18 10:26:57 -0700456 ALL_2G_FREQUENCIES = [
457 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462
458 ]
459 NONE_DFS_5G_FREQUENCIES = [
460 5180, 5200, 5220, 5240, 5745, 5765, 5785, 5805, 5825
461 ]
462 MIX_CHANNEL_SCAN = [
463 2412, 2437, 2462, 5180, 5200, 5280, 5260, 5300, 5500, 5320, 5520, 5560,
464 5700, 5745, 5805
465 ]
Ang Li73697b32015-12-03 00:41:53 +0000466
467 def __init__(self, model=None):
Omar El Ayach8c017902020-10-18 10:26:57 -0700468 self.DFS_5G_FREQUENCIES = [
469 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620,
470 5640, 5660, 5680, 5700, 5720
471 ]
Girish Moturu0c567b02017-08-11 16:20:01 -0700472 self.ALL_5G_FREQUENCIES = self.DFS_5G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000473
Bindu Mahadevff295782019-02-08 16:17:48 -0800474
Girish Moturuf02fa1d2017-05-21 09:51:23 +0530475class WifiReferenceNetworks:
476 """ Class to parse and return networks of different band and
477 auth type from reference_networks
478 """
479 def __init__(self, obj):
480 self.reference_networks = obj
481 self.WIFI_2G = "2g"
482 self.WIFI_5G = "5g"
483
484 self.secure_networks_2g = []
485 self.secure_networks_5g = []
486 self.open_networks_2g = []
487 self.open_networks_5g = []
488 self._parse_networks()
489
490 def _parse_networks(self):
491 for network in self.reference_networks:
492 for key in network:
493 if key == self.WIFI_2G:
494 if "password" in network[key]:
495 self.secure_networks_2g.append(network[key])
496 else:
497 self.open_networks_2g.append(network[key])
498 else:
499 if "password" in network[key]:
500 self.secure_networks_5g.append(network[key])
501 else:
502 self.open_networks_5g.append(network[key])
503
504 def return_2g_secure_networks(self):
505 return self.secure_networks_2g
506
507 def return_5g_secure_networks(self):
508 return self.secure_networks_5g
509
510 def return_2g_open_networks(self):
511 return self.open_networks_2g
512
513 def return_5g_open_networks(self):
514 return self.open_networks_5g
515
516 def return_secure_networks(self):
517 return self.secure_networks_2g + self.secure_networks_5g
518
519 def return_open_networks(self):
520 return self.open_networks_2g + self.open_networks_5g
521
Ang Li82522812016-06-02 13:57:21 -0700522
523def _assert_on_fail_handler(func, assert_on_fail, *args, **kwargs):
524 """Wrapper function that handles the bahevior of assert_on_fail.
525
526 When assert_on_fail is True, let all test signals through, which can
527 terminate test cases directly. When assert_on_fail is False, the wrapper
528 raises no test signals and reports operation status by returning True or
529 False.
530
531 Args:
532 func: The function to wrap. This function reports operation status by
533 raising test signals.
534 assert_on_fail: A boolean that specifies if the output of the wrapper
535 is test signal based or return value based.
536 args: Positional args for func.
537 kwargs: Name args for func.
538
539 Returns:
540 If assert_on_fail is True, returns True/False to signal operation
541 status, otherwise return nothing.
542 """
543 try:
544 func(*args, **kwargs)
545 if not assert_on_fail:
546 return True
547 except signals.TestSignal:
548 if assert_on_fail:
549 raise
550 return False
551
552
553def assert_network_in_list(target, network_list):
554 """Makes sure a specified target Wi-Fi network exists in a list of Wi-Fi
555 networks.
556
557 Args:
558 target: A dict representing a Wi-Fi network.
559 E.g. {WifiEnums.SSID_KEY: "SomeNetwork"}
560 network_list: A list of dicts, each representing a Wi-Fi network.
561 """
562 match_results = match_networks(target, network_list)
563 asserts.assert_true(
564 match_results, "Target network %s, does not exist in network list %s" %
565 (target, network_list))
566
567
Ang Li73697b32015-12-03 00:41:53 +0000568def match_networks(target_params, networks):
569 """Finds the WiFi networks that match a given set of parameters in a list
570 of WiFi networks.
571
Girish Moturubc48d9f2016-11-01 13:24:14 -0700572 To be considered a match, the network should contain every key-value pair
573 of target_params
Ang Li73697b32015-12-03 00:41:53 +0000574
575 Args:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700576 target_params: A dict with 1 or more key-value pairs representing a Wi-Fi network.
577 E.g { 'SSID': 'wh_ap1_5g', 'BSSID': '30:b5:c2:33:e4:47' }
Ang Li73697b32015-12-03 00:41:53 +0000578 networks: A list of dict objects representing WiFi networks.
579
580 Returns:
581 The networks that match the target parameters.
582 """
583 results = []
Betty Zhou3caa0982017-02-22 19:26:20 -0800584 asserts.assert_true(target_params,
585 "Expected networks object 'target_params' is empty")
Ang Li73697b32015-12-03 00:41:53 +0000586 for n in networks:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700587 add_network = 1
Ang Li9a66de72016-02-08 15:26:38 -0800588 for k, v in target_params.items():
589 if k not in n:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700590 add_network = 0
591 break
Ang Li9a66de72016-02-08 15:26:38 -0800592 if n[k] != v:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700593 add_network = 0
594 break
595 if add_network:
Ang Li73697b32015-12-03 00:41:53 +0000596 results.append(n)
597 return results
598
Bindu Mahadevff295782019-02-08 16:17:48 -0800599
Roshan Pius93b519c2018-05-09 12:07:11 -0700600def wait_for_wifi_state(ad, state, assert_on_fail=True):
601 """Waits for the device to transition to the specified wifi state
602
603 Args:
604 ad: An AndroidDevice object.
605 state: Wifi state to wait for.
606 assert_on_fail: If True, error checks in this function will raise test
607 failure signals.
608
609 Returns:
610 If assert_on_fail is False, function returns True if the device transitions
611 to the specified state, False otherwise. If assert_on_fail is True, no return value.
612 """
Omar El Ayach8c017902020-10-18 10:26:57 -0700613 return _assert_on_fail_handler(_wait_for_wifi_state,
614 assert_on_fail,
615 ad,
616 state=state)
Roshan Pius93b519c2018-05-09 12:07:11 -0700617
618
619def _wait_for_wifi_state(ad, state):
620 """Toggles the state of wifi.
621
622 TestFailure signals are raised when something goes wrong.
623
624 Args:
625 ad: An AndroidDevice object.
626 state: Wifi state to wait for.
627 """
628 if state == ad.droid.wifiCheckState():
629 # Check if the state is already achieved, so we don't wait for the
630 # state change event by mistake.
631 return
632 ad.droid.wifiStartTrackingStateChange()
Omar El Ayach8c017902020-10-18 10:26:57 -0700633 fail_msg = "Device did not transition to Wi-Fi state to %s on %s." % (
634 state, ad.serial)
Roshan Pius93b519c2018-05-09 12:07:11 -0700635 try:
636 ad.ed.wait_for_event(wifi_constants.WIFI_STATE_CHANGED,
637 lambda x: x["data"]["enabled"] == state,
638 SHORT_TIMEOUT)
639 except Empty:
640 asserts.assert_equal(state, ad.droid.wifiCheckState(), fail_msg)
641 finally:
642 ad.droid.wifiStopTrackingStateChange()
Ang Li82522812016-06-02 13:57:21 -0700643
Bindu Mahadevff295782019-02-08 16:17:48 -0800644
Ang Li82522812016-06-02 13:57:21 -0700645def wifi_toggle_state(ad, new_state=None, assert_on_fail=True):
Ang Li6b557182015-11-11 17:19:17 -0800646 """Toggles the state of wifi.
Ang Li73697b32015-12-03 00:41:53 +0000647
Ang Li6b557182015-11-11 17:19:17 -0800648 Args:
649 ad: An AndroidDevice object.
650 new_state: Wifi state to set to. If None, opposite of the current state.
Ang Li82522812016-06-02 13:57:21 -0700651 assert_on_fail: If True, error checks in this function will raise test
652 failure signals.
Ang Li73697b32015-12-03 00:41:53 +0000653
Ang Li6b557182015-11-11 17:19:17 -0800654 Returns:
Ang Li82522812016-06-02 13:57:21 -0700655 If assert_on_fail is False, function returns True if the toggle was
656 successful, False otherwise. If assert_on_fail is True, no return value.
657 """
Omar El Ayach8c017902020-10-18 10:26:57 -0700658 return _assert_on_fail_handler(_wifi_toggle_state,
659 assert_on_fail,
660 ad,
661 new_state=new_state)
Ang Li82522812016-06-02 13:57:21 -0700662
663
664def _wifi_toggle_state(ad, new_state=None):
665 """Toggles the state of wifi.
666
667 TestFailure signals are raised when something goes wrong.
668
669 Args:
670 ad: An AndroidDevice object.
671 new_state: The state to set Wi-Fi to. If None, opposite of the current
672 state will be set.
Ang Li6b557182015-11-11 17:19:17 -0800673 """
Ang Li31b00782016-06-21 13:04:23 -0700674 if new_state is None:
675 new_state = not ad.droid.wifiCheckState()
Ang Lie5c85c92016-07-27 15:38:09 -0700676 elif new_state == ad.droid.wifiCheckState():
677 # Check if the new_state is already achieved, so we don't wait for the
678 # state change event by mistake.
679 return
680 ad.droid.wifiStartTrackingStateChange()
Ang Li31b00782016-06-21 13:04:23 -0700681 ad.log.info("Setting Wi-Fi state to %s.", new_state)
Roshan Pius5a027fa2018-05-04 13:59:38 -0700682 ad.ed.clear_all_events()
Ang Li31b00782016-06-21 13:04:23 -0700683 # Setting wifi state.
Ang Li6b557182015-11-11 17:19:17 -0800684 ad.droid.wifiToggleState(new_state)
Jaineel3bd9bea2019-12-13 12:44:17 -0800685 time.sleep(2)
Ang Lie2e93a22016-06-22 16:43:28 -0700686 fail_msg = "Failed to set Wi-Fi state to %s on %s." % (new_state,
687 ad.serial)
Ang Li73697b32015-12-03 00:41:53 +0000688 try:
Roshan Pius5a027fa2018-05-04 13:59:38 -0700689 ad.ed.wait_for_event(wifi_constants.WIFI_STATE_CHANGED,
690 lambda x: x["data"]["enabled"] == new_state,
691 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +0000692 except Empty:
Ang Li82522812016-06-02 13:57:21 -0700693 asserts.assert_equal(new_state, ad.droid.wifiCheckState(), fail_msg)
Ang Li6b557182015-11-11 17:19:17 -0800694 finally:
695 ad.droid.wifiStopTrackingStateChange()
696
Ang Li82522812016-06-02 13:57:21 -0700697
Ang Li6b557182015-11-11 17:19:17 -0800698def reset_wifi(ad):
Ang Li1179fa72016-06-16 09:44:06 -0700699 """Clears all saved Wi-Fi networks on a device.
700
701 This will turn Wi-Fi on.
Ang Li6b557182015-11-11 17:19:17 -0800702
703 Args:
704 ad: An AndroidDevice object.
705
Ang Li6b557182015-11-11 17:19:17 -0800706 """
Ang Li6b557182015-11-11 17:19:17 -0800707 networks = ad.droid.wifiGetConfiguredNetworks()
708 if not networks:
709 return
710 for n in networks:
711 ad.droid.wifiForgetNetwork(n['networkId'])
712 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800713 event = ad.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS,
Ang Li82522812016-06-02 13:57:21 -0700714 SHORT_TIMEOUT)
Ang Li6b557182015-11-11 17:19:17 -0800715 except Empty:
Ang Li1179fa72016-06-16 09:44:06 -0700716 logging.warning("Could not confirm the removal of network %s.", n)
717 # Check again to see if there's any network left.
Betty Zhou3caa0982017-02-22 19:26:20 -0800718 asserts.assert_true(
719 not ad.droid.wifiGetConfiguredNetworks(),
720 "Failed to remove these configured Wi-Fi networks: %s" % networks)
Ang Li82522812016-06-02 13:57:21 -0700721
Ang Li73697b32015-12-03 00:41:53 +0000722
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700723def toggle_airplane_mode_on_and_off(ad):
724 """Turn ON and OFF Airplane mode.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800725
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700726 ad: An AndroidDevice object.
727 Returns: Assert if turning on/off Airplane mode fails.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800728
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700729 """
730 ad.log.debug("Toggling Airplane mode ON.")
Omar El Ayach8c017902020-10-18 10:26:57 -0700731 asserts.assert_true(utils.force_airplane_mode(ad, True),
732 "Can not turn on airplane mode on: %s" % ad.serial)
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700733 time.sleep(DEFAULT_TIMEOUT)
734 ad.log.debug("Toggling Airplane mode OFF.")
Omar El Ayach8c017902020-10-18 10:26:57 -0700735 asserts.assert_true(utils.force_airplane_mode(ad, False),
736 "Can not turn on airplane mode on: %s" % ad.serial)
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700737 time.sleep(DEFAULT_TIMEOUT)
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800738
739
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700740def toggle_wifi_off_and_on(ad):
741 """Turn OFF and ON WiFi.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800742
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700743 ad: An AndroidDevice object.
744 Returns: Assert if turning off/on WiFi fails.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800745
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700746 """
747 ad.log.debug("Toggling wifi OFF.")
748 wifi_toggle_state(ad, False)
749 time.sleep(DEFAULT_TIMEOUT)
750 ad.log.debug("Toggling wifi ON.")
751 wifi_toggle_state(ad, True)
752 time.sleep(DEFAULT_TIMEOUT)
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800753
754
Ang Li73697b32015-12-03 00:41:53 +0000755def wifi_forget_network(ad, net_ssid):
Ang Li8e767182015-12-09 17:29:24 -0800756 """Remove configured Wifi network on an android device.
Ang Li73697b32015-12-03 00:41:53 +0000757
Ang Li8e767182015-12-09 17:29:24 -0800758 Args:
759 ad: android_device object for forget network.
760 net_ssid: ssid of network to be forget
Ang Li73697b32015-12-03 00:41:53 +0000761
Ang Li8e767182015-12-09 17:29:24 -0800762 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700763 networks = ad.droid.wifiGetConfiguredNetworks()
Ang Li8e767182015-12-09 17:29:24 -0800764 if not networks:
765 return
766 for n in networks:
767 if net_ssid in n[WifiEnums.SSID_KEY]:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700768 ad.droid.wifiForgetNetwork(n['networkId'])
Ang Li8e767182015-12-09 17:29:24 -0800769 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800770 event = ad.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS,
Betty Zhou3caa0982017-02-22 19:26:20 -0800771 SHORT_TIMEOUT)
Ang Li8e767182015-12-09 17:29:24 -0800772 except Empty:
Girish Moturu1bf82302016-11-01 13:27:00 -0700773 asserts.fail("Failed to remove network %s." % n)
Ang Li73697b32015-12-03 00:41:53 +0000774
Ang Li82522812016-06-02 13:57:21 -0700775
Ang Li73697b32015-12-03 00:41:53 +0000776def wifi_test_device_init(ad):
777 """Initializes an android device for wifi testing.
778
779 0. Make sure SL4A connection is established on the android device.
780 1. Disable location service's WiFi scan.
781 2. Turn WiFi on.
782 3. Clear all saved networks.
783 4. Set country code to US.
784 5. Enable WiFi verbose logging.
785 6. Sync device time with computer time.
786 7. Turn off cellular data.
Ang Lifee28402016-07-13 13:43:29 -0700787 8. Turn off ambient display.
Ang Li73697b32015-12-03 00:41:53 +0000788 """
Ang Lifee28402016-07-13 13:43:29 -0700789 utils.require_sl4a((ad, ))
Ang Li73697b32015-12-03 00:41:53 +0000790 ad.droid.wifiScannerToggleAlwaysAvailable(False)
791 msg = "Failed to turn off location service's scan."
Ang Li82522812016-06-02 13:57:21 -0700792 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
793 wifi_toggle_state(ad, True)
Ang Li6b557182015-11-11 17:19:17 -0800794 reset_wifi(ad)
Ang Li73697b32015-12-03 00:41:53 +0000795 ad.droid.wifiEnableVerboseLogging(1)
Ang Li8e767182015-12-09 17:29:24 -0800796 msg = "Failed to enable WiFi verbose logging."
Ang Li82522812016-06-02 13:57:21 -0700797 asserts.assert_equal(ad.droid.wifiGetVerboseLoggingLevel(), 1, msg)
Ang Li73697b32015-12-03 00:41:53 +0000798 # We don't verify the following settings since they are not critical.
Ang Lie2e93a22016-06-22 16:43:28 -0700799 # Set wpa_supplicant log level to EXCESSIVE.
Omar El Ayach8c017902020-10-18 10:26:57 -0700800 output = ad.adb.shell(
801 "wpa_cli -i wlan0 -p -g@android:wpa_wlan0 IFNAME="
802 "wlan0 log_level EXCESSIVE",
803 ignore_status=True)
Ang Lie2e93a22016-06-22 16:43:28 -0700804 ad.log.info("wpa_supplicant log change status: %s", output)
Ang Lifee28402016-07-13 13:43:29 -0700805 utils.sync_device_time(ad)
Ang Li0bf8e022016-01-04 17:34:48 -0800806 ad.droid.telephonyToggleDataConnection(False)
Roshan Pius48df08c2019-09-13 08:07:30 -0700807 set_wifi_country_code(ad, WifiEnums.CountryCode.US)
Ang Lifee28402016-07-13 13:43:29 -0700808 utils.set_ambient_display(ad, False)
Ang Li73697b32015-12-03 00:41:53 +0000809
Omar El Ayach8c017902020-10-18 10:26:57 -0700810
Roshan Pius48df08c2019-09-13 08:07:30 -0700811def set_wifi_country_code(ad, country_code):
812 """Sets the wifi country code on the device.
813
814 Args:
815 ad: An AndroidDevice object.
816 country_code: 2 letter ISO country code
codycaldwell35b87182020-01-16 14:08:01 -0800817
818 Raises:
819 An RpcException if unable to set the country code.
Roshan Pius48df08c2019-09-13 08:07:30 -0700820 """
Jaineelc5b56a62019-10-10 17:12:02 -0700821 try:
codycaldwell35b87182020-01-16 14:08:01 -0800822 ad.adb.shell("cmd wifi force-country-code enabled %s" % country_code)
Jaineel Mehtacbad5cc2020-11-19 21:38:18 +0000823 except Exception as e:
Jaineelc5b56a62019-10-10 17:12:02 -0700824 ad.droid.wifiSetCountryCode(WifiEnums.CountryCode.US)
Roshan Pius48df08c2019-09-13 08:07:30 -0700825
Ang Li82522812016-06-02 13:57:21 -0700826
Ang Li6b557182015-11-11 17:19:17 -0800827def start_wifi_connection_scan(ad):
Ang Li73697b32015-12-03 00:41:53 +0000828 """Starts a wifi connection scan and wait for results to become available.
829
830 Args:
Ang Li6b557182015-11-11 17:19:17 -0800831 ad: An AndroidDevice object.
Ang Li73697b32015-12-03 00:41:53 +0000832 """
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800833 ad.ed.clear_all_events()
Ang Li6b557182015-11-11 17:19:17 -0800834 ad.droid.wifiStartScan()
Ang Li82522812016-06-02 13:57:21 -0700835 try:
836 ad.ed.pop_event("WifiManagerScanResultsAvailable", 60)
837 except Empty:
838 asserts.fail("Wi-Fi results did not become available within 60s.")
839
Ang Li73697b32015-12-03 00:41:53 +0000840
Roshan Piuscb9bc482018-02-01 14:27:09 -0800841def start_wifi_connection_scan_and_return_status(ad):
842 """
843 Starts a wifi connection scan and wait for results to become available
844 or a scan failure to be reported.
845
846 Args:
847 ad: An AndroidDevice object.
848 Returns:
849 True: if scan succeeded & results are available
850 False: if scan failed
851 """
852 ad.ed.clear_all_events()
853 ad.droid.wifiStartScan()
854 try:
Omar El Ayach8c017902020-10-18 10:26:57 -0700855 events = ad.ed.pop_events("WifiManagerScan(ResultsAvailable|Failure)",
856 60)
Roshan Piuscb9bc482018-02-01 14:27:09 -0800857 except Empty:
858 asserts.fail(
859 "Wi-Fi scan results/failure did not become available within 60s.")
860 # If there are multiple matches, we check for atleast one success.
861 for event in events:
862 if event["name"] == "WifiManagerScanResultsAvailable":
863 return True
864 elif event["name"] == "WifiManagerScanFailure":
865 ad.log.debug("Scan failure received")
866 return False
867
868
Omar El Ayach8c017902020-10-18 10:26:57 -0700869def start_wifi_connection_scan_and_check_for_network(ad,
870 network_ssid,
Roshan Piuscb9bc482018-02-01 14:27:09 -0800871 max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800872 """
873 Start connectivity scans & checks if the |network_ssid| is seen in
874 scan results. The method performs a max of |max_tries| connectivity scans
875 to find the network.
876
877 Args:
878 ad: An AndroidDevice object.
879 network_ssid: SSID of the network we are looking for.
880 max_tries: Number of scans to try.
881 Returns:
882 True: if network_ssid is found in scan results.
883 False: if network_ssid is not found in scan results.
884 """
885 for num_tries in range(max_tries):
Roshan Piuscb9bc482018-02-01 14:27:09 -0800886 if start_wifi_connection_scan_and_return_status(ad):
887 scan_results = ad.droid.wifiGetScanResults()
Omar El Ayach8c017902020-10-18 10:26:57 -0700888 match_results = match_networks({WifiEnums.SSID_KEY: network_ssid},
889 scan_results)
Roshan Piuscb9bc482018-02-01 14:27:09 -0800890 if len(match_results) > 0:
891 return True
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800892 return False
893
894
Omar El Ayach8c017902020-10-18 10:26:57 -0700895def start_wifi_connection_scan_and_ensure_network_found(
896 ad, network_ssid, max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800897 """
898 Start connectivity scans & ensure the |network_ssid| is seen in
899 scan results. The method performs a max of |max_tries| connectivity scans
900 to find the network.
901 This method asserts on failure!
902
903 Args:
904 ad: An AndroidDevice object.
905 network_ssid: SSID of the network we are looking for.
906 max_tries: Number of scans to try.
907 """
908 ad.log.info("Starting scans to ensure %s is present", network_ssid)
909 assert_msg = "Failed to find " + network_ssid + " in scan results" \
910 " after " + str(max_tries) + " tries"
Omar El Ayach8c017902020-10-18 10:26:57 -0700911 asserts.assert_true(
912 start_wifi_connection_scan_and_check_for_network(
913 ad, network_ssid, max_tries), assert_msg)
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800914
915
Omar El Ayach8c017902020-10-18 10:26:57 -0700916def start_wifi_connection_scan_and_ensure_network_not_found(
917 ad, network_ssid, max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800918 """
919 Start connectivity scans & ensure the |network_ssid| is not seen in
920 scan results. The method performs a max of |max_tries| connectivity scans
921 to find the network.
922 This method asserts on failure!
923
924 Args:
925 ad: An AndroidDevice object.
926 network_ssid: SSID of the network we are looking for.
927 max_tries: Number of scans to try.
928 """
929 ad.log.info("Starting scans to ensure %s is not present", network_ssid)
930 assert_msg = "Found " + network_ssid + " in scan results" \
931 " after " + str(max_tries) + " tries"
Omar El Ayach8c017902020-10-18 10:26:57 -0700932 asserts.assert_false(
933 start_wifi_connection_scan_and_check_for_network(
934 ad, network_ssid, max_tries), assert_msg)
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800935
936
Ang Li73697b32015-12-03 00:41:53 +0000937def start_wifi_background_scan(ad, scan_setting):
938 """Starts wifi background scan.
939
940 Args:
941 ad: android_device object to initiate connection on.
942 scan_setting: A dict representing the settings of the scan.
943
944 Returns:
945 If scan was started successfully, event data of success event is returned.
946 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700947 idx = ad.droid.wifiScannerStartBackgroundScan(scan_setting)
948 event = ad.ed.pop_event("WifiScannerScan{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -0800949 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +0000950 return event['data']
951
Ang Li82522812016-06-02 13:57:21 -0700952
Roshan Piusce821342018-01-10 11:03:04 -0800953def start_wifi_tethering(ad, ssid, password, band=None, hidden=None):
Ang Li73697b32015-12-03 00:41:53 +0000954 """Starts wifi tethering on an android_device.
955
956 Args:
957 ad: android_device to start wifi tethering on.
958 ssid: The SSID the soft AP should broadcast.
959 password: The password the soft AP should use.
960 band: The band the soft AP should be set on. It should be either
961 WifiEnums.WIFI_CONFIG_APBAND_2G or WifiEnums.WIFI_CONFIG_APBAND_5G.
Roshan Piusce821342018-01-10 11:03:04 -0800962 hidden: boolean to indicate if the AP needs to be hidden or not.
Ang Li73697b32015-12-03 00:41:53 +0000963
964 Returns:
Girish Moturu3581d612016-11-02 15:08:51 -0700965 No return value. Error checks in this function will raise test failure signals
Ang Li73697b32015-12-03 00:41:53 +0000966 """
Ang Li82522812016-06-02 13:57:21 -0700967 config = {WifiEnums.SSID_KEY: ssid}
Ang Li73697b32015-12-03 00:41:53 +0000968 if password:
969 config[WifiEnums.PWD_KEY] = password
970 if band:
lesl6d30a172020-03-05 15:05:22 +0800971 config[WifiEnums.AP_BAND_KEY] = band
Roshan Piusce821342018-01-10 11:03:04 -0800972 if hidden:
Omar El Ayach8c017902020-10-18 10:26:57 -0700973 config[WifiEnums.HIDDEN_KEY] = hidden
974 asserts.assert_true(ad.droid.wifiSetWifiApConfiguration(config),
975 "Failed to update WifiAp Configuration")
Girish Moturu40d7dc22016-11-02 12:14:56 -0700976 ad.droid.wifiStartTrackingTetherStateChange()
977 ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
Rebecca Silbersteina2889852016-08-11 00:48:53 -0700978 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700979 ad.ed.pop_event("ConnectivityManagerOnTetheringStarted")
980 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -0800981 lambda x: x["data"]["ACTIVE_TETHER"], 30)
Ang Li76216d12016-09-20 14:51:57 -0700982 ad.log.debug("Tethering started successfully.")
Rebecca Silbersteina2889852016-08-11 00:48:53 -0700983 except Empty:
984 msg = "Failed to receive confirmation of wifi tethering starting"
985 asserts.fail(msg)
986 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700987 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li73697b32015-12-03 00:41:53 +0000988
Bindu Mahadevff295782019-02-08 16:17:48 -0800989
Omar El Ayach8c017902020-10-18 10:26:57 -0700990def save_wifi_soft_ap_config(ad,
991 wifi_config,
992 band=None,
993 hidden=None,
994 security=None,
995 password=None,
996 channel=None,
997 max_clients=None,
lesl6d30a172020-03-05 15:05:22 +0800998 shutdown_timeout_enable=None,
999 shutdown_timeout_millis=None,
1000 client_control_enable=None,
Omar El Ayach8c017902020-10-18 10:26:57 -07001001 allowedList=None,
1002 blockedList=None):
lesl6d30a172020-03-05 15:05:22 +08001003 """ Save a soft ap configuration and verified
1004 Args:
1005 ad: android_device to set soft ap configuration.
1006 wifi_config: a soft ap configuration object, at least include SSID.
1007 band: specifies the band for the soft ap.
1008 hidden: specifies the soft ap need to broadcast its SSID or not.
1009 security: specifies the security type for the soft ap.
1010 password: specifies the password for the soft ap.
1011 channel: specifies the channel for the soft ap.
1012 max_clients: specifies the maximum connected client number.
1013 shutdown_timeout_enable: specifies the auto shut down enable or not.
1014 shutdown_timeout_millis: specifies the shut down timeout value.
1015 client_control_enable: specifies the client control enable or not.
1016 allowedList: specifies allowed clients list.
1017 blockedList: specifies blocked clients list.
1018 """
1019 if security and password:
Omar El Ayach8c017902020-10-18 10:26:57 -07001020 wifi_config[WifiEnums.SECURITY] = security
1021 wifi_config[WifiEnums.PWD_KEY] = password
Girish Moturu528b5442018-06-07 10:48:14 -07001022 if band:
lesl6d30a172020-03-05 15:05:22 +08001023 wifi_config[WifiEnums.AP_BAND_KEY] = band
Girish Moturu528b5442018-06-07 10:48:14 -07001024 if hidden:
1025 wifi_config[WifiEnums.HIDDEN_KEY] = hidden
lesl6d30a172020-03-05 15:05:22 +08001026 if channel and band:
1027 wifi_config[WifiEnums.AP_BAND_KEY] = band
1028 wifi_config[WifiEnums.AP_CHANNEL_KEY] = channel
1029 if max_clients:
1030 wifi_config[WifiEnums.AP_MAXCLIENTS_KEY] = max_clients
1031 if shutdown_timeout_enable:
1032 wifi_config[
1033 WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] = shutdown_timeout_enable
1034 if shutdown_timeout_millis:
Omar El Ayach8c017902020-10-18 10:26:57 -07001035 wifi_config[WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] = shutdown_timeout_millis
lesl6d30a172020-03-05 15:05:22 +08001036 if client_control_enable:
1037 wifi_config[WifiEnums.AP_CLIENTCONTROL_KEY] = client_control_enable
1038 if allowedList:
1039 wifi_config[WifiEnums.AP_ALLOWEDLIST_KEY] = allowedList
1040 if blockedList:
1041 wifi_config[WifiEnums.AP_BLOCKEDLIST_KEY] = blockedList
1042
1043 if WifiEnums.AP_CHANNEL_KEY in wifi_config and wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001044 WifiEnums.AP_CHANNEL_KEY] == 0:
lesl6d30a172020-03-05 15:05:22 +08001045 del wifi_config[WifiEnums.AP_CHANNEL_KEY]
1046
1047 if WifiEnums.SECURITY in wifi_config and wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001048 WifiEnums.SECURITY] == WifiEnums.SoftApSecurityType.OPEN:
lesl6d30a172020-03-05 15:05:22 +08001049 del wifi_config[WifiEnums.SECURITY]
1050 del wifi_config[WifiEnums.PWD_KEY]
1051
Girish Moturu528b5442018-06-07 10:48:14 -07001052 asserts.assert_true(ad.droid.wifiSetWifiApConfiguration(wifi_config),
1053 "Failed to set WifiAp Configuration")
1054
1055 wifi_ap = ad.droid.wifiGetApConfiguration()
1056 asserts.assert_true(
1057 wifi_ap[WifiEnums.SSID_KEY] == wifi_config[WifiEnums.SSID_KEY],
lesl6d30a172020-03-05 15:05:22 +08001058 "Hotspot SSID doesn't match")
1059 if WifiEnums.SECURITY in wifi_config:
1060 asserts.assert_true(
1061 wifi_ap[WifiEnums.SECURITY] == wifi_config[WifiEnums.SECURITY],
1062 "Hotspot Security doesn't match")
1063 if WifiEnums.PWD_KEY in wifi_config:
1064 asserts.assert_true(
1065 wifi_ap[WifiEnums.PWD_KEY] == wifi_config[WifiEnums.PWD_KEY],
1066 "Hotspot Password doesn't match")
Girish Moturu528b5442018-06-07 10:48:14 -07001067
lesl6d30a172020-03-05 15:05:22 +08001068 if WifiEnums.HIDDEN_KEY in wifi_config:
1069 asserts.assert_true(
1070 wifi_ap[WifiEnums.HIDDEN_KEY] == wifi_config[WifiEnums.HIDDEN_KEY],
1071 "Hotspot hidden setting doesn't match")
1072
1073 if WifiEnums.AP_BAND_KEY in wifi_config:
1074 asserts.assert_true(
Omar El Ayach8c017902020-10-18 10:26:57 -07001075 wifi_ap[WifiEnums.AP_BAND_KEY] == wifi_config[
1076 WifiEnums.AP_BAND_KEY], "Hotspot Band doesn't match")
lesl6d30a172020-03-05 15:05:22 +08001077 if WifiEnums.AP_CHANNEL_KEY in wifi_config:
1078 asserts.assert_true(
1079 wifi_ap[WifiEnums.AP_CHANNEL_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001080 WifiEnums.AP_CHANNEL_KEY], "Hotspot Channel doesn't match")
lesl6d30a172020-03-05 15:05:22 +08001081 if WifiEnums.AP_MAXCLIENTS_KEY in wifi_config:
1082 asserts.assert_true(
1083 wifi_ap[WifiEnums.AP_MAXCLIENTS_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001084 WifiEnums.AP_MAXCLIENTS_KEY],
1085 "Hotspot Max Clients doesn't match")
lesl6d30a172020-03-05 15:05:22 +08001086 if WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY in wifi_config:
1087 asserts.assert_true(
1088 wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001089 WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY],
lesl6d30a172020-03-05 15:05:22 +08001090 "Hotspot ShutDown feature flag doesn't match")
1091 if WifiEnums.AP_SHUTDOWNTIMEOUT_KEY in wifi_config:
1092 asserts.assert_true(
1093 wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001094 WifiEnums.AP_SHUTDOWNTIMEOUT_KEY],
lesl6d30a172020-03-05 15:05:22 +08001095 "Hotspot ShutDown timeout setting doesn't match")
1096 if WifiEnums.AP_CLIENTCONTROL_KEY in wifi_config:
1097 asserts.assert_true(
1098 wifi_ap[WifiEnums.AP_CLIENTCONTROL_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001099 WifiEnums.AP_CLIENTCONTROL_KEY],
lesl6d30a172020-03-05 15:05:22 +08001100 "Hotspot Client control flag doesn't match")
1101 if WifiEnums.AP_ALLOWEDLIST_KEY in wifi_config:
1102 asserts.assert_true(
1103 wifi_ap[WifiEnums.AP_ALLOWEDLIST_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001104 WifiEnums.AP_ALLOWEDLIST_KEY],
lesl6d30a172020-03-05 15:05:22 +08001105 "Hotspot Allowed List doesn't match")
1106 if WifiEnums.AP_BLOCKEDLIST_KEY in wifi_config:
1107 asserts.assert_true(
1108 wifi_ap[WifiEnums.AP_BLOCKEDLIST_KEY] == wifi_config[
Omar El Ayach8c017902020-10-18 10:26:57 -07001109 WifiEnums.AP_BLOCKEDLIST_KEY],
lesl6d30a172020-03-05 15:05:22 +08001110 "Hotspot Blocked List doesn't match")
Bindu Mahadevff295782019-02-08 16:17:48 -08001111
Omar El Ayach8c017902020-10-18 10:26:57 -07001112
Girish Moturu528b5442018-06-07 10:48:14 -07001113def start_wifi_tethering_saved_config(ad):
1114 """ Turn on wifi hotspot with a config that is already saved """
1115 ad.droid.wifiStartTrackingTetherStateChange()
1116 ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
1117 try:
1118 ad.ed.pop_event("ConnectivityManagerOnTetheringStarted")
1119 ad.ed.wait_for_event("TetherStateChanged",
1120 lambda x: x["data"]["ACTIVE_TETHER"], 30)
1121 except:
1122 asserts.fail("Didn't receive wifi tethering starting confirmation")
1123 finally:
1124 ad.droid.wifiStopTrackingTetherStateChange()
Betty Zhou3caa0982017-02-22 19:26:20 -08001125
Bindu Mahadevff295782019-02-08 16:17:48 -08001126
Ang Li73697b32015-12-03 00:41:53 +00001127def stop_wifi_tethering(ad):
1128 """Stops wifi tethering on an android_device.
Ang Li73697b32015-12-03 00:41:53 +00001129 Args:
1130 ad: android_device to stop wifi tethering on.
1131 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001132 ad.droid.wifiStartTrackingTetherStateChange()
1133 ad.droid.connectivityStopTethering(tel_defines.TETHERING_WIFI)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001134 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001135 ad.ed.pop_event("WifiManagerApDisabled", 30)
1136 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -08001137 lambda x: not x["data"]["ACTIVE_TETHER"], 30)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001138 except Empty:
1139 msg = "Failed to receive confirmation of wifi tethering stopping"
1140 asserts.fail(msg)
1141 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001142 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li82522812016-06-02 13:57:21 -07001143
Ang Li76216d12016-09-20 14:51:57 -07001144
Roshan Pius58916a32016-06-16 16:26:44 -07001145def toggle_wifi_and_wait_for_reconnection(ad,
1146 network,
1147 num_of_tries=1,
1148 assert_on_fail=True):
1149 """Toggle wifi state and then wait for Android device to reconnect to
1150 the provided wifi network.
1151
1152 This expects the device to be already connected to the provided network.
1153
1154 Logic steps are
1155 1. Ensure that we're connected to the network.
1156 2. Turn wifi off.
1157 3. Wait for 10 seconds.
1158 4. Turn wifi on.
1159 5. Wait for the "connected" event, then confirm the connected ssid is the
1160 one requested.
1161
1162 Args:
1163 ad: android_device object to initiate connection on.
1164 network: A dictionary representing the network to await connection. The
1165 dictionary must have the key "SSID".
1166 num_of_tries: An integer that is the number of times to try before
1167 delaring failure. Default is 1.
1168 assert_on_fail: If True, error checks in this function will raise test
1169 failure signals.
1170
1171 Returns:
1172 If assert_on_fail is False, function returns True if the toggle was
1173 successful, False otherwise. If assert_on_fail is True, no return value.
1174 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001175 return _assert_on_fail_handler(_toggle_wifi_and_wait_for_reconnection,
1176 assert_on_fail,
1177 ad,
1178 network,
1179 num_of_tries=num_of_tries)
Roshan Pius58916a32016-06-16 16:26:44 -07001180
1181
Girish Moturu5d9f4202019-12-03 15:29:21 -08001182def _toggle_wifi_and_wait_for_reconnection(ad, network, num_of_tries=3):
Roshan Pius58916a32016-06-16 16:26:44 -07001183 """Toggle wifi state and then wait for Android device to reconnect to
1184 the provided wifi network.
1185
1186 This expects the device to be already connected to the provided network.
1187
1188 Logic steps are
1189 1. Ensure that we're connected to the network.
1190 2. Turn wifi off.
1191 3. Wait for 10 seconds.
1192 4. Turn wifi on.
1193 5. Wait for the "connected" event, then confirm the connected ssid is the
1194 one requested.
1195
1196 This will directly fail a test if anything goes wrong.
1197
1198 Args:
1199 ad: android_device object to initiate connection on.
1200 network: A dictionary representing the network to await connection. The
1201 dictionary must have the key "SSID".
1202 num_of_tries: An integer that is the number of times to try before
1203 delaring failure. Default is 1.
1204 """
Roshan Pius58916a32016-06-16 16:26:44 -07001205 expected_ssid = network[WifiEnums.SSID_KEY]
1206 # First ensure that we're already connected to the provided network.
1207 verify_con = {WifiEnums.SSID_KEY: expected_ssid}
1208 verify_wifi_connection_info(ad, verify_con)
1209 # Now toggle wifi state and wait for the connection event.
1210 wifi_toggle_state(ad, False)
1211 time.sleep(10)
1212 wifi_toggle_state(ad, True)
1213 ad.droid.wifiStartTrackingStateChange()
1214 try:
1215 connect_result = None
1216 for i in range(num_of_tries):
1217 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -08001218 connect_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
Roshan Pius58916a32016-06-16 16:26:44 -07001219 30)
1220 break
1221 except Empty:
1222 pass
Omar El Ayach8c017902020-10-18 10:26:57 -07001223 asserts.assert_true(
1224 connect_result, "Failed to connect to Wi-Fi network %s on %s" %
1225 (network, ad.serial))
Betty Zhou3caa0982017-02-22 19:26:20 -08001226 logging.debug("Connection result on %s: %s.", ad.serial,
1227 connect_result)
Roshan Pius58916a32016-06-16 16:26:44 -07001228 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001229 asserts.assert_equal(
1230 actual_ssid, expected_ssid, "Connected to the wrong network on %s."
1231 "Expected %s, but got %s." %
1232 (ad.serial, expected_ssid, actual_ssid))
Betty Zhou3caa0982017-02-22 19:26:20 -08001233 logging.info("Connected to Wi-Fi network %s on %s", actual_ssid,
1234 ad.serial)
Roshan Pius58916a32016-06-16 16:26:44 -07001235 finally:
1236 ad.droid.wifiStopTrackingStateChange()
1237
1238
Omar El Ayach8c017902020-10-18 10:26:57 -07001239def wait_for_connect(ad,
1240 expected_ssid=None,
1241 expected_id=None,
1242 tries=2,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001243 assert_on_fail=True):
Roshan Piusd1204442018-11-12 12:20:39 -08001244 """Wait for a connect event.
1245
1246 This will directly fail a test if anything goes wrong.
1247
1248 Args:
1249 ad: An Android device object.
1250 expected_ssid: SSID of the network to connect to.
1251 expected_id: Network Id of the network to connect to.
1252 tries: An integer that is the number of times to try before failing.
1253 assert_on_fail: If True, error checks in this function will raise test
1254 failure signals.
1255
1256 Returns:
1257 Returns a value only if assert_on_fail is false.
1258 Returns True if the connection was successful, False otherwise.
1259 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001260 return _assert_on_fail_handler(_wait_for_connect, assert_on_fail, ad,
1261 expected_ssid, expected_id, tries)
Roshan Piusd1204442018-11-12 12:20:39 -08001262
1263
Oscar Shucb9af9b2019-05-02 20:01:49 +00001264def _wait_for_connect(ad, expected_ssid=None, expected_id=None, tries=2):
Roshan Piusd1204442018-11-12 12:20:39 -08001265 """Wait for a connect event.
1266
1267 Args:
1268 ad: An Android device object.
1269 expected_ssid: SSID of the network to connect to.
1270 expected_id: Network Id of the network to connect to.
1271 tries: An integer that is the number of times to try before failing.
1272 """
1273 ad.droid.wifiStartTrackingStateChange()
1274 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001275 connect_result = _wait_for_connect_event(ad,
1276 ssid=expected_ssid,
1277 id=expected_id,
1278 tries=tries)
1279 asserts.assert_true(
1280 connect_result,
1281 "Failed to connect to Wi-Fi network %s" % expected_ssid)
Roshan Piusd1204442018-11-12 12:20:39 -08001282 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
1283 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1284 if expected_ssid:
1285 asserts.assert_equal(actual_ssid, expected_ssid,
1286 "Connected to the wrong network")
1287 actual_id = connect_result['data'][WifiEnums.NETID_KEY]
1288 if expected_id:
1289 asserts.assert_equal(actual_id, expected_id,
1290 "Connected to the wrong network")
1291 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
1292 except Empty:
1293 asserts.fail("Failed to start connection process to %s" %
1294 expected_ssid)
1295 except Exception as error:
1296 ad.log.error("Failed to connect to %s with error %s", expected_ssid,
1297 error)
1298 raise signals.TestFailure("Failed to connect to %s network" %
1299 expected_ssid)
1300 finally:
1301 ad.droid.wifiStopTrackingStateChange()
1302
1303
Oscar Shucb9af9b2019-05-02 20:01:49 +00001304def _wait_for_connect_event(ad, ssid=None, id=None, tries=1):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001305 """Wait for a connect event on queue and pop when available.
1306
1307 Args:
1308 ad: An Android device object.
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001309 ssid: SSID of the network to connect to.
1310 id: Network Id of the network to connect to.
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001311 tries: An integer that is the number of times to try before failing.
1312
1313 Returns:
1314 A dict with details of the connection data, which looks like this:
1315 {
1316 'time': 1485460337798,
1317 'name': 'WifiNetworkConnected',
1318 'data': {
1319 'rssi': -27,
1320 'is_24ghz': True,
1321 'mac_address': '02:00:00:00:00:00',
1322 'network_id': 1,
1323 'BSSID': '30:b5:c2:33:d3:fc',
1324 'ip_address': 117483712,
1325 'link_speed': 54,
1326 'supplicant_state': 'completed',
1327 'hidden_ssid': False,
1328 'SSID': 'wh_ap1_2g',
1329 'is_5ghz': False}
1330 }
1331
1332 """
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001333 conn_result = None
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001334
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001335 # If ssid and network id is None, just wait for any connect event.
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001336 if id is None and ssid is None:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001337 for i in range(tries):
1338 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001339 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
1340 30)
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001341 break
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001342 except Empty:
1343 pass
1344 else:
Omar El Ayach8c017902020-10-18 10:26:57 -07001345 # If ssid or network id is specified, wait for specific connect event.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001346 for i in range(tries):
1347 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001348 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
1349 30)
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001350 if id and conn_result['data'][WifiEnums.NETID_KEY] == id:
1351 break
1352 elif ssid and conn_result['data'][WifiEnums.SSID_KEY] == ssid:
1353 break
1354 except Empty:
1355 pass
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001356
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001357 return conn_result
1358
Bindu Mahadevff295782019-02-08 16:17:48 -08001359
Roshan Piusffc29912019-01-18 13:39:49 -08001360def wait_for_disconnect(ad, timeout=10):
1361 """Wait for a disconnect event within the specified timeout.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001362
1363 Args:
1364 ad: Android device object.
Roshan Piusffc29912019-01-18 13:39:49 -08001365 timeout: Timeout in seconds.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001366
1367 """
1368 try:
1369 ad.droid.wifiStartTrackingStateChange()
Roshan Piusffc29912019-01-18 13:39:49 -08001370 event = ad.ed.pop_event("WifiNetworkDisconnected", timeout)
Roshan Piusbf7e3982018-02-15 12:37:41 -08001371 except Empty:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001372 raise signals.TestFailure("Device did not disconnect from the network")
Roshan Piusffc29912019-01-18 13:39:49 -08001373 finally:
1374 ad.droid.wifiStopTrackingStateChange()
1375
1376
1377def ensure_no_disconnect(ad, duration=10):
1378 """Ensure that there is no disconnect for the specified duration.
1379
1380 Args:
1381 ad: Android device object.
1382 duration: Duration in seconds.
1383
1384 """
1385 try:
1386 ad.droid.wifiStartTrackingStateChange()
1387 event = ad.ed.pop_event("WifiNetworkDisconnected", duration)
1388 raise signals.TestFailure("Device disconnected from the network")
1389 except Empty:
1390 pass
1391 finally:
1392 ad.droid.wifiStopTrackingStateChange()
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001393
1394
Omar El Ayach8c017902020-10-18 10:26:57 -07001395def connect_to_wifi_network(ad,
1396 network,
1397 assert_on_fail=True,
1398 check_connectivity=True,
1399 hidden=False):
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001400 """Connection logic for open and psk wifi networks.
1401
1402 Args:
Jong Wook Kim92356922018-02-06 18:32:49 -08001403 ad: AndroidDevice to use for connection
1404 network: network info of the network to connect to
1405 assert_on_fail: If true, errors from wifi_connect will raise
1406 test failure signals.
Joe Brennan48c3f692019-04-11 08:30:16 -07001407 hidden: Is the Wifi network hidden.
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001408 """
Joe Brennan48c3f692019-04-11 08:30:16 -07001409 if hidden:
1410 start_wifi_connection_scan_and_ensure_network_not_found(
1411 ad, network[WifiEnums.SSID_KEY])
1412 else:
1413 start_wifi_connection_scan_and_ensure_network_found(
1414 ad, network[WifiEnums.SSID_KEY])
Jong Wook Kim92356922018-02-06 18:32:49 -08001415 wifi_connect(ad,
1416 network,
1417 num_of_tries=3,
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001418 assert_on_fail=assert_on_fail,
1419 check_connectivity=check_connectivity)
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001420
1421
1422def connect_to_wifi_network_with_id(ad, network_id, network_ssid):
1423 """Connect to the given network using network id and verify SSID.
1424
1425 Args:
1426 network_id: int Network Id of the network.
1427 network_ssid: string SSID of the network.
1428
1429 Returns: True if connect using network id was successful;
1430 False otherwise.
1431
1432 """
Jong Wook Kim92356922018-02-06 18:32:49 -08001433 start_wifi_connection_scan_and_ensure_network_found(ad, network_ssid)
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001434 wifi_connect_by_id(ad, network_id)
1435 connect_data = ad.droid.wifiGetConnectionInfo()
1436 connect_ssid = connect_data[WifiEnums.SSID_KEY]
1437 ad.log.debug("Expected SSID = %s Connected SSID = %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001438 (network_ssid, connect_ssid))
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001439 if connect_ssid != network_ssid:
1440 return False
1441 return True
1442
1443
Omar El Ayach8c017902020-10-18 10:26:57 -07001444def wifi_connect(ad,
1445 network,
1446 num_of_tries=1,
1447 assert_on_fail=True,
1448 check_connectivity=True):
Ang Li99d8c6d2015-12-09 15:56:13 -08001449 """Connect an Android device to a wifi network.
Ang Li73697b32015-12-03 00:41:53 +00001450
1451 Initiate connection to a wifi network, wait for the "connected" event, then
Ang Li99d8c6d2015-12-09 15:56:13 -08001452 confirm the connected ssid is the one requested.
Ang Li73697b32015-12-03 00:41:53 +00001453
Ang Li82522812016-06-02 13:57:21 -07001454 This will directly fail a test if anything goes wrong.
1455
Ang Li73697b32015-12-03 00:41:53 +00001456 Args:
1457 ad: android_device object to initiate connection on.
Ang Li99d8c6d2015-12-09 15:56:13 -08001458 network: A dictionary representing the network to connect to. The
Ang Li82522812016-06-02 13:57:21 -07001459 dictionary must have the key "SSID".
1460 num_of_tries: An integer that is the number of times to try before
1461 delaring failure. Default is 1.
1462 assert_on_fail: If True, error checks in this function will raise test
1463 failure signals.
1464
1465 Returns:
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001466 Returns a value only if assert_on_fail is false.
1467 Returns True if the connection was successful, False otherwise.
Ang Li73697b32015-12-03 00:41:53 +00001468 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001469 return _assert_on_fail_handler(_wifi_connect,
1470 assert_on_fail,
1471 ad,
1472 network,
1473 num_of_tries=num_of_tries,
1474 check_connectivity=check_connectivity)
Ang Li82522812016-06-02 13:57:21 -07001475
1476
Oscar Shucb9af9b2019-05-02 20:01:49 +00001477def _wifi_connect(ad, network, num_of_tries=1, check_connectivity=True):
Ang Li82522812016-06-02 13:57:21 -07001478 """Connect an Android device to a wifi network.
1479
1480 Initiate connection to a wifi network, wait for the "connected" event, then
1481 confirm the connected ssid is the one requested.
1482
1483 This will directly fail a test if anything goes wrong.
1484
1485 Args:
1486 ad: android_device object to initiate connection on.
1487 network: A dictionary representing the network to connect to. The
1488 dictionary must have the key "SSID".
1489 num_of_tries: An integer that is the number of times to try before
1490 delaring failure. Default is 1.
1491 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001492 asserts.assert_true(
1493 WifiEnums.SSID_KEY in network,
1494 "Key '%s' must be present in network definition." % WifiEnums.SSID_KEY)
Ang Li99d8c6d2015-12-09 15:56:13 -08001495 ad.droid.wifiStartTrackingStateChange()
Betty Zhoud35dab82016-12-06 15:24:23 -08001496 expected_ssid = network[WifiEnums.SSID_KEY]
Bindu Mahadev50374df2017-01-04 11:03:32 -08001497 ad.droid.wifiConnectByConfig(network)
1498 ad.log.info("Starting connection process to %s", expected_ssid)
Ang Li73697b32015-12-03 00:41:53 +00001499 try:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001500 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_CONFIG_SUCCESS, 30)
Omar El Ayach8c017902020-10-18 10:26:57 -07001501 connect_result = _wait_for_connect_event(ad,
1502 ssid=expected_ssid,
1503 tries=num_of_tries)
1504 asserts.assert_true(
1505 connect_result, "Failed to connect to Wi-Fi network %s on %s" %
1506 (network, ad.serial))
Ang Li31b00782016-06-21 13:04:23 -07001507 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
Ang Li99d8c6d2015-12-09 15:56:13 -08001508 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001509 asserts.assert_equal(
1510 actual_ssid, expected_ssid,
1511 "Connected to the wrong network on %s." % ad.serial)
Ang Li31b00782016-06-21 13:04:23 -07001512 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
Bindu Mahadev50374df2017-01-04 11:03:32 -08001513
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001514 if check_connectivity:
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08001515 internet = validate_connection(ad, DEFAULT_PING_ADDR)
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001516 if not internet:
Omar El Ayach8c017902020-10-18 10:26:57 -07001517 raise signals.TestFailure(
1518 "Failed to connect to internet on %s" % expected_ssid)
Bindu Mahadev50374df2017-01-04 11:03:32 -08001519 except Empty:
1520 asserts.fail("Failed to start connection process to %s on %s" %
1521 (network, ad.serial))
Bindu Mahadev4e710362016-11-17 16:17:11 -08001522 except Exception as error:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001523 ad.log.error("Failed to connect to %s with error %s", expected_ssid,
1524 error)
1525 raise signals.TestFailure("Failed to connect to %s network" % network)
1526
Ang Li73697b32015-12-03 00:41:53 +00001527 finally:
Ang Li99d8c6d2015-12-09 15:56:13 -08001528 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001529
Bindu Mahadev50374df2017-01-04 11:03:32 -08001530
Oscar Shucb9af9b2019-05-02 20:01:49 +00001531def wifi_connect_by_id(ad, network_id, num_of_tries=3, assert_on_fail=True):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001532 """Connect an Android device to a wifi network using network Id.
1533
1534 Start connection to the wifi network, with the given network Id, wait for
1535 the "connected" event, then verify the connected network is the one requested.
1536
1537 This will directly fail a test if anything goes wrong.
1538
1539 Args:
1540 ad: android_device object to initiate connection on.
1541 network_id: Integer specifying the network id of the network.
1542 num_of_tries: An integer that is the number of times to try before
1543 delaring failure. Default is 1.
1544 assert_on_fail: If True, error checks in this function will raise test
1545 failure signals.
1546
1547 Returns:
1548 Returns a value only if assert_on_fail is false.
1549 Returns True if the connection was successful, False otherwise.
1550 """
1551 _assert_on_fail_handler(_wifi_connect_by_id, assert_on_fail, ad,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001552 network_id, num_of_tries)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001553
1554
Oscar Shucb9af9b2019-05-02 20:01:49 +00001555def _wifi_connect_by_id(ad, network_id, num_of_tries=1):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001556 """Connect an Android device to a wifi network using it's network id.
1557
1558 Start connection to the wifi network, with the given network id, wait for
1559 the "connected" event, then verify the connected network is the one requested.
1560
1561 Args:
1562 ad: android_device object to initiate connection on.
1563 network_id: Integer specifying the network id of the network.
1564 num_of_tries: An integer that is the number of times to try before
1565 delaring failure. Default is 1.
1566 """
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001567 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001568 # Clear all previous events.
1569 ad.ed.clear_all_events()
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001570 ad.droid.wifiConnectByNetworkId(network_id)
1571 ad.log.info("Starting connection to network with id %d", network_id)
1572 try:
1573 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_NETID_SUCCESS, 60)
Omar El Ayach8c017902020-10-18 10:26:57 -07001574 connect_result = _wait_for_connect_event(ad,
1575 id=network_id,
1576 tries=num_of_tries)
1577 asserts.assert_true(
1578 connect_result,
1579 "Failed to connect to Wi-Fi network using network id")
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001580 ad.log.debug("Wi-Fi connection result: %s", connect_result)
1581 actual_id = connect_result['data'][WifiEnums.NETID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001582 asserts.assert_equal(
1583 actual_id, network_id, "Connected to the wrong network on %s."
1584 "Expected network id = %d, but got %d." %
1585 (ad.serial, network_id, actual_id))
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001586 expected_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1587 ad.log.info("Connected to Wi-Fi network %s with %d network id.",
Omar El Ayach8c017902020-10-18 10:26:57 -07001588 expected_ssid, network_id)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001589
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001590 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1591 if not internet:
1592 raise signals.TestFailure("Failed to connect to internet on %s" %
1593 expected_ssid)
1594 except Empty:
1595 asserts.fail("Failed to connect to network with id %d on %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001596 (network_id, ad.serial))
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001597 except Exception as error:
1598 ad.log.error("Failed to connect to network with id %d with error %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07001599 network_id, error)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001600 raise signals.TestFailure("Failed to connect to network with network"
1601 " id %d" % network_id)
1602 finally:
1603 ad.droid.wifiStopTrackingStateChange()
1604
Oscar Shu0b5ff4d2019-08-07 18:11:56 +00001605
Omar El Ayach8c017902020-10-18 10:26:57 -07001606def wifi_connect_using_network_request(ad,
1607 network,
1608 network_specifier,
Roshan Pius5561d232021-01-22 16:34:39 -08001609 num_of_tries=3):
Roshan Piusc999e5e2018-11-09 10:59:52 -08001610 """Connect an Android device to a wifi network using network request.
1611
1612 Trigger a network request with the provided network specifier,
1613 wait for the "onMatch" event, ensure that the scan results in "onMatch"
1614 event contain the specified network, then simulate the user granting the
1615 request with the specified network selected. Then wait for the "onAvailable"
1616 network callback indicating successful connection to network.
1617
1618 Args:
1619 ad: android_device object to initiate connection on.
1620 network_specifier: A dictionary representing the network specifier to
1621 use.
1622 network: A dictionary representing the network to connect to. The
1623 dictionary must have the key "SSID".
1624 num_of_tries: An integer that is the number of times to try before
1625 delaring failure.
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001626 Returns:
1627 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001628 """
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001629 key = ad.droid.connectivityRequestWifiNetwork(network_specifier, 0)
1630 ad.log.info("Sent network request %s with %s " % (key, network_specifier))
Roshan Piusc999e5e2018-11-09 10:59:52 -08001631 # Need a delay here because UI interaction should only start once wifi
1632 # starts processing the request.
1633 time.sleep(wifi_constants.NETWORK_REQUEST_CB_REGISTER_DELAY_SEC)
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001634 _wait_for_wifi_connect_after_network_request(ad, network, key, num_of_tries)
1635 return key
Roshan Piusc999e5e2018-11-09 10:59:52 -08001636
1637
Omar El Ayach8c017902020-10-18 10:26:57 -07001638def wait_for_wifi_connect_after_network_request(ad,
1639 network,
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001640 key,
Omar El Ayach8c017902020-10-18 10:26:57 -07001641 num_of_tries=3,
Roshan Piusc999e5e2018-11-09 10:59:52 -08001642 assert_on_fail=True):
1643 """
1644 Simulate and verify the connection flow after initiating the network
1645 request.
1646
1647 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1648 event contain the specified network, then simulate the user granting the
1649 request with the specified network selected. Then wait for the "onAvailable"
1650 network callback indicating successful connection to network.
1651
1652 Args:
1653 ad: android_device object to initiate connection on.
1654 network: A dictionary representing the network to connect to. The
1655 dictionary must have the key "SSID".
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001656 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001657 num_of_tries: An integer that is the number of times to try before
1658 delaring failure.
1659 assert_on_fail: If True, error checks in this function will raise test
1660 failure signals.
1661
1662 Returns:
1663 Returns a value only if assert_on_fail is false.
1664 Returns True if the connection was successful, False otherwise.
1665 """
1666 _assert_on_fail_handler(_wait_for_wifi_connect_after_network_request,
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001667 assert_on_fail, ad, network, key, num_of_tries)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001668
1669
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001670def _wait_for_wifi_connect_after_network_request(ad, network, key, num_of_tries=3):
Roshan Piusc999e5e2018-11-09 10:59:52 -08001671 """
1672 Simulate and verify the connection flow after initiating the network
1673 request.
1674
1675 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1676 event contain the specified network, then simulate the user granting the
1677 request with the specified network selected. Then wait for the "onAvailable"
1678 network callback indicating successful connection to network.
1679
1680 Args:
1681 ad: android_device object to initiate connection on.
1682 network: A dictionary representing the network to connect to. The
1683 dictionary must have the key "SSID".
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001684 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001685 num_of_tries: An integer that is the number of times to try before
1686 delaring failure.
1687 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001688 asserts.assert_true(
1689 WifiEnums.SSID_KEY in network,
1690 "Key '%s' must be present in network definition." % WifiEnums.SSID_KEY)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001691 ad.droid.wifiStartTrackingStateChange()
1692 expected_ssid = network[WifiEnums.SSID_KEY]
1693 ad.droid.wifiRegisterNetworkRequestMatchCallback()
1694 # Wait for the platform to scan and return a list of networks
1695 # matching the request
1696 try:
1697 matched_network = None
Omar El Ayach8c017902020-10-18 10:26:57 -07001698 for _ in [0, num_of_tries]:
Roshan Piusc999e5e2018-11-09 10:59:52 -08001699 on_match_event = ad.ed.pop_event(
1700 wifi_constants.WIFI_NETWORK_REQUEST_MATCH_CB_ON_MATCH, 60)
1701 asserts.assert_true(on_match_event,
1702 "Network request on match not received.")
1703 matched_scan_results = on_match_event["data"]
1704 ad.log.debug("Network request on match results %s",
1705 matched_scan_results)
1706 matched_network = match_networks(
1707 {WifiEnums.SSID_KEY: network[WifiEnums.SSID_KEY]},
1708 matched_scan_results)
Roshan Pius6cd4aaf2021-02-09 15:54:30 -08001709 ad.log.debug("Network request on match %s", matched_network)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001710 if matched_network:
Omar El Ayach8c017902020-10-18 10:26:57 -07001711 break
Roshan Piusc999e5e2018-11-09 10:59:52 -08001712
Omar El Ayach8c017902020-10-18 10:26:57 -07001713 asserts.assert_true(matched_network,
1714 "Target network %s not found" % network)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001715
1716 ad.droid.wifiSendUserSelectionForNetworkRequestMatch(network)
1717 ad.log.info("Sent user selection for network request %s",
1718 expected_ssid)
1719
1720 # Wait for the platform to connect to the network.
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001721 autils.wait_for_event_with_keys(
1722 ad, cconsts.EVENT_NETWORK_CALLBACK,
1723 60,
1724 (cconsts.NETWORK_CB_KEY_ID, key),
1725 (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_AVAILABLE))
1726 on_capabilities_changed = autils.wait_for_event_with_keys(
1727 ad, cconsts.EVENT_NETWORK_CALLBACK,
1728 10,
1729 (cconsts.NETWORK_CB_KEY_ID, key),
1730 (cconsts.NETWORK_CB_KEY_EVENT,
1731 cconsts.NETWORK_CB_CAPABILITIES_CHANGED))
1732 connected_network =\
1733 on_capabilities_changed["data"][cconsts.NETWORK_CB_KEY_TRANSPORT_INFO]
Roshan Piusc999e5e2018-11-09 10:59:52 -08001734 ad.log.info("Connected to network %s", connected_network)
Omar El Ayach8c017902020-10-18 10:26:57 -07001735 asserts.assert_equal(
1736 connected_network[WifiEnums.SSID_KEY], expected_ssid,
1737 "Connected to the wrong network."
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001738 "Expected %s, but got %s."
1739 % (network, connected_network))
Roshan Piusc999e5e2018-11-09 10:59:52 -08001740 except Empty:
1741 asserts.fail("Failed to connect to %s" % expected_ssid)
1742 except Exception as error:
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001743 ad.log.error("Failed to connect to %s with error %s" %
Roshan Piusc999e5e2018-11-09 10:59:52 -08001744 (expected_ssid, error))
1745 raise signals.TestFailure("Failed to connect to %s network" % network)
1746 finally:
1747 ad.droid.wifiStopTrackingStateChange()
1748
1749
Omar El Ayach8c017902020-10-18 10:26:57 -07001750def wifi_passpoint_connect(ad,
1751 passpoint_network,
1752 num_of_tries=1,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001753 assert_on_fail=True):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001754 """Connect an Android device to a wifi network.
1755
1756 Initiate connection to a wifi network, wait for the "connected" event, then
1757 confirm the connected ssid is the one requested.
1758
1759 This will directly fail a test if anything goes wrong.
1760
1761 Args:
1762 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001763 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001764 num_of_tries: An integer that is the number of times to try before
1765 delaring failure. Default is 1.
1766 assert_on_fail: If True, error checks in this function will raise test
1767 failure signals.
1768
1769 Returns:
1770 If assert_on_fail is False, function returns network id, if the connect was
1771 successful, False otherwise. If assert_on_fail is True, no return value.
1772 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001773 _assert_on_fail_handler(_wifi_passpoint_connect,
1774 assert_on_fail,
1775 ad,
1776 passpoint_network,
1777 num_of_tries=num_of_tries)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001778
1779
Oscar Shucb9af9b2019-05-02 20:01:49 +00001780def _wifi_passpoint_connect(ad, passpoint_network, num_of_tries=1):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001781 """Connect an Android device to a wifi network.
1782
1783 Initiate connection to a wifi network, wait for the "connected" event, then
1784 confirm the connected ssid is the one requested.
1785
1786 This will directly fail a test if anything goes wrong.
1787
1788 Args:
1789 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001790 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001791 num_of_tries: An integer that is the number of times to try before
1792 delaring failure. Default is 1.
1793 """
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001794 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001795 expected_ssid = passpoint_network
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001796 ad.log.info("Starting connection process to passpoint %s", expected_ssid)
1797
1798 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001799 connect_result = _wait_for_connect_event(ad, expected_ssid,
1800 num_of_tries)
1801 asserts.assert_true(
1802 connect_result, "Failed to connect to WiFi passpoint network %s on"
1803 " %s" % (expected_ssid, ad.serial))
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001804 ad.log.info("Wi-Fi connection result: %s.", connect_result)
1805 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001806 asserts.assert_equal(
1807 actual_ssid, expected_ssid,
1808 "Connected to the wrong network on %s." % ad.serial)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001809 ad.log.info("Connected to Wi-Fi passpoint network %s.", actual_ssid)
1810
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001811 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1812 if not internet:
1813 raise signals.TestFailure("Failed to connect to internet on %s" %
1814 expected_ssid)
1815 except Exception as error:
1816 ad.log.error("Failed to connect to passpoint network %s with error %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07001817 expected_ssid, error)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001818 raise signals.TestFailure("Failed to connect to %s passpoint network" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001819 expected_ssid)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001820
1821 finally:
1822 ad.droid.wifiStopTrackingStateChange()
1823
1824
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001825def delete_passpoint(ad, fqdn):
1826 """Delete a required Passpoint configuration."""
1827 try:
1828 ad.droid.removePasspointConfig(fqdn)
1829 return True
1830 except Exception as error:
Omar El Ayach8c017902020-10-18 10:26:57 -07001831 ad.log.error(
1832 "Failed to remove passpoint configuration with FQDN=%s "
1833 "and error=%s", fqdn, error)
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001834 return False
1835
1836
Ang Li73697b32015-12-03 00:41:53 +00001837def start_wifi_single_scan(ad, scan_setting):
1838 """Starts wifi single shot scan.
1839
1840 Args:
1841 ad: android_device object to initiate connection on.
1842 scan_setting: A dict representing the settings of the scan.
1843
1844 Returns:
1845 If scan was started successfully, event data of success event is returned.
1846 """
Ang Li82522812016-06-02 13:57:21 -07001847 idx = ad.droid.wifiScannerStartScan(scan_setting)
1848 event = ad.ed.pop_event("WifiScannerScan%sonSuccess" % idx, SHORT_TIMEOUT)
Ang Li31b00782016-06-21 13:04:23 -07001849 ad.log.debug("Got event %s", event)
Ang Li73697b32015-12-03 00:41:53 +00001850 return event['data']
1851
Ang Li82522812016-06-02 13:57:21 -07001852
Ang Li73697b32015-12-03 00:41:53 +00001853def track_connection(ad, network_ssid, check_connection_count):
1854 """Track wifi connection to network changes for given number of counts
1855
1856 Args:
1857 ad: android_device object for forget network.
1858 network_ssid: network ssid to which connection would be tracked
1859 check_connection_count: Integer for maximum number network connection
Ang Li82522812016-06-02 13:57:21 -07001860 check.
Ang Li73697b32015-12-03 00:41:53 +00001861 Returns:
Ang Li73697b32015-12-03 00:41:53 +00001862 True if connection to given network happen, else return False.
1863 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001864 ad.droid.wifiStartTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001865 while check_connection_count > 0:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001866 connect_network = ad.ed.pop_event("WifiNetworkConnected", 120)
Ang Li31b00782016-06-21 13:04:23 -07001867 ad.log.info("Connected to network %s", connect_network)
Ang Li82522812016-06-02 13:57:21 -07001868 if (WifiEnums.SSID_KEY in connect_network['data'] and
1869 connect_network['data'][WifiEnums.SSID_KEY] == network_ssid):
1870 return True
Ang Li8e767182015-12-09 17:29:24 -08001871 check_connection_count -= 1
Girish Moturu40d7dc22016-11-02 12:14:56 -07001872 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001873 return False
1874
Ang Li82522812016-06-02 13:57:21 -07001875
Ang Li73697b32015-12-03 00:41:53 +00001876def get_scan_time_and_channels(wifi_chs, scan_setting, stime_channel):
1877 """Calculate the scan time required based on the band or channels in scan
1878 setting
1879
1880 Args:
1881 wifi_chs: Object of channels supported
1882 scan_setting: scan setting used for start scan
1883 stime_channel: scan time per channel
1884
1885 Returns:
1886 scan_time: time required for completing a scan
1887 scan_channels: channel used for scanning
1888 """
1889 scan_time = 0
1890 scan_channels = []
1891 if "band" in scan_setting and "channels" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001892 scan_channels = wifi_chs.band_to_freq(scan_setting["band"])
Ang Li73697b32015-12-03 00:41:53 +00001893 elif "channels" in scan_setting and "band" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001894 scan_channels = scan_setting["channels"]
Ang Li73697b32015-12-03 00:41:53 +00001895 scan_time = len(scan_channels) * stime_channel
1896 for channel in scan_channels:
Ang Li8e767182015-12-09 17:29:24 -08001897 if channel in WifiEnums.DFS_5G_FREQUENCIES:
Ang Li82522812016-06-02 13:57:21 -07001898 scan_time += 132 #passive scan time on DFS
Ang Li73697b32015-12-03 00:41:53 +00001899 return scan_time, scan_channels
1900
Ang Li82522812016-06-02 13:57:21 -07001901
Ang Li73697b32015-12-03 00:41:53 +00001902def start_wifi_track_bssid(ad, track_setting):
1903 """Start tracking Bssid for the given settings.
1904
1905 Args:
1906 ad: android_device object.
1907 track_setting: Setting for which the bssid tracking should be started
1908
1909 Returns:
1910 If tracking started successfully, event data of success event is returned.
1911 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001912 idx = ad.droid.wifiScannerStartTrackingBssids(
Ang Li82522812016-06-02 13:57:21 -07001913 track_setting["bssidInfos"], track_setting["apLostThreshold"])
Girish Moturu40d7dc22016-11-02 12:14:56 -07001914 event = ad.ed.pop_event("WifiScannerBssid{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -08001915 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +00001916 return event['data']
1917
Ang Li82522812016-06-02 13:57:21 -07001918
Ang Li73697b32015-12-03 00:41:53 +00001919def convert_pem_key_to_pkcs8(in_file, out_file):
1920 """Converts the key file generated by us to the format required by
1921 Android using openssl.
1922
1923 The input file must have the extension "pem". The output file must
1924 have the extension "der".
1925
1926 Args:
1927 in_file: The original key file.
1928 out_file: The full path to the converted key file, including
1929 filename.
1930 """
Ang Li82522812016-06-02 13:57:21 -07001931 asserts.assert_true(in_file.endswith(".pem"), "Input file has to be .pem.")
Omar El Ayach8c017902020-10-18 10:26:57 -07001932 asserts.assert_true(out_file.endswith(".der"),
1933 "Output file has to be .der.")
Ang Li73697b32015-12-03 00:41:53 +00001934 cmd = ("openssl pkcs8 -inform PEM -in {} -outform DER -out {} -nocrypt"
1935 " -topk8").format(in_file, out_file)
Ang Lifee28402016-07-13 13:43:29 -07001936 utils.exe_cmd(cmd)
Ang Li73697b32015-12-03 00:41:53 +00001937
Ang Li82522812016-06-02 13:57:21 -07001938
Omar El Ayach8c017902020-10-18 10:26:57 -07001939def validate_connection(ad,
1940 ping_addr=DEFAULT_PING_ADDR,
1941 wait_time=15,
Girish Moturu804a3492020-02-17 14:32:02 -08001942 ping_gateway=True):
Ang Li73697b32015-12-03 00:41:53 +00001943 """Validate internet connection by pinging the address provided.
1944
1945 Args:
1946 ad: android_device object.
1947 ping_addr: address on internet for pinging.
Girish Moturua2a5bf22019-08-16 09:52:29 -07001948 wait_time: wait for some time before validating connection
Ang Li73697b32015-12-03 00:41:53 +00001949
1950 Returns:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001951 ping output if successful, NULL otherwise.
Ang Li73697b32015-12-03 00:41:53 +00001952 """
Girish Moturua2a5bf22019-08-16 09:52:29 -07001953 # wait_time to allow for DHCP to complete.
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08001954 for i in range(wait_time):
Girish Moturuacf35002020-11-09 23:37:35 -08001955 if ad.droid.connectivityNetworkIsConnected(
Omar El Ayach8c017902020-10-18 10:26:57 -07001956 ) and ad.droid.connectivityGetIPv4DefaultGateway():
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08001957 break
1958 time.sleep(1)
Girish Moturu804a3492020-02-17 14:32:02 -08001959 ping = False
1960 try:
1961 ping = ad.droid.httpPing(ping_addr)
1962 ad.log.info("Http ping result: %s.", ping)
1963 except:
1964 pass
1965 if not ping and ping_gateway:
1966 ad.log.info("Http ping failed. Pinging default gateway")
1967 gw = ad.droid.connectivityGetIPv4DefaultGateway()
1968 result = ad.adb.shell("ping -c 6 {}".format(gw))
1969 ad.log.info("Default gateway ping result: %s" % result)
1970 ping = False if "100% packet loss" in result else True
Ang Li73697b32015-12-03 00:41:53 +00001971 return ping
1972
Ang Li82522812016-06-02 13:57:21 -07001973
Ang Li73697b32015-12-03 00:41:53 +00001974#TODO(angli): This can only verify if an actual value is exactly the same.
1975# Would be nice to be able to verify an actual value is one of serveral.
1976def verify_wifi_connection_info(ad, expected_con):
1977 """Verifies that the information of the currently connected wifi network is
1978 as expected.
1979
1980 Args:
1981 expected_con: A dict representing expected key-value pairs for wifi
1982 connection. e.g. {"SSID": "test_wifi"}
1983 """
1984 current_con = ad.droid.wifiGetConnectionInfo()
Ang Li374d7602016-02-08 17:27:27 -08001985 case_insensitive = ["BSSID", "supplicant_state"]
Ang Li31b00782016-06-21 13:04:23 -07001986 ad.log.debug("Current connection: %s", current_con)
Ang Li73697b32015-12-03 00:41:53 +00001987 for k, expected_v in expected_con.items():
Ang Li9a66de72016-02-08 15:26:38 -08001988 # Do not verify authentication related fields.
1989 if k == "password":
1990 continue
Ang Li82522812016-06-02 13:57:21 -07001991 msg = "Field %s does not exist in wifi connection info %s." % (
1992 k, current_con)
Ang Li374d7602016-02-08 17:27:27 -08001993 if k not in current_con:
1994 raise signals.TestFailure(msg)
1995 actual_v = current_con[k]
1996 if k in case_insensitive:
1997 actual_v = actual_v.lower()
1998 expected_v = expected_v.lower()
Ang Li73697b32015-12-03 00:41:53 +00001999 msg = "Expected %s to be %s, actual %s is %s." % (k, expected_v, k,
Ang Li82522812016-06-02 13:57:21 -07002000 actual_v)
Ang Li374d7602016-02-08 17:27:27 -08002001 if actual_v != expected_v:
2002 raise signals.TestFailure(msg)
Ang Li73697b32015-12-03 00:41:53 +00002003
Ang Li82522812016-06-02 13:57:21 -07002004
Omar El Ayach8c017902020-10-18 10:26:57 -07002005def check_autoconnect_to_open_network(
2006 ad, conn_timeout=WIFI_CONNECTION_TIMEOUT_DEFAULT):
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08002007 """Connects to any open WiFI AP
2008 Args:
2009 timeout value in sec to wait for UE to connect to a WiFi AP
2010 Returns:
2011 True if UE connects to WiFi AP (supplicant_state = completed)
2012 False if UE fails to complete connection within WIFI_CONNECTION_TIMEOUT time.
2013 """
2014 if ad.droid.wifiCheckState():
2015 return True
2016 ad.droid.wifiToggleState()
2017 wifi_connection_state = None
2018 timeout = time.time() + conn_timeout
2019 while wifi_connection_state != "completed":
Omar El Ayach8c017902020-10-18 10:26:57 -07002020 wifi_connection_state = ad.droid.wifiGetConnectionInfo(
2021 )['supplicant_state']
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08002022 if time.time() > timeout:
2023 ad.log.warning("Failed to connect to WiFi AP")
2024 return False
2025 return True
2026
2027
Ang Li73697b32015-12-03 00:41:53 +00002028def expand_enterprise_config_by_phase2(config):
2029 """Take an enterprise config and generate a list of configs, each with
2030 a different phase2 auth type.
2031
2032 Args:
2033 config: A dict representing enterprise config.
2034
2035 Returns
2036 A list of enterprise configs.
2037 """
2038 results = []
Ang Li0e7e58f2016-02-22 12:15:02 -08002039 phase2_types = WifiEnums.EapPhase2
2040 if config[WifiEnums.Enterprise.EAP] == WifiEnums.Eap.PEAP:
2041 # Skip unsupported phase2 types for PEAP.
2042 phase2_types = [WifiEnums.EapPhase2.GTC, WifiEnums.EapPhase2.MSCHAPV2]
2043 for phase2_type in phase2_types:
Ang Li73697b32015-12-03 00:41:53 +00002044 # Skip a special case for passpoint TTLS.
Omar El Ayach8c017902020-10-18 10:26:57 -07002045 if (WifiEnums.Enterprise.FQDN in config
2046 and phase2_type == WifiEnums.EapPhase2.GTC):
Ang Li73697b32015-12-03 00:41:53 +00002047 continue
2048 c = dict(config)
Girish Moturu150d32f2017-02-14 12:27:07 -08002049 c[WifiEnums.Enterprise.PHASE2] = phase2_type.value
Ang Li73697b32015-12-03 00:41:53 +00002050 results.append(c)
2051 return results
Ang Li2d3fe982016-06-08 10:00:43 -07002052
2053
Girish Moturub48a13c2017-02-27 11:36:42 -08002054def generate_eap_test_name(config, ad=None):
Girish Moturu150d32f2017-02-14 12:27:07 -08002055 """ Generates a test case name based on an EAP configuration.
2056
2057 Args:
2058 config: A dict representing an EAP credential.
Girish Moturub48a13c2017-02-27 11:36:42 -08002059 ad object: Redundant but required as the same param is passed
2060 to test_func in run_generated_tests
Girish Moturu150d32f2017-02-14 12:27:07 -08002061
2062 Returns:
2063 A string representing the name of a generated EAP test case.
2064 """
2065 eap = WifiEnums.Eap
2066 eap_phase2 = WifiEnums.EapPhase2
Girish Moturub48a13c2017-02-27 11:36:42 -08002067 Ent = WifiEnums.Enterprise
Girish Moturu150d32f2017-02-14 12:27:07 -08002068 name = "test_connect-"
2069 eap_name = ""
2070 for e in eap:
2071 if e.value == config[Ent.EAP]:
2072 eap_name = e.name
2073 break
2074 if "peap0" in config[WifiEnums.SSID_KEY].lower():
2075 eap_name = "PEAP0"
2076 if "peap1" in config[WifiEnums.SSID_KEY].lower():
2077 eap_name = "PEAP1"
2078 name += eap_name
2079 if Ent.PHASE2 in config:
2080 for e in eap_phase2:
2081 if e.value == config[Ent.PHASE2]:
2082 name += "-{}".format(e.name)
2083 break
2084 return name
2085
2086
Ang Li2d3fe982016-06-08 10:00:43 -07002087def group_attenuators(attenuators):
2088 """Groups a list of attenuators into attenuator groups for backward
2089 compatibility reasons.
2090
2091 Most legacy Wi-Fi setups have two attenuators each connected to a separate
2092 AP. The new Wi-Fi setup has four attenuators, each connected to one channel
2093 on an AP, so two of them are connected to one AP.
2094
2095 To make the existing scripts work in the new setup, when the script needs
2096 to attenuate one AP, it needs to set attenuation on both attenuators
2097 connected to the same AP.
2098
2099 This function groups attenuators properly so the scripts work in both
2100 legacy and new Wi-Fi setups.
2101
2102 Args:
2103 attenuators: A list of attenuator objects, either two or four in length.
2104
2105 Raises:
2106 signals.TestFailure is raised if the attenuator list does not have two
2107 or four objects.
2108 """
2109 attn0 = attenuator.AttenuatorGroup("AP0")
2110 attn1 = attenuator.AttenuatorGroup("AP1")
2111 # Legacy testbed setup has two attenuation channels.
2112 num_of_attns = len(attenuators)
2113 if num_of_attns == 2:
2114 attn0.add(attenuators[0])
2115 attn1.add(attenuators[1])
2116 elif num_of_attns == 4:
2117 attn0.add(attenuators[0])
2118 attn0.add(attenuators[1])
2119 attn1.add(attenuators[2])
2120 attn1.add(attenuators[3])
2121 else:
2122 asserts.fail(("Either two or four attenuators are required for this "
2123 "test, but found %s") % num_of_attns)
2124 return [attn0, attn1]
Jong Wook Kim92356922018-02-06 18:32:49 -08002125
Bindu Mahadevff295782019-02-08 16:17:48 -08002126
Girish Moturu36348a32019-12-10 08:41:54 -08002127def set_attns(attenuator, attn_val_name, roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002128 """Sets attenuation values on attenuators used in this test.
2129
2130 Args:
2131 attenuator: The attenuator object.
2132 attn_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002133 roaming_attn: Dictionary specifying the attenuation params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002134 """
2135 logging.info("Set attenuation values to %s", roaming_attn[attn_val_name])
2136 try:
2137 attenuator[0].set_atten(roaming_attn[attn_val_name][0])
2138 attenuator[1].set_atten(roaming_attn[attn_val_name][1])
2139 attenuator[2].set_atten(roaming_attn[attn_val_name][2])
2140 attenuator[3].set_atten(roaming_attn[attn_val_name][3])
2141 except:
2142 logging.exception("Failed to set attenuation values %s.",
Omar El Ayach8c017902020-10-18 10:26:57 -07002143 attn_val_name)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002144 raise
2145
Omar El Ayach8c017902020-10-18 10:26:57 -07002146
Girish Moturu36348a32019-12-10 08:41:54 -08002147def set_attns_steps(attenuators,
2148 atten_val_name,
2149 roaming_attn=ROAMING_ATTN,
2150 steps=10,
2151 wait_time=12):
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002152 """Set attenuation values on attenuators used in this test. It will change
2153 the attenuation values linearly from current value to target value step by
2154 step.
2155
2156 Args:
2157 attenuators: The list of attenuator objects that you want to change
2158 their attenuation value.
2159 atten_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002160 roaming_attn: Dictionary specifying the attenuation params.
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002161 steps: Number of attenuator changes to reach the target value.
2162 wait_time: Sleep time for each change of attenuator.
2163 """
2164 logging.info("Set attenuation values to %s in %d step(s)",
Omar El Ayach8c017902020-10-18 10:26:57 -07002165 roaming_attn[atten_val_name], steps)
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002166 start_atten = [attenuator.get_atten() for attenuator in attenuators]
2167 target_atten = roaming_attn[atten_val_name]
2168 for current_step in range(steps):
2169 progress = (current_step + 1) / steps
2170 for i, attenuator in enumerate(attenuators):
2171 amount_since_start = (target_atten[i] - start_atten[i]) * progress
2172 attenuator.set_atten(round(start_atten[i] + amount_since_start))
2173 time.sleep(wait_time)
2174
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002175
Girish Moturu36348a32019-12-10 08:41:54 -08002176def trigger_roaming_and_validate(dut,
2177 attenuator,
2178 attn_val_name,
2179 expected_con,
2180 roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002181 """Sets attenuators to trigger roaming and validate the DUT connected
2182 to the BSSID expected.
2183
2184 Args:
2185 attenuator: The attenuator object.
2186 attn_val_name: Name of the attenuation value pair to use.
2187 expected_con: The network information of the expected network.
Girish Moturu36348a32019-12-10 08:41:54 -08002188 roaming_attn: Dictionary specifying the attenaution params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002189 """
2190 expected_con = {
2191 WifiEnums.SSID_KEY: expected_con[WifiEnums.SSID_KEY],
2192 WifiEnums.BSSID_KEY: expected_con["bssid"],
2193 }
Girish Moturu36348a32019-12-10 08:41:54 -08002194 set_attns_steps(attenuator, attn_val_name, roaming_attn)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002195
Hsiu-Chang Chenef856402018-09-18 12:32:49 +08002196 verify_wifi_connection_info(dut, expected_con)
2197 expected_bssid = expected_con[WifiEnums.BSSID_KEY]
2198 logging.info("Roamed to %s successfully", expected_bssid)
2199 if not validate_connection(dut):
2200 raise signals.TestFailure("Fail to connect to internet on %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07002201 expected_bssid)
2202
Jong Wook Kim92356922018-02-06 18:32:49 -08002203
2204def create_softap_config():
2205 """Create a softap config with random ssid and password."""
2206 ap_ssid = "softap_" + utils.rand_ascii_str(8)
2207 ap_password = utils.rand_ascii_str(8)
2208 logging.info("softap setup: %s %s", ap_ssid, ap_password)
2209 config = {
2210 WifiEnums.SSID_KEY: ap_ssid,
2211 WifiEnums.PWD_KEY: ap_password,
2212 }
2213 return config
Girish Moturucf4dccd2018-08-27 12:22:00 -07002214
Omar El Ayach8c017902020-10-18 10:26:57 -07002215
Bindu Mahadevff295782019-02-08 16:17:48 -08002216def start_softap_and_verify(ad, band):
2217 """Bring-up softap and verify AP mode and in scan results.
2218
2219 Args:
2220 band: The band to use for softAP.
2221
2222 Returns: dict, the softAP config.
2223
2224 """
lesl2f0fb232019-11-05 16:35:28 +08002225 # Register before start the test.
2226 callbackId = ad.dut.droid.registerSoftApCallback()
2227 # Check softap info value is default
2228 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2229 asserts.assert_true(frequency == 0, "Softap frequency is not reset")
2230 asserts.assert_true(bandwdith == 0, "Softap bandwdith is not reset")
2231
Bindu Mahadevff295782019-02-08 16:17:48 -08002232 config = create_softap_config()
2233 start_wifi_tethering(ad.dut,
2234 config[WifiEnums.SSID_KEY],
Omar El Ayach8c017902020-10-18 10:26:57 -07002235 config[WifiEnums.PWD_KEY],
2236 band=band)
Bindu Mahadevff295782019-02-08 16:17:48 -08002237 asserts.assert_true(ad.dut.droid.wifiIsApEnabled(),
Omar El Ayach8c017902020-10-18 10:26:57 -07002238 "SoftAp is not reported as running")
2239 start_wifi_connection_scan_and_ensure_network_found(
2240 ad.dut_client, config[WifiEnums.SSID_KEY])
lesl2f0fb232019-11-05 16:35:28 +08002241
2242 # Check softap info can get from callback succeed and assert value should be
2243 # valid.
2244 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2245 asserts.assert_true(frequency > 0, "Softap frequency is not valid")
2246 asserts.assert_true(bandwdith > 0, "Softap bandwdith is not valid")
2247 # Unregister callback
2248 ad.dut.droid.unregisterSoftApCallback(callbackId)
2249
Bindu Mahadevff295782019-02-08 16:17:48 -08002250 return config
2251
Omar El Ayach8c017902020-10-18 10:26:57 -07002252
lesle8e3c0a2019-02-22 17:06:04 +08002253def wait_for_expected_number_of_softap_clients(ad, callbackId,
Omar El Ayach8c017902020-10-18 10:26:57 -07002254 expected_num_of_softap_clients):
lesle8e3c0a2019-02-22 17:06:04 +08002255 """Wait for the number of softap clients to be updated as expected.
2256 Args:
2257 callbackId: Id of the callback associated with registering.
2258 expected_num_of_softap_clients: expected number of softap clients.
2259 """
2260 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002261 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
James Mattis5a5dd492020-05-14 13:09:43 -07002262 clientData = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data']
2263 clientCount = clientData[wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07002264 clientMacAddresses = clientData[
2265 wifi_constants.SOFTAP_CLIENTS_MACS_CALLBACK_KEY]
2266 asserts.assert_equal(
2267 clientCount, expected_num_of_softap_clients,
2268 "The number of softap clients doesn't match the expected number")
2269 asserts.assert_equal(
2270 len(clientMacAddresses), expected_num_of_softap_clients,
2271 "The number of mac addresses doesn't match the expected number")
James Mattis5a5dd492020-05-14 13:09:43 -07002272 for macAddress in clientMacAddresses:
Omar El Ayach8c017902020-10-18 10:26:57 -07002273 asserts.assert_true(checkMacAddress(macAddress),
2274 "An invalid mac address was returned")
2275
James Mattis5a5dd492020-05-14 13:09:43 -07002276
2277def checkMacAddress(input):
2278 """Validate whether a string is a valid mac address or not.
2279
2280 Args:
2281 input: The string to validate.
2282
2283 Returns: True/False, returns true for a valid mac address and false otherwise.
2284 """
2285 macValidationRegex = "[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$"
2286 if re.match(macValidationRegex, input.lower()):
2287 return True
2288 return False
lesle8e3c0a2019-02-22 17:06:04 +08002289
Omar El Ayach8c017902020-10-18 10:26:57 -07002290
lesle8e3c0a2019-02-22 17:06:04 +08002291def wait_for_expected_softap_state(ad, callbackId, expected_softap_state):
2292 """Wait for the expected softap state change.
2293 Args:
2294 callbackId: Id of the callback associated with registering.
2295 expected_softap_state: The expected softap state.
2296 """
2297 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002298 callbackId) + wifi_constants.SOFTAP_STATE_CHANGED
2299 asserts.assert_equal(
2300 ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data'][
2301 wifi_constants.SOFTAP_STATE_CHANGE_CALLBACK_KEY],
2302 expected_softap_state,
2303 "Softap state doesn't match with expected state")
2304
lesle8e3c0a2019-02-22 17:06:04 +08002305
2306def get_current_number_of_softap_clients(ad, callbackId):
2307 """pop up all of softap client updated event from queue.
2308 Args:
2309 callbackId: Id of the callback associated with registering.
2310
2311 Returns:
2312 If exist aleast callback, returns last updated number_of_softap_clients.
2313 Returns None when no any match callback event in queue.
2314 """
2315 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002316 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
lesle8e3c0a2019-02-22 17:06:04 +08002317 events = ad.ed.pop_all(eventStr)
2318 for event in events:
Omar El Ayach8c017902020-10-18 10:26:57 -07002319 num_of_clients = event['data'][
2320 wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
lesle8e3c0a2019-02-22 17:06:04 +08002321 if len(events) == 0:
2322 return None
2323 return num_of_clients
Bindu Mahadevff295782019-02-08 16:17:48 -08002324
Omar El Ayach8c017902020-10-18 10:26:57 -07002325
lesl2f0fb232019-11-05 16:35:28 +08002326def get_current_softap_info(ad, callbackId, least_one):
2327 """pop up all of softap info changed event from queue.
2328 Args:
2329 callbackId: Id of the callback associated with registering.
2330 least_one: Wait for the info callback event before pop all.
2331 Returns:
2332 Returns last updated information of softap.
2333 """
2334 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002335 callbackId) + wifi_constants.SOFTAP_INFO_CHANGED
2336 ad.log.info("softap info dump from eventStr %s", eventStr)
lesl2f0fb232019-11-05 16:35:28 +08002337 frequency = 0
2338 bandwidth = 0
2339 if (least_one):
2340 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
Omar El Ayach8c017902020-10-18 10:26:57 -07002341 frequency = event['data'][
2342 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2343 bandwidth = event['data'][
2344 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
lesl2f0fb232019-11-05 16:35:28 +08002345 ad.log.info("softap info updated, frequency is %s, bandwidth is %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07002346 frequency, bandwidth)
lesl2f0fb232019-11-05 16:35:28 +08002347
2348 events = ad.ed.pop_all(eventStr)
2349 for event in events:
Omar El Ayach8c017902020-10-18 10:26:57 -07002350 frequency = event['data'][
2351 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2352 bandwidth = event['data'][
2353 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
2354 ad.log.info("softap info, frequency is %s, bandwidth is %s", frequency,
2355 bandwidth)
lesl2f0fb232019-11-05 16:35:28 +08002356 return frequency, bandwidth
2357
2358
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002359def get_ssrdumps(ad):
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002360 """Pulls dumps in the ssrdump dir
2361 Args:
2362 ad: android device object.
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002363 """
2364 logs = ad.get_file_names("/data/vendor/ssrdump/")
2365 if logs:
2366 ad.log.info("Pulling ssrdumps %s", logs)
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002367 log_path = os.path.join(ad.device_log_path, "SSRDUMPS_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002368 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002369 ad.pull_files(logs, log_path)
Hsiu-Chang Chen769bef12020-10-10 06:07:52 +00002370 ad.adb.shell("find /data/vendor/ssrdump/ -type f -delete",
Omar El Ayach8c017902020-10-18 10:26:57 -07002371 ignore_status=True)
2372
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002373
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002374def start_pcap(pcap, wifi_band, test_name):
Girish Moturucf4dccd2018-08-27 12:22:00 -07002375 """Start packet capture in monitor mode.
2376
2377 Args:
2378 pcap: packet capture object
2379 wifi_band: '2g' or '5g' or 'dual'
Bindu Mahadev76551c12018-12-13 19:42:14 +00002380 test_name: test name to be used for pcap file name
2381
2382 Returns:
xianyuanjia0431ba32018-12-14 09:56:42 -08002383 Dictionary with wifi band as key and the tuple
2384 (pcap Process object, log directory) as the value
Girish Moturucf4dccd2018-08-27 12:22:00 -07002385 """
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002386 log_dir = os.path.join(
Xianyuan Jia5cd06bb2019-06-10 16:29:57 -07002387 context.get_current_context().get_full_output_path(), 'PacketCapture')
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002388 os.makedirs(log_dir, exist_ok=True)
Girish Moturucf4dccd2018-08-27 12:22:00 -07002389 if wifi_band == 'dual':
2390 bands = [BAND_2G, BAND_5G]
2391 else:
2392 bands = [wifi_band]
xianyuanjia0431ba32018-12-14 09:56:42 -08002393 procs = {}
Girish Moturucf4dccd2018-08-27 12:22:00 -07002394 for band in bands:
xianyuanjia0431ba32018-12-14 09:56:42 -08002395 proc = pcap.start_packet_capture(band, log_dir, test_name)
2396 procs[band] = (proc, os.path.join(log_dir, test_name))
2397 return procs
Girish Moturucf4dccd2018-08-27 12:22:00 -07002398
Bindu Mahadevff295782019-02-08 16:17:48 -08002399
xianyuanjia0431ba32018-12-14 09:56:42 -08002400def stop_pcap(pcap, procs, test_status=None):
Bindu Mahadev76551c12018-12-13 19:42:14 +00002401 """Stop packet capture in monitor mode.
2402
2403 Since, the pcap logs in monitor mode can be very large, we will
2404 delete them if they are not required. 'test_status' if True, will delete
2405 the pcap files. If False, we will keep them.
Girish Moturucf4dccd2018-08-27 12:22:00 -07002406
2407 Args:
2408 pcap: packet capture object
xianyuanjia0431ba32018-12-14 09:56:42 -08002409 procs: dictionary returned by start_pcap
Bindu Mahadev76551c12018-12-13 19:42:14 +00002410 test_status: status of the test case
Girish Moturucf4dccd2018-08-27 12:22:00 -07002411 """
xianyuanjia0431ba32018-12-14 09:56:42 -08002412 for proc, fname in procs.values():
2413 pcap.stop_packet_capture(proc)
Bindu Mahadev76551c12018-12-13 19:42:14 +00002414
2415 if test_status:
xianyuanjia0431ba32018-12-14 09:56:42 -08002416 shutil.rmtree(os.path.dirname(fname))
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002417
Omar El Ayach8c017902020-10-18 10:26:57 -07002418
Jaineel95887fd2019-10-16 16:19:01 -07002419def verify_mac_not_found_in_pcap(ad, mac, packets):
xshuf7267682019-06-03 14:41:56 -07002420 """Verify that a mac address is not found in the captured packets.
2421
2422 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002423 ad: android device object
xshuf7267682019-06-03 14:41:56 -07002424 mac: string representation of the mac address
2425 packets: packets obtained by rdpcap(pcap_fname)
2426 """
2427 for pkt in packets:
2428 logging.debug("Packet Summary = %s", pkt.summary())
2429 if mac in pkt.summary():
Jaineel95887fd2019-10-16 16:19:01 -07002430 asserts.fail("Device %s caught Factory MAC: %s in packet sniffer."
2431 "Packet = %s" % (ad.serial, mac, pkt.show()))
Bindu Mahadevff295782019-02-08 16:17:48 -08002432
Omar El Ayach8c017902020-10-18 10:26:57 -07002433
Jaineel95887fd2019-10-16 16:19:01 -07002434def verify_mac_is_found_in_pcap(ad, mac, packets):
Nate Jiangc2c09c62019-06-05 17:26:08 -07002435 """Verify that a mac address is found in the captured packets.
2436
2437 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002438 ad: android device object
Nate Jiangc2c09c62019-06-05 17:26:08 -07002439 mac: string representation of the mac address
2440 packets: packets obtained by rdpcap(pcap_fname)
2441 """
2442 for pkt in packets:
2443 if mac in pkt.summary():
2444 return
Jaineel95887fd2019-10-16 16:19:01 -07002445 asserts.fail("Did not find MAC = %s in packet sniffer."
2446 "for device %s" % (mac, ad.serial))
Nate Jiangc2c09c62019-06-05 17:26:08 -07002447
Omar El Ayach8c017902020-10-18 10:26:57 -07002448
Girish Moturuddc0d382020-08-24 12:08:41 -07002449def start_cnss_diags(ads, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002450 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002451 start_cnss_diag(ad, cnss_diag_file, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002452
Bindu Mahadevff295782019-02-08 16:17:48 -08002453
Girish Moturuddc0d382020-08-24 12:08:41 -07002454def start_cnss_diag(ad, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002455 """Start cnss_diag to record extra wifi logs
2456
2457 Args:
2458 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002459 cnss_diag_file: cnss diag config file to push to device.
2460 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002461 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002462 if ad.model not in pixel_models:
2463 ad.log.info("Device not supported to collect pixel logger")
2464 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002465 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2466 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2467 else:
2468 prop = wifi_constants.CNSS_DIAG_PROP
2469 if ad.adb.getprop(prop) != 'true':
Omar El Ayach8c017902020-10-18 10:26:57 -07002470 if not int(
2471 ad.adb.shell("ls -l %s%s | wc -l" %
2472 (CNSS_DIAG_CONFIG_PATH, CNSS_DIAG_CONFIG_FILE))):
Girish Moturuddc0d382020-08-24 12:08:41 -07002473 ad.adb.push("%s %s" % (cnss_diag_file, CNSS_DIAG_CONFIG_PATH))
Omar El Ayach8c017902020-10-18 10:26:57 -07002474 ad.adb.shell(
2475 "find /data/vendor/wifi/cnss_diag/wlan_logs/ -type f -delete",
2476 ignore_status=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002477 ad.adb.shell("setprop %s true" % prop, ignore_status=True)
2478
Bindu Mahadevff295782019-02-08 16:17:48 -08002479
Girish Moturuddc0d382020-08-24 12:08:41 -07002480def stop_cnss_diags(ads, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002481 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002482 stop_cnss_diag(ad, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002483
Bindu Mahadevff295782019-02-08 16:17:48 -08002484
Girish Moturuddc0d382020-08-24 12:08:41 -07002485def stop_cnss_diag(ad, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002486 """Stops cnss_diag
2487
2488 Args:
2489 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002490 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002491 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002492 if ad.model not in pixel_models:
2493 ad.log.info("Device not supported to collect pixel logger")
2494 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002495 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2496 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2497 else:
2498 prop = wifi_constants.CNSS_DIAG_PROP
2499 ad.adb.shell("setprop %s false" % prop, ignore_status=True)
2500
Bindu Mahadevff295782019-02-08 16:17:48 -08002501
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002502def get_cnss_diag_log(ad):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002503 """Pulls the cnss_diag logs in the wlan_logs dir
2504 Args:
2505 ad: android device object.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002506 """
2507 logs = ad.get_file_names("/data/vendor/wifi/cnss_diag/wlan_logs/")
2508 if logs:
2509 ad.log.info("Pulling cnss_diag logs %s", logs)
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002510 log_path = os.path.join(ad.device_log_path, "CNSS_DIAG_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002511 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002512 ad.pull_files(logs, log_path)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002513
Bindu Mahadevff295782019-02-08 16:17:48 -08002514
Omar El Ayach8c017902020-10-18 10:26:57 -07002515LinkProbeResult = namedtuple(
2516 'LinkProbeResult',
2517 ('is_success', 'stdout', 'elapsed_time', 'failure_reason'))
David Sue4cd9c22019-03-26 18:07:26 -07002518
2519
2520def send_link_probe(ad):
2521 """Sends a link probe to the currently connected AP, and returns whether the
2522 probe succeeded or not.
2523
2524 Args:
2525 ad: android device object
2526 Returns:
2527 LinkProbeResult namedtuple
2528 """
2529 stdout = ad.adb.shell('cmd wifi send-link-probe')
2530 asserts.assert_false('Error' in stdout or 'Exception' in stdout,
2531 'Exception while sending link probe: ' + stdout)
2532
2533 is_success = False
2534 elapsed_time = None
2535 failure_reason = None
2536 if 'succeeded' in stdout:
2537 is_success = True
2538 elapsed_time = next(
2539 (int(token) for token in stdout.split() if token.isdigit()), None)
2540 elif 'failed with reason' in stdout:
2541 failure_reason = next(
2542 (int(token) for token in stdout.split() if token.isdigit()), None)
2543 else:
2544 asserts.fail('Unexpected link probe result: ' + stdout)
2545
Omar El Ayach8c017902020-10-18 10:26:57 -07002546 return LinkProbeResult(is_success=is_success,
2547 stdout=stdout,
2548 elapsed_time=elapsed_time,
2549 failure_reason=failure_reason)
David Sue4cd9c22019-03-26 18:07:26 -07002550
2551
2552def send_link_probes(ad, num_probes, delay_sec):
2553 """Sends a sequence of link probes to the currently connected AP, and
2554 returns whether the probes succeeded or not.
2555
2556 Args:
2557 ad: android device object
2558 num_probes: number of probes to perform
2559 delay_sec: delay time between probes, in seconds
2560 Returns:
2561 List[LinkProbeResult] one LinkProbeResults for each probe
2562 """
2563 logging.info('Sending link probes')
2564 results = []
2565 for _ in range(num_probes):
2566 # send_link_probe() will also fail the test if it sees an exception
2567 # in the stdout of the adb shell command
2568 result = send_link_probe(ad)
2569 logging.info('link probe results: ' + str(result))
2570 results.append(result)
2571 time.sleep(delay_sec)
2572
2573 return results
2574
2575
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002576def ap_setup(test, index, ap, network, bandwidth=80, channel=6):
Omar El Ayach8c017902020-10-18 10:26:57 -07002577 """Set up the AP with provided network info.
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002578
2579 Args:
2580 test: the calling test class object.
2581 index: int, index of the AP.
2582 ap: access_point object of the AP.
2583 network: dict with information of the network, including ssid,
2584 password and bssid.
2585 bandwidth: the operation bandwidth for the AP, default 80MHz.
2586 channel: the channel number for the AP.
2587 Returns:
2588 brconfigs: the bridge interface configs
2589 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002590 bss_settings = []
2591 ssid = network[WifiEnums.SSID_KEY]
2592 test.access_points[index].close()
2593 time.sleep(5)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002594
Omar El Ayach8c017902020-10-18 10:26:57 -07002595 # Configure AP as required.
2596 if "password" in network.keys():
2597 password = network["password"]
2598 security = hostapd_security.Security(security_mode="wpa",
2599 password=password)
2600 else:
2601 security = hostapd_security.Security(security_mode=None, password=None)
2602 config = hostapd_ap_preset.create_ap_preset(channel=channel,
2603 ssid=ssid,
2604 security=security,
2605 bss_settings=bss_settings,
2606 vht_bandwidth=bandwidth,
2607 profile_name='whirlwind',
2608 iface_wlan_2g=ap.wlan_2g,
2609 iface_wlan_5g=ap.wlan_5g)
2610 ap.start_ap(config)
2611 logging.info("AP started on channel {} with SSID {}".format(channel, ssid))
Bindu Mahadevff295782019-02-08 16:17:48 -08002612
2613
2614def turn_ap_off(test, AP):
2615 """Bring down hostapd on the Access Point.
2616 Args:
2617 test: The test class object.
2618 AP: int, indicating which AP to turn OFF.
2619 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002620 hostapd_2g = test.access_points[AP - 1]._aps['wlan0'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002621 if hostapd_2g.is_alive():
2622 hostapd_2g.stop()
2623 logging.debug('Turned WLAN0 AP%d off' % AP)
Omar El Ayach8c017902020-10-18 10:26:57 -07002624 hostapd_5g = test.access_points[AP - 1]._aps['wlan1'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002625 if hostapd_5g.is_alive():
2626 hostapd_5g.stop()
2627 logging.debug('Turned WLAN1 AP%d off' % AP)
2628
2629
2630def turn_ap_on(test, AP):
2631 """Bring up hostapd on the Access Point.
2632 Args:
2633 test: The test class object.
2634 AP: int, indicating which AP to turn ON.
2635 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002636 hostapd_2g = test.access_points[AP - 1]._aps['wlan0'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002637 if not hostapd_2g.is_alive():
2638 hostapd_2g.start(hostapd_2g.config)
2639 logging.debug('Turned WLAN0 AP%d on' % AP)
Omar El Ayach8c017902020-10-18 10:26:57 -07002640 hostapd_5g = test.access_points[AP - 1]._aps['wlan1'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002641 if not hostapd_5g.is_alive():
2642 hostapd_5g.start(hostapd_5g.config)
2643 logging.debug('Turned WLAN1 AP%d on' % AP)
Joe Brennan48c3f692019-04-11 08:30:16 -07002644
2645
2646def turn_location_off_and_scan_toggle_off(ad):
2647 """Turns off wifi location scans."""
2648 utils.set_location_service(ad, False)
2649 ad.droid.wifiScannerToggleAlwaysAvailable(False)
2650 msg = "Failed to turn off location service's scan."
2651 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
Alfie Chen675be872020-06-04 10:48:14 +08002652
2653
2654def set_softap_channel(dut, ap_iface='wlan1', cs_count=10, channel=2462):
2655 """ Set SoftAP mode channel
2656
2657 Args:
2658 dut: android device object
2659 ap_iface: interface of SoftAP mode.
2660 cs_count: how many beacon frames before switch channel, default = 10
2661 channel: a wifi channel.
2662 """
2663 chan_switch_cmd = 'hostapd_cli -i {} chan_switch {} {}'
Omar El Ayach8c017902020-10-18 10:26:57 -07002664 chan_switch_cmd_show = chan_switch_cmd.format(ap_iface, cs_count, channel)
Alfie Chen675be872020-06-04 10:48:14 +08002665 dut.log.info('adb shell {}'.format(chan_switch_cmd_show))
Omar El Ayach8c017902020-10-18 10:26:57 -07002666 chan_switch_result = dut.adb.shell(
2667 chan_switch_cmd.format(ap_iface, cs_count, channel))
Alfie Chen675be872020-06-04 10:48:14 +08002668 if chan_switch_result == 'OK':
2669 dut.log.info('switch hotspot channel to {}'.format(channel))
2670 return chan_switch_result
2671
2672 asserts.fail("Failed to switch hotspot channel")