blob: 7f5cade8e64b22316d4a6d805892db9d6b6e3a57 [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)
1709 if matched_network:
Omar El Ayach8c017902020-10-18 10:26:57 -07001710 break
Roshan Piusc999e5e2018-11-09 10:59:52 -08001711
Omar El Ayach8c017902020-10-18 10:26:57 -07001712 asserts.assert_true(matched_network,
1713 "Target network %s not found" % network)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001714
1715 ad.droid.wifiSendUserSelectionForNetworkRequestMatch(network)
1716 ad.log.info("Sent user selection for network request %s",
1717 expected_ssid)
1718
1719 # Wait for the platform to connect to the network.
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001720 autils.wait_for_event_with_keys(
1721 ad, cconsts.EVENT_NETWORK_CALLBACK,
1722 60,
1723 (cconsts.NETWORK_CB_KEY_ID, key),
1724 (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_AVAILABLE))
1725 on_capabilities_changed = autils.wait_for_event_with_keys(
1726 ad, cconsts.EVENT_NETWORK_CALLBACK,
1727 10,
1728 (cconsts.NETWORK_CB_KEY_ID, key),
1729 (cconsts.NETWORK_CB_KEY_EVENT,
1730 cconsts.NETWORK_CB_CAPABILITIES_CHANGED))
1731 connected_network =\
1732 on_capabilities_changed["data"][cconsts.NETWORK_CB_KEY_TRANSPORT_INFO]
Roshan Piusc999e5e2018-11-09 10:59:52 -08001733 ad.log.info("Connected to network %s", connected_network)
Omar El Ayach8c017902020-10-18 10:26:57 -07001734 asserts.assert_equal(
1735 connected_network[WifiEnums.SSID_KEY], expected_ssid,
1736 "Connected to the wrong network."
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001737 "Expected %s, but got %s."
1738 % (network, connected_network))
Roshan Piusc999e5e2018-11-09 10:59:52 -08001739 except Empty:
1740 asserts.fail("Failed to connect to %s" % expected_ssid)
1741 except Exception as error:
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001742 ad.log.error("Failed to connect to %s with error %s" %
Roshan Piusc999e5e2018-11-09 10:59:52 -08001743 (expected_ssid, error))
1744 raise signals.TestFailure("Failed to connect to %s network" % network)
1745 finally:
1746 ad.droid.wifiStopTrackingStateChange()
1747
1748
Omar El Ayach8c017902020-10-18 10:26:57 -07001749def wifi_passpoint_connect(ad,
1750 passpoint_network,
1751 num_of_tries=1,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001752 assert_on_fail=True):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001753 """Connect an Android device to a wifi network.
1754
1755 Initiate connection to a wifi network, wait for the "connected" event, then
1756 confirm the connected ssid is the one requested.
1757
1758 This will directly fail a test if anything goes wrong.
1759
1760 Args:
1761 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001762 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001763 num_of_tries: An integer that is the number of times to try before
1764 delaring failure. Default is 1.
1765 assert_on_fail: If True, error checks in this function will raise test
1766 failure signals.
1767
1768 Returns:
1769 If assert_on_fail is False, function returns network id, if the connect was
1770 successful, False otherwise. If assert_on_fail is True, no return value.
1771 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001772 _assert_on_fail_handler(_wifi_passpoint_connect,
1773 assert_on_fail,
1774 ad,
1775 passpoint_network,
1776 num_of_tries=num_of_tries)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001777
1778
Oscar Shucb9af9b2019-05-02 20:01:49 +00001779def _wifi_passpoint_connect(ad, passpoint_network, num_of_tries=1):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001780 """Connect an Android device to a wifi network.
1781
1782 Initiate connection to a wifi network, wait for the "connected" event, then
1783 confirm the connected ssid is the one requested.
1784
1785 This will directly fail a test if anything goes wrong.
1786
1787 Args:
1788 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001789 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001790 num_of_tries: An integer that is the number of times to try before
1791 delaring failure. Default is 1.
1792 """
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001793 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001794 expected_ssid = passpoint_network
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001795 ad.log.info("Starting connection process to passpoint %s", expected_ssid)
1796
1797 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001798 connect_result = _wait_for_connect_event(ad, expected_ssid,
1799 num_of_tries)
1800 asserts.assert_true(
1801 connect_result, "Failed to connect to WiFi passpoint network %s on"
1802 " %s" % (expected_ssid, ad.serial))
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001803 ad.log.info("Wi-Fi connection result: %s.", connect_result)
1804 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001805 asserts.assert_equal(
1806 actual_ssid, expected_ssid,
1807 "Connected to the wrong network on %s." % ad.serial)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001808 ad.log.info("Connected to Wi-Fi passpoint network %s.", actual_ssid)
1809
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001810 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1811 if not internet:
1812 raise signals.TestFailure("Failed to connect to internet on %s" %
1813 expected_ssid)
1814 except Exception as error:
1815 ad.log.error("Failed to connect to passpoint network %s with error %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07001816 expected_ssid, error)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001817 raise signals.TestFailure("Failed to connect to %s passpoint network" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001818 expected_ssid)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001819
1820 finally:
1821 ad.droid.wifiStopTrackingStateChange()
1822
1823
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001824def delete_passpoint(ad, fqdn):
1825 """Delete a required Passpoint configuration."""
1826 try:
1827 ad.droid.removePasspointConfig(fqdn)
1828 return True
1829 except Exception as error:
Omar El Ayach8c017902020-10-18 10:26:57 -07001830 ad.log.error(
1831 "Failed to remove passpoint configuration with FQDN=%s "
1832 "and error=%s", fqdn, error)
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001833 return False
1834
1835
Ang Li73697b32015-12-03 00:41:53 +00001836def start_wifi_single_scan(ad, scan_setting):
1837 """Starts wifi single shot scan.
1838
1839 Args:
1840 ad: android_device object to initiate connection on.
1841 scan_setting: A dict representing the settings of the scan.
1842
1843 Returns:
1844 If scan was started successfully, event data of success event is returned.
1845 """
Ang Li82522812016-06-02 13:57:21 -07001846 idx = ad.droid.wifiScannerStartScan(scan_setting)
1847 event = ad.ed.pop_event("WifiScannerScan%sonSuccess" % idx, SHORT_TIMEOUT)
Ang Li31b00782016-06-21 13:04:23 -07001848 ad.log.debug("Got event %s", event)
Ang Li73697b32015-12-03 00:41:53 +00001849 return event['data']
1850
Ang Li82522812016-06-02 13:57:21 -07001851
Ang Li73697b32015-12-03 00:41:53 +00001852def track_connection(ad, network_ssid, check_connection_count):
1853 """Track wifi connection to network changes for given number of counts
1854
1855 Args:
1856 ad: android_device object for forget network.
1857 network_ssid: network ssid to which connection would be tracked
1858 check_connection_count: Integer for maximum number network connection
Ang Li82522812016-06-02 13:57:21 -07001859 check.
Ang Li73697b32015-12-03 00:41:53 +00001860 Returns:
Ang Li73697b32015-12-03 00:41:53 +00001861 True if connection to given network happen, else return False.
1862 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001863 ad.droid.wifiStartTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001864 while check_connection_count > 0:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001865 connect_network = ad.ed.pop_event("WifiNetworkConnected", 120)
Ang Li31b00782016-06-21 13:04:23 -07001866 ad.log.info("Connected to network %s", connect_network)
Ang Li82522812016-06-02 13:57:21 -07001867 if (WifiEnums.SSID_KEY in connect_network['data'] and
1868 connect_network['data'][WifiEnums.SSID_KEY] == network_ssid):
1869 return True
Ang Li8e767182015-12-09 17:29:24 -08001870 check_connection_count -= 1
Girish Moturu40d7dc22016-11-02 12:14:56 -07001871 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001872 return False
1873
Ang Li82522812016-06-02 13:57:21 -07001874
Ang Li73697b32015-12-03 00:41:53 +00001875def get_scan_time_and_channels(wifi_chs, scan_setting, stime_channel):
1876 """Calculate the scan time required based on the band or channels in scan
1877 setting
1878
1879 Args:
1880 wifi_chs: Object of channels supported
1881 scan_setting: scan setting used for start scan
1882 stime_channel: scan time per channel
1883
1884 Returns:
1885 scan_time: time required for completing a scan
1886 scan_channels: channel used for scanning
1887 """
1888 scan_time = 0
1889 scan_channels = []
1890 if "band" in scan_setting and "channels" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001891 scan_channels = wifi_chs.band_to_freq(scan_setting["band"])
Ang Li73697b32015-12-03 00:41:53 +00001892 elif "channels" in scan_setting and "band" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001893 scan_channels = scan_setting["channels"]
Ang Li73697b32015-12-03 00:41:53 +00001894 scan_time = len(scan_channels) * stime_channel
1895 for channel in scan_channels:
Ang Li8e767182015-12-09 17:29:24 -08001896 if channel in WifiEnums.DFS_5G_FREQUENCIES:
Ang Li82522812016-06-02 13:57:21 -07001897 scan_time += 132 #passive scan time on DFS
Ang Li73697b32015-12-03 00:41:53 +00001898 return scan_time, scan_channels
1899
Ang Li82522812016-06-02 13:57:21 -07001900
Ang Li73697b32015-12-03 00:41:53 +00001901def start_wifi_track_bssid(ad, track_setting):
1902 """Start tracking Bssid for the given settings.
1903
1904 Args:
1905 ad: android_device object.
1906 track_setting: Setting for which the bssid tracking should be started
1907
1908 Returns:
1909 If tracking started successfully, event data of success event is returned.
1910 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001911 idx = ad.droid.wifiScannerStartTrackingBssids(
Ang Li82522812016-06-02 13:57:21 -07001912 track_setting["bssidInfos"], track_setting["apLostThreshold"])
Girish Moturu40d7dc22016-11-02 12:14:56 -07001913 event = ad.ed.pop_event("WifiScannerBssid{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -08001914 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +00001915 return event['data']
1916
Ang Li82522812016-06-02 13:57:21 -07001917
Ang Li73697b32015-12-03 00:41:53 +00001918def convert_pem_key_to_pkcs8(in_file, out_file):
1919 """Converts the key file generated by us to the format required by
1920 Android using openssl.
1921
1922 The input file must have the extension "pem". The output file must
1923 have the extension "der".
1924
1925 Args:
1926 in_file: The original key file.
1927 out_file: The full path to the converted key file, including
1928 filename.
1929 """
Ang Li82522812016-06-02 13:57:21 -07001930 asserts.assert_true(in_file.endswith(".pem"), "Input file has to be .pem.")
Omar El Ayach8c017902020-10-18 10:26:57 -07001931 asserts.assert_true(out_file.endswith(".der"),
1932 "Output file has to be .der.")
Ang Li73697b32015-12-03 00:41:53 +00001933 cmd = ("openssl pkcs8 -inform PEM -in {} -outform DER -out {} -nocrypt"
1934 " -topk8").format(in_file, out_file)
Ang Lifee28402016-07-13 13:43:29 -07001935 utils.exe_cmd(cmd)
Ang Li73697b32015-12-03 00:41:53 +00001936
Ang Li82522812016-06-02 13:57:21 -07001937
Omar El Ayach8c017902020-10-18 10:26:57 -07001938def validate_connection(ad,
1939 ping_addr=DEFAULT_PING_ADDR,
1940 wait_time=15,
Girish Moturu804a3492020-02-17 14:32:02 -08001941 ping_gateway=True):
Ang Li73697b32015-12-03 00:41:53 +00001942 """Validate internet connection by pinging the address provided.
1943
1944 Args:
1945 ad: android_device object.
1946 ping_addr: address on internet for pinging.
Girish Moturua2a5bf22019-08-16 09:52:29 -07001947 wait_time: wait for some time before validating connection
Ang Li73697b32015-12-03 00:41:53 +00001948
1949 Returns:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001950 ping output if successful, NULL otherwise.
Ang Li73697b32015-12-03 00:41:53 +00001951 """
Girish Moturua2a5bf22019-08-16 09:52:29 -07001952 # wait_time to allow for DHCP to complete.
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08001953 for i in range(wait_time):
Girish Moturuacf35002020-11-09 23:37:35 -08001954 if ad.droid.connectivityNetworkIsConnected(
Omar El Ayach8c017902020-10-18 10:26:57 -07001955 ) and ad.droid.connectivityGetIPv4DefaultGateway():
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08001956 break
1957 time.sleep(1)
Girish Moturu804a3492020-02-17 14:32:02 -08001958 ping = False
1959 try:
1960 ping = ad.droid.httpPing(ping_addr)
1961 ad.log.info("Http ping result: %s.", ping)
1962 except:
1963 pass
1964 if not ping and ping_gateway:
1965 ad.log.info("Http ping failed. Pinging default gateway")
1966 gw = ad.droid.connectivityGetIPv4DefaultGateway()
1967 result = ad.adb.shell("ping -c 6 {}".format(gw))
1968 ad.log.info("Default gateway ping result: %s" % result)
1969 ping = False if "100% packet loss" in result else True
Ang Li73697b32015-12-03 00:41:53 +00001970 return ping
1971
Ang Li82522812016-06-02 13:57:21 -07001972
Ang Li73697b32015-12-03 00:41:53 +00001973#TODO(angli): This can only verify if an actual value is exactly the same.
1974# Would be nice to be able to verify an actual value is one of serveral.
1975def verify_wifi_connection_info(ad, expected_con):
1976 """Verifies that the information of the currently connected wifi network is
1977 as expected.
1978
1979 Args:
1980 expected_con: A dict representing expected key-value pairs for wifi
1981 connection. e.g. {"SSID": "test_wifi"}
1982 """
1983 current_con = ad.droid.wifiGetConnectionInfo()
Ang Li374d7602016-02-08 17:27:27 -08001984 case_insensitive = ["BSSID", "supplicant_state"]
Ang Li31b00782016-06-21 13:04:23 -07001985 ad.log.debug("Current connection: %s", current_con)
Ang Li73697b32015-12-03 00:41:53 +00001986 for k, expected_v in expected_con.items():
Ang Li9a66de72016-02-08 15:26:38 -08001987 # Do not verify authentication related fields.
1988 if k == "password":
1989 continue
Ang Li82522812016-06-02 13:57:21 -07001990 msg = "Field %s does not exist in wifi connection info %s." % (
1991 k, current_con)
Ang Li374d7602016-02-08 17:27:27 -08001992 if k not in current_con:
1993 raise signals.TestFailure(msg)
1994 actual_v = current_con[k]
1995 if k in case_insensitive:
1996 actual_v = actual_v.lower()
1997 expected_v = expected_v.lower()
Ang Li73697b32015-12-03 00:41:53 +00001998 msg = "Expected %s to be %s, actual %s is %s." % (k, expected_v, k,
Ang Li82522812016-06-02 13:57:21 -07001999 actual_v)
Ang Li374d7602016-02-08 17:27:27 -08002000 if actual_v != expected_v:
2001 raise signals.TestFailure(msg)
Ang Li73697b32015-12-03 00:41:53 +00002002
Ang Li82522812016-06-02 13:57:21 -07002003
Omar El Ayach8c017902020-10-18 10:26:57 -07002004def check_autoconnect_to_open_network(
2005 ad, conn_timeout=WIFI_CONNECTION_TIMEOUT_DEFAULT):
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08002006 """Connects to any open WiFI AP
2007 Args:
2008 timeout value in sec to wait for UE to connect to a WiFi AP
2009 Returns:
2010 True if UE connects to WiFi AP (supplicant_state = completed)
2011 False if UE fails to complete connection within WIFI_CONNECTION_TIMEOUT time.
2012 """
2013 if ad.droid.wifiCheckState():
2014 return True
2015 ad.droid.wifiToggleState()
2016 wifi_connection_state = None
2017 timeout = time.time() + conn_timeout
2018 while wifi_connection_state != "completed":
Omar El Ayach8c017902020-10-18 10:26:57 -07002019 wifi_connection_state = ad.droid.wifiGetConnectionInfo(
2020 )['supplicant_state']
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08002021 if time.time() > timeout:
2022 ad.log.warning("Failed to connect to WiFi AP")
2023 return False
2024 return True
2025
2026
Ang Li73697b32015-12-03 00:41:53 +00002027def expand_enterprise_config_by_phase2(config):
2028 """Take an enterprise config and generate a list of configs, each with
2029 a different phase2 auth type.
2030
2031 Args:
2032 config: A dict representing enterprise config.
2033
2034 Returns
2035 A list of enterprise configs.
2036 """
2037 results = []
Ang Li0e7e58f2016-02-22 12:15:02 -08002038 phase2_types = WifiEnums.EapPhase2
2039 if config[WifiEnums.Enterprise.EAP] == WifiEnums.Eap.PEAP:
2040 # Skip unsupported phase2 types for PEAP.
2041 phase2_types = [WifiEnums.EapPhase2.GTC, WifiEnums.EapPhase2.MSCHAPV2]
2042 for phase2_type in phase2_types:
Ang Li73697b32015-12-03 00:41:53 +00002043 # Skip a special case for passpoint TTLS.
Omar El Ayach8c017902020-10-18 10:26:57 -07002044 if (WifiEnums.Enterprise.FQDN in config
2045 and phase2_type == WifiEnums.EapPhase2.GTC):
Ang Li73697b32015-12-03 00:41:53 +00002046 continue
2047 c = dict(config)
Girish Moturu150d32f2017-02-14 12:27:07 -08002048 c[WifiEnums.Enterprise.PHASE2] = phase2_type.value
Ang Li73697b32015-12-03 00:41:53 +00002049 results.append(c)
2050 return results
Ang Li2d3fe982016-06-08 10:00:43 -07002051
2052
Girish Moturub48a13c2017-02-27 11:36:42 -08002053def generate_eap_test_name(config, ad=None):
Girish Moturu150d32f2017-02-14 12:27:07 -08002054 """ Generates a test case name based on an EAP configuration.
2055
2056 Args:
2057 config: A dict representing an EAP credential.
Girish Moturub48a13c2017-02-27 11:36:42 -08002058 ad object: Redundant but required as the same param is passed
2059 to test_func in run_generated_tests
Girish Moturu150d32f2017-02-14 12:27:07 -08002060
2061 Returns:
2062 A string representing the name of a generated EAP test case.
2063 """
2064 eap = WifiEnums.Eap
2065 eap_phase2 = WifiEnums.EapPhase2
Girish Moturub48a13c2017-02-27 11:36:42 -08002066 Ent = WifiEnums.Enterprise
Girish Moturu150d32f2017-02-14 12:27:07 -08002067 name = "test_connect-"
2068 eap_name = ""
2069 for e in eap:
2070 if e.value == config[Ent.EAP]:
2071 eap_name = e.name
2072 break
2073 if "peap0" in config[WifiEnums.SSID_KEY].lower():
2074 eap_name = "PEAP0"
2075 if "peap1" in config[WifiEnums.SSID_KEY].lower():
2076 eap_name = "PEAP1"
2077 name += eap_name
2078 if Ent.PHASE2 in config:
2079 for e in eap_phase2:
2080 if e.value == config[Ent.PHASE2]:
2081 name += "-{}".format(e.name)
2082 break
2083 return name
2084
2085
Ang Li2d3fe982016-06-08 10:00:43 -07002086def group_attenuators(attenuators):
2087 """Groups a list of attenuators into attenuator groups for backward
2088 compatibility reasons.
2089
2090 Most legacy Wi-Fi setups have two attenuators each connected to a separate
2091 AP. The new Wi-Fi setup has four attenuators, each connected to one channel
2092 on an AP, so two of them are connected to one AP.
2093
2094 To make the existing scripts work in the new setup, when the script needs
2095 to attenuate one AP, it needs to set attenuation on both attenuators
2096 connected to the same AP.
2097
2098 This function groups attenuators properly so the scripts work in both
2099 legacy and new Wi-Fi setups.
2100
2101 Args:
2102 attenuators: A list of attenuator objects, either two or four in length.
2103
2104 Raises:
2105 signals.TestFailure is raised if the attenuator list does not have two
2106 or four objects.
2107 """
2108 attn0 = attenuator.AttenuatorGroup("AP0")
2109 attn1 = attenuator.AttenuatorGroup("AP1")
2110 # Legacy testbed setup has two attenuation channels.
2111 num_of_attns = len(attenuators)
2112 if num_of_attns == 2:
2113 attn0.add(attenuators[0])
2114 attn1.add(attenuators[1])
2115 elif num_of_attns == 4:
2116 attn0.add(attenuators[0])
2117 attn0.add(attenuators[1])
2118 attn1.add(attenuators[2])
2119 attn1.add(attenuators[3])
2120 else:
2121 asserts.fail(("Either two or four attenuators are required for this "
2122 "test, but found %s") % num_of_attns)
2123 return [attn0, attn1]
Jong Wook Kim92356922018-02-06 18:32:49 -08002124
Bindu Mahadevff295782019-02-08 16:17:48 -08002125
Girish Moturu36348a32019-12-10 08:41:54 -08002126def set_attns(attenuator, attn_val_name, roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002127 """Sets attenuation values on attenuators used in this test.
2128
2129 Args:
2130 attenuator: The attenuator object.
2131 attn_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002132 roaming_attn: Dictionary specifying the attenuation params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002133 """
2134 logging.info("Set attenuation values to %s", roaming_attn[attn_val_name])
2135 try:
2136 attenuator[0].set_atten(roaming_attn[attn_val_name][0])
2137 attenuator[1].set_atten(roaming_attn[attn_val_name][1])
2138 attenuator[2].set_atten(roaming_attn[attn_val_name][2])
2139 attenuator[3].set_atten(roaming_attn[attn_val_name][3])
2140 except:
2141 logging.exception("Failed to set attenuation values %s.",
Omar El Ayach8c017902020-10-18 10:26:57 -07002142 attn_val_name)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002143 raise
2144
Omar El Ayach8c017902020-10-18 10:26:57 -07002145
Girish Moturu36348a32019-12-10 08:41:54 -08002146def set_attns_steps(attenuators,
2147 atten_val_name,
2148 roaming_attn=ROAMING_ATTN,
2149 steps=10,
2150 wait_time=12):
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002151 """Set attenuation values on attenuators used in this test. It will change
2152 the attenuation values linearly from current value to target value step by
2153 step.
2154
2155 Args:
2156 attenuators: The list of attenuator objects that you want to change
2157 their attenuation value.
2158 atten_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002159 roaming_attn: Dictionary specifying the attenuation params.
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002160 steps: Number of attenuator changes to reach the target value.
2161 wait_time: Sleep time for each change of attenuator.
2162 """
2163 logging.info("Set attenuation values to %s in %d step(s)",
Omar El Ayach8c017902020-10-18 10:26:57 -07002164 roaming_attn[atten_val_name], steps)
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002165 start_atten = [attenuator.get_atten() for attenuator in attenuators]
2166 target_atten = roaming_attn[atten_val_name]
2167 for current_step in range(steps):
2168 progress = (current_step + 1) / steps
2169 for i, attenuator in enumerate(attenuators):
2170 amount_since_start = (target_atten[i] - start_atten[i]) * progress
2171 attenuator.set_atten(round(start_atten[i] + amount_since_start))
2172 time.sleep(wait_time)
2173
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002174
Girish Moturu36348a32019-12-10 08:41:54 -08002175def trigger_roaming_and_validate(dut,
2176 attenuator,
2177 attn_val_name,
2178 expected_con,
2179 roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002180 """Sets attenuators to trigger roaming and validate the DUT connected
2181 to the BSSID expected.
2182
2183 Args:
2184 attenuator: The attenuator object.
2185 attn_val_name: Name of the attenuation value pair to use.
2186 expected_con: The network information of the expected network.
Girish Moturu36348a32019-12-10 08:41:54 -08002187 roaming_attn: Dictionary specifying the attenaution params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002188 """
2189 expected_con = {
2190 WifiEnums.SSID_KEY: expected_con[WifiEnums.SSID_KEY],
2191 WifiEnums.BSSID_KEY: expected_con["bssid"],
2192 }
Girish Moturu36348a32019-12-10 08:41:54 -08002193 set_attns_steps(attenuator, attn_val_name, roaming_attn)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002194
Hsiu-Chang Chenef856402018-09-18 12:32:49 +08002195 verify_wifi_connection_info(dut, expected_con)
2196 expected_bssid = expected_con[WifiEnums.BSSID_KEY]
2197 logging.info("Roamed to %s successfully", expected_bssid)
2198 if not validate_connection(dut):
2199 raise signals.TestFailure("Fail to connect to internet on %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07002200 expected_bssid)
2201
Jong Wook Kim92356922018-02-06 18:32:49 -08002202
2203def create_softap_config():
2204 """Create a softap config with random ssid and password."""
2205 ap_ssid = "softap_" + utils.rand_ascii_str(8)
2206 ap_password = utils.rand_ascii_str(8)
2207 logging.info("softap setup: %s %s", ap_ssid, ap_password)
2208 config = {
2209 WifiEnums.SSID_KEY: ap_ssid,
2210 WifiEnums.PWD_KEY: ap_password,
2211 }
2212 return config
Girish Moturucf4dccd2018-08-27 12:22:00 -07002213
Omar El Ayach8c017902020-10-18 10:26:57 -07002214
Bindu Mahadevff295782019-02-08 16:17:48 -08002215def start_softap_and_verify(ad, band):
2216 """Bring-up softap and verify AP mode and in scan results.
2217
2218 Args:
2219 band: The band to use for softAP.
2220
2221 Returns: dict, the softAP config.
2222
2223 """
lesl2f0fb232019-11-05 16:35:28 +08002224 # Register before start the test.
2225 callbackId = ad.dut.droid.registerSoftApCallback()
2226 # Check softap info value is default
2227 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2228 asserts.assert_true(frequency == 0, "Softap frequency is not reset")
2229 asserts.assert_true(bandwdith == 0, "Softap bandwdith is not reset")
2230
Bindu Mahadevff295782019-02-08 16:17:48 -08002231 config = create_softap_config()
2232 start_wifi_tethering(ad.dut,
2233 config[WifiEnums.SSID_KEY],
Omar El Ayach8c017902020-10-18 10:26:57 -07002234 config[WifiEnums.PWD_KEY],
2235 band=band)
Bindu Mahadevff295782019-02-08 16:17:48 -08002236 asserts.assert_true(ad.dut.droid.wifiIsApEnabled(),
Omar El Ayach8c017902020-10-18 10:26:57 -07002237 "SoftAp is not reported as running")
2238 start_wifi_connection_scan_and_ensure_network_found(
2239 ad.dut_client, config[WifiEnums.SSID_KEY])
lesl2f0fb232019-11-05 16:35:28 +08002240
2241 # Check softap info can get from callback succeed and assert value should be
2242 # valid.
2243 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2244 asserts.assert_true(frequency > 0, "Softap frequency is not valid")
2245 asserts.assert_true(bandwdith > 0, "Softap bandwdith is not valid")
2246 # Unregister callback
2247 ad.dut.droid.unregisterSoftApCallback(callbackId)
2248
Bindu Mahadevff295782019-02-08 16:17:48 -08002249 return config
2250
Omar El Ayach8c017902020-10-18 10:26:57 -07002251
lesle8e3c0a2019-02-22 17:06:04 +08002252def wait_for_expected_number_of_softap_clients(ad, callbackId,
Omar El Ayach8c017902020-10-18 10:26:57 -07002253 expected_num_of_softap_clients):
lesle8e3c0a2019-02-22 17:06:04 +08002254 """Wait for the number of softap clients to be updated as expected.
2255 Args:
2256 callbackId: Id of the callback associated with registering.
2257 expected_num_of_softap_clients: expected number of softap clients.
2258 """
2259 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002260 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
James Mattis5a5dd492020-05-14 13:09:43 -07002261 clientData = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data']
2262 clientCount = clientData[wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07002263 clientMacAddresses = clientData[
2264 wifi_constants.SOFTAP_CLIENTS_MACS_CALLBACK_KEY]
2265 asserts.assert_equal(
2266 clientCount, expected_num_of_softap_clients,
2267 "The number of softap clients doesn't match the expected number")
2268 asserts.assert_equal(
2269 len(clientMacAddresses), expected_num_of_softap_clients,
2270 "The number of mac addresses doesn't match the expected number")
James Mattis5a5dd492020-05-14 13:09:43 -07002271 for macAddress in clientMacAddresses:
Omar El Ayach8c017902020-10-18 10:26:57 -07002272 asserts.assert_true(checkMacAddress(macAddress),
2273 "An invalid mac address was returned")
2274
James Mattis5a5dd492020-05-14 13:09:43 -07002275
2276def checkMacAddress(input):
2277 """Validate whether a string is a valid mac address or not.
2278
2279 Args:
2280 input: The string to validate.
2281
2282 Returns: True/False, returns true for a valid mac address and false otherwise.
2283 """
2284 macValidationRegex = "[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$"
2285 if re.match(macValidationRegex, input.lower()):
2286 return True
2287 return False
lesle8e3c0a2019-02-22 17:06:04 +08002288
Omar El Ayach8c017902020-10-18 10:26:57 -07002289
lesle8e3c0a2019-02-22 17:06:04 +08002290def wait_for_expected_softap_state(ad, callbackId, expected_softap_state):
2291 """Wait for the expected softap state change.
2292 Args:
2293 callbackId: Id of the callback associated with registering.
2294 expected_softap_state: The expected softap state.
2295 """
2296 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002297 callbackId) + wifi_constants.SOFTAP_STATE_CHANGED
2298 asserts.assert_equal(
2299 ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data'][
2300 wifi_constants.SOFTAP_STATE_CHANGE_CALLBACK_KEY],
2301 expected_softap_state,
2302 "Softap state doesn't match with expected state")
2303
lesle8e3c0a2019-02-22 17:06:04 +08002304
2305def get_current_number_of_softap_clients(ad, callbackId):
2306 """pop up all of softap client updated event from queue.
2307 Args:
2308 callbackId: Id of the callback associated with registering.
2309
2310 Returns:
2311 If exist aleast callback, returns last updated number_of_softap_clients.
2312 Returns None when no any match callback event in queue.
2313 """
2314 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002315 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
lesle8e3c0a2019-02-22 17:06:04 +08002316 events = ad.ed.pop_all(eventStr)
2317 for event in events:
Omar El Ayach8c017902020-10-18 10:26:57 -07002318 num_of_clients = event['data'][
2319 wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
lesle8e3c0a2019-02-22 17:06:04 +08002320 if len(events) == 0:
2321 return None
2322 return num_of_clients
Bindu Mahadevff295782019-02-08 16:17:48 -08002323
Omar El Ayach8c017902020-10-18 10:26:57 -07002324
lesl2f0fb232019-11-05 16:35:28 +08002325def get_current_softap_info(ad, callbackId, least_one):
2326 """pop up all of softap info changed event from queue.
2327 Args:
2328 callbackId: Id of the callback associated with registering.
2329 least_one: Wait for the info callback event before pop all.
2330 Returns:
2331 Returns last updated information of softap.
2332 """
2333 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002334 callbackId) + wifi_constants.SOFTAP_INFO_CHANGED
2335 ad.log.info("softap info dump from eventStr %s", eventStr)
lesl2f0fb232019-11-05 16:35:28 +08002336 frequency = 0
2337 bandwidth = 0
2338 if (least_one):
2339 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
Omar El Ayach8c017902020-10-18 10:26:57 -07002340 frequency = event['data'][
2341 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2342 bandwidth = event['data'][
2343 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
lesl2f0fb232019-11-05 16:35:28 +08002344 ad.log.info("softap info updated, frequency is %s, bandwidth is %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07002345 frequency, bandwidth)
lesl2f0fb232019-11-05 16:35:28 +08002346
2347 events = ad.ed.pop_all(eventStr)
2348 for event in events:
Omar El Ayach8c017902020-10-18 10:26:57 -07002349 frequency = event['data'][
2350 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2351 bandwidth = event['data'][
2352 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
2353 ad.log.info("softap info, frequency is %s, bandwidth is %s", frequency,
2354 bandwidth)
lesl2f0fb232019-11-05 16:35:28 +08002355 return frequency, bandwidth
2356
2357
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002358def get_ssrdumps(ad):
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002359 """Pulls dumps in the ssrdump dir
2360 Args:
2361 ad: android device object.
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002362 """
2363 logs = ad.get_file_names("/data/vendor/ssrdump/")
2364 if logs:
2365 ad.log.info("Pulling ssrdumps %s", logs)
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002366 log_path = os.path.join(ad.device_log_path, "SSRDUMPS_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002367 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002368 ad.pull_files(logs, log_path)
Hsiu-Chang Chen769bef12020-10-10 06:07:52 +00002369 ad.adb.shell("find /data/vendor/ssrdump/ -type f -delete",
Omar El Ayach8c017902020-10-18 10:26:57 -07002370 ignore_status=True)
2371
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002372
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002373def start_pcap(pcap, wifi_band, test_name):
Girish Moturucf4dccd2018-08-27 12:22:00 -07002374 """Start packet capture in monitor mode.
2375
2376 Args:
2377 pcap: packet capture object
2378 wifi_band: '2g' or '5g' or 'dual'
Bindu Mahadev76551c12018-12-13 19:42:14 +00002379 test_name: test name to be used for pcap file name
2380
2381 Returns:
xianyuanjia0431ba32018-12-14 09:56:42 -08002382 Dictionary with wifi band as key and the tuple
2383 (pcap Process object, log directory) as the value
Girish Moturucf4dccd2018-08-27 12:22:00 -07002384 """
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002385 log_dir = os.path.join(
Xianyuan Jia5cd06bb2019-06-10 16:29:57 -07002386 context.get_current_context().get_full_output_path(), 'PacketCapture')
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002387 os.makedirs(log_dir, exist_ok=True)
Girish Moturucf4dccd2018-08-27 12:22:00 -07002388 if wifi_band == 'dual':
2389 bands = [BAND_2G, BAND_5G]
2390 else:
2391 bands = [wifi_band]
xianyuanjia0431ba32018-12-14 09:56:42 -08002392 procs = {}
Girish Moturucf4dccd2018-08-27 12:22:00 -07002393 for band in bands:
xianyuanjia0431ba32018-12-14 09:56:42 -08002394 proc = pcap.start_packet_capture(band, log_dir, test_name)
2395 procs[band] = (proc, os.path.join(log_dir, test_name))
2396 return procs
Girish Moturucf4dccd2018-08-27 12:22:00 -07002397
Bindu Mahadevff295782019-02-08 16:17:48 -08002398
xianyuanjia0431ba32018-12-14 09:56:42 -08002399def stop_pcap(pcap, procs, test_status=None):
Bindu Mahadev76551c12018-12-13 19:42:14 +00002400 """Stop packet capture in monitor mode.
2401
2402 Since, the pcap logs in monitor mode can be very large, we will
2403 delete them if they are not required. 'test_status' if True, will delete
2404 the pcap files. If False, we will keep them.
Girish Moturucf4dccd2018-08-27 12:22:00 -07002405
2406 Args:
2407 pcap: packet capture object
xianyuanjia0431ba32018-12-14 09:56:42 -08002408 procs: dictionary returned by start_pcap
Bindu Mahadev76551c12018-12-13 19:42:14 +00002409 test_status: status of the test case
Girish Moturucf4dccd2018-08-27 12:22:00 -07002410 """
xianyuanjia0431ba32018-12-14 09:56:42 -08002411 for proc, fname in procs.values():
2412 pcap.stop_packet_capture(proc)
Bindu Mahadev76551c12018-12-13 19:42:14 +00002413
2414 if test_status:
xianyuanjia0431ba32018-12-14 09:56:42 -08002415 shutil.rmtree(os.path.dirname(fname))
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002416
Omar El Ayach8c017902020-10-18 10:26:57 -07002417
Jaineel95887fd2019-10-16 16:19:01 -07002418def verify_mac_not_found_in_pcap(ad, mac, packets):
xshuf7267682019-06-03 14:41:56 -07002419 """Verify that a mac address is not found in the captured packets.
2420
2421 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002422 ad: android device object
xshuf7267682019-06-03 14:41:56 -07002423 mac: string representation of the mac address
2424 packets: packets obtained by rdpcap(pcap_fname)
2425 """
2426 for pkt in packets:
2427 logging.debug("Packet Summary = %s", pkt.summary())
2428 if mac in pkt.summary():
Jaineel95887fd2019-10-16 16:19:01 -07002429 asserts.fail("Device %s caught Factory MAC: %s in packet sniffer."
2430 "Packet = %s" % (ad.serial, mac, pkt.show()))
Bindu Mahadevff295782019-02-08 16:17:48 -08002431
Omar El Ayach8c017902020-10-18 10:26:57 -07002432
Jaineel95887fd2019-10-16 16:19:01 -07002433def verify_mac_is_found_in_pcap(ad, mac, packets):
Nate Jiangc2c09c62019-06-05 17:26:08 -07002434 """Verify that a mac address is found in the captured packets.
2435
2436 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002437 ad: android device object
Nate Jiangc2c09c62019-06-05 17:26:08 -07002438 mac: string representation of the mac address
2439 packets: packets obtained by rdpcap(pcap_fname)
2440 """
2441 for pkt in packets:
2442 if mac in pkt.summary():
2443 return
Jaineel95887fd2019-10-16 16:19:01 -07002444 asserts.fail("Did not find MAC = %s in packet sniffer."
2445 "for device %s" % (mac, ad.serial))
Nate Jiangc2c09c62019-06-05 17:26:08 -07002446
Omar El Ayach8c017902020-10-18 10:26:57 -07002447
Girish Moturuddc0d382020-08-24 12:08:41 -07002448def start_cnss_diags(ads, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002449 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002450 start_cnss_diag(ad, cnss_diag_file, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002451
Bindu Mahadevff295782019-02-08 16:17:48 -08002452
Girish Moturuddc0d382020-08-24 12:08:41 -07002453def start_cnss_diag(ad, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002454 """Start cnss_diag to record extra wifi logs
2455
2456 Args:
2457 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002458 cnss_diag_file: cnss diag config file to push to device.
2459 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002460 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002461 if ad.model not in pixel_models:
2462 ad.log.info("Device not supported to collect pixel logger")
2463 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002464 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2465 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2466 else:
2467 prop = wifi_constants.CNSS_DIAG_PROP
2468 if ad.adb.getprop(prop) != 'true':
Omar El Ayach8c017902020-10-18 10:26:57 -07002469 if not int(
2470 ad.adb.shell("ls -l %s%s | wc -l" %
2471 (CNSS_DIAG_CONFIG_PATH, CNSS_DIAG_CONFIG_FILE))):
Girish Moturuddc0d382020-08-24 12:08:41 -07002472 ad.adb.push("%s %s" % (cnss_diag_file, CNSS_DIAG_CONFIG_PATH))
Omar El Ayach8c017902020-10-18 10:26:57 -07002473 ad.adb.shell(
2474 "find /data/vendor/wifi/cnss_diag/wlan_logs/ -type f -delete",
2475 ignore_status=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002476 ad.adb.shell("setprop %s true" % prop, ignore_status=True)
2477
Bindu Mahadevff295782019-02-08 16:17:48 -08002478
Girish Moturuddc0d382020-08-24 12:08:41 -07002479def stop_cnss_diags(ads, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002480 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002481 stop_cnss_diag(ad, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002482
Bindu Mahadevff295782019-02-08 16:17:48 -08002483
Girish Moturuddc0d382020-08-24 12:08:41 -07002484def stop_cnss_diag(ad, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002485 """Stops cnss_diag
2486
2487 Args:
2488 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002489 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002490 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002491 if ad.model not in pixel_models:
2492 ad.log.info("Device not supported to collect pixel logger")
2493 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002494 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2495 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2496 else:
2497 prop = wifi_constants.CNSS_DIAG_PROP
2498 ad.adb.shell("setprop %s false" % prop, ignore_status=True)
2499
Bindu Mahadevff295782019-02-08 16:17:48 -08002500
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002501def get_cnss_diag_log(ad):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002502 """Pulls the cnss_diag logs in the wlan_logs dir
2503 Args:
2504 ad: android device object.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002505 """
2506 logs = ad.get_file_names("/data/vendor/wifi/cnss_diag/wlan_logs/")
2507 if logs:
2508 ad.log.info("Pulling cnss_diag logs %s", logs)
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002509 log_path = os.path.join(ad.device_log_path, "CNSS_DIAG_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002510 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002511 ad.pull_files(logs, log_path)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002512
Bindu Mahadevff295782019-02-08 16:17:48 -08002513
Omar El Ayach8c017902020-10-18 10:26:57 -07002514LinkProbeResult = namedtuple(
2515 'LinkProbeResult',
2516 ('is_success', 'stdout', 'elapsed_time', 'failure_reason'))
David Sue4cd9c22019-03-26 18:07:26 -07002517
2518
2519def send_link_probe(ad):
2520 """Sends a link probe to the currently connected AP, and returns whether the
2521 probe succeeded or not.
2522
2523 Args:
2524 ad: android device object
2525 Returns:
2526 LinkProbeResult namedtuple
2527 """
2528 stdout = ad.adb.shell('cmd wifi send-link-probe')
2529 asserts.assert_false('Error' in stdout or 'Exception' in stdout,
2530 'Exception while sending link probe: ' + stdout)
2531
2532 is_success = False
2533 elapsed_time = None
2534 failure_reason = None
2535 if 'succeeded' in stdout:
2536 is_success = True
2537 elapsed_time = next(
2538 (int(token) for token in stdout.split() if token.isdigit()), None)
2539 elif 'failed with reason' in stdout:
2540 failure_reason = next(
2541 (int(token) for token in stdout.split() if token.isdigit()), None)
2542 else:
2543 asserts.fail('Unexpected link probe result: ' + stdout)
2544
Omar El Ayach8c017902020-10-18 10:26:57 -07002545 return LinkProbeResult(is_success=is_success,
2546 stdout=stdout,
2547 elapsed_time=elapsed_time,
2548 failure_reason=failure_reason)
David Sue4cd9c22019-03-26 18:07:26 -07002549
2550
2551def send_link_probes(ad, num_probes, delay_sec):
2552 """Sends a sequence of link probes to the currently connected AP, and
2553 returns whether the probes succeeded or not.
2554
2555 Args:
2556 ad: android device object
2557 num_probes: number of probes to perform
2558 delay_sec: delay time between probes, in seconds
2559 Returns:
2560 List[LinkProbeResult] one LinkProbeResults for each probe
2561 """
2562 logging.info('Sending link probes')
2563 results = []
2564 for _ in range(num_probes):
2565 # send_link_probe() will also fail the test if it sees an exception
2566 # in the stdout of the adb shell command
2567 result = send_link_probe(ad)
2568 logging.info('link probe results: ' + str(result))
2569 results.append(result)
2570 time.sleep(delay_sec)
2571
2572 return results
2573
2574
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002575def ap_setup(test, index, ap, network, bandwidth=80, channel=6):
Omar El Ayach8c017902020-10-18 10:26:57 -07002576 """Set up the AP with provided network info.
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002577
2578 Args:
2579 test: the calling test class object.
2580 index: int, index of the AP.
2581 ap: access_point object of the AP.
2582 network: dict with information of the network, including ssid,
2583 password and bssid.
2584 bandwidth: the operation bandwidth for the AP, default 80MHz.
2585 channel: the channel number for the AP.
2586 Returns:
2587 brconfigs: the bridge interface configs
2588 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002589 bss_settings = []
2590 ssid = network[WifiEnums.SSID_KEY]
2591 test.access_points[index].close()
2592 time.sleep(5)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002593
Omar El Ayach8c017902020-10-18 10:26:57 -07002594 # Configure AP as required.
2595 if "password" in network.keys():
2596 password = network["password"]
2597 security = hostapd_security.Security(security_mode="wpa",
2598 password=password)
2599 else:
2600 security = hostapd_security.Security(security_mode=None, password=None)
2601 config = hostapd_ap_preset.create_ap_preset(channel=channel,
2602 ssid=ssid,
2603 security=security,
2604 bss_settings=bss_settings,
2605 vht_bandwidth=bandwidth,
2606 profile_name='whirlwind',
2607 iface_wlan_2g=ap.wlan_2g,
2608 iface_wlan_5g=ap.wlan_5g)
2609 ap.start_ap(config)
2610 logging.info("AP started on channel {} with SSID {}".format(channel, ssid))
Bindu Mahadevff295782019-02-08 16:17:48 -08002611
2612
2613def turn_ap_off(test, AP):
2614 """Bring down hostapd on the Access Point.
2615 Args:
2616 test: The test class object.
2617 AP: int, indicating which AP to turn OFF.
2618 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002619 hostapd_2g = test.access_points[AP - 1]._aps['wlan0'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002620 if hostapd_2g.is_alive():
2621 hostapd_2g.stop()
2622 logging.debug('Turned WLAN0 AP%d off' % AP)
Omar El Ayach8c017902020-10-18 10:26:57 -07002623 hostapd_5g = test.access_points[AP - 1]._aps['wlan1'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002624 if hostapd_5g.is_alive():
2625 hostapd_5g.stop()
2626 logging.debug('Turned WLAN1 AP%d off' % AP)
2627
2628
2629def turn_ap_on(test, AP):
2630 """Bring up hostapd on the Access Point.
2631 Args:
2632 test: The test class object.
2633 AP: int, indicating which AP to turn ON.
2634 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002635 hostapd_2g = test.access_points[AP - 1]._aps['wlan0'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002636 if not hostapd_2g.is_alive():
2637 hostapd_2g.start(hostapd_2g.config)
2638 logging.debug('Turned WLAN0 AP%d on' % AP)
Omar El Ayach8c017902020-10-18 10:26:57 -07002639 hostapd_5g = test.access_points[AP - 1]._aps['wlan1'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002640 if not hostapd_5g.is_alive():
2641 hostapd_5g.start(hostapd_5g.config)
2642 logging.debug('Turned WLAN1 AP%d on' % AP)
Joe Brennan48c3f692019-04-11 08:30:16 -07002643
2644
2645def turn_location_off_and_scan_toggle_off(ad):
2646 """Turns off wifi location scans."""
2647 utils.set_location_service(ad, False)
2648 ad.droid.wifiScannerToggleAlwaysAvailable(False)
2649 msg = "Failed to turn off location service's scan."
2650 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
Alfie Chen675be872020-06-04 10:48:14 +08002651
2652
2653def set_softap_channel(dut, ap_iface='wlan1', cs_count=10, channel=2462):
2654 """ Set SoftAP mode channel
2655
2656 Args:
2657 dut: android device object
2658 ap_iface: interface of SoftAP mode.
2659 cs_count: how many beacon frames before switch channel, default = 10
2660 channel: a wifi channel.
2661 """
2662 chan_switch_cmd = 'hostapd_cli -i {} chan_switch {} {}'
Omar El Ayach8c017902020-10-18 10:26:57 -07002663 chan_switch_cmd_show = chan_switch_cmd.format(ap_iface, cs_count, channel)
Alfie Chen675be872020-06-04 10:48:14 +08002664 dut.log.info('adb shell {}'.format(chan_switch_cmd_show))
Omar El Ayach8c017902020-10-18 10:26:57 -07002665 chan_switch_result = dut.adb.shell(
2666 chan_switch_cmd.format(ap_iface, cs_count, channel))
Alfie Chen675be872020-06-04 10:48:14 +08002667 if chan_switch_result == 'OK':
2668 dut.log.info('switch hotspot channel to {}'.format(channel))
2669 return chan_switch_result
2670
2671 asserts.fail("Failed to switch hotspot channel")