blob: 9da78ca49158feb3af6a1b4bb576e83b8f489f71 [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,
1609 num_of_tries=3,
1610 assert_on_fail=True):
Roshan Piusc999e5e2018-11-09 10:59:52 -08001611 """Connect an Android device to a wifi network using network request.
1612
1613 Trigger a network request with the provided network specifier,
1614 wait for the "onMatch" event, ensure that the scan results in "onMatch"
1615 event contain the specified network, then simulate the user granting the
1616 request with the specified network selected. Then wait for the "onAvailable"
1617 network callback indicating successful connection to network.
1618
1619 This will directly fail a test if anything goes wrong.
1620
1621 Args:
1622 ad: android_device object to initiate connection on.
1623 network_specifier: A dictionary representing the network specifier to
1624 use.
1625 network: A dictionary representing the network to connect to. The
1626 dictionary must have the key "SSID".
1627 num_of_tries: An integer that is the number of times to try before
1628 delaring failure.
1629 assert_on_fail: If True, error checks in this function will raise test
1630 failure signals.
1631
1632 Returns:
1633 Returns a value only if assert_on_fail is false.
1634 Returns True if the connection was successful, False otherwise.
1635 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001636 _assert_on_fail_handler(_wifi_connect_using_network_request,
1637 assert_on_fail, ad, network, network_specifier,
1638 num_of_tries)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001639
1640
Omar El Ayach8c017902020-10-18 10:26:57 -07001641def _wifi_connect_using_network_request(ad,
1642 network,
1643 network_specifier,
Roshan Piusc999e5e2018-11-09 10:59:52 -08001644 num_of_tries=3):
1645 """Connect an Android device to a wifi network using network request.
1646
1647 Trigger a network request with the provided network specifier,
1648 wait for the "onMatch" event, ensure that the scan results in "onMatch"
1649 event contain the specified network, then simulate the user granting the
1650 request with the specified network selected. Then wait for the "onAvailable"
1651 network callback indicating successful connection to network.
1652
1653 Args:
1654 ad: android_device object to initiate connection on.
1655 network_specifier: A dictionary representing the network specifier to
1656 use.
1657 network: A dictionary representing the network to connect to. The
1658 dictionary must have the key "SSID".
1659 num_of_tries: An integer that is the number of times to try before
1660 delaring failure.
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001661 Returns:
1662 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001663 """
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001664 key = ad.droid.connectivityRequestWifiNetwork(network_specifier, 0)
1665 ad.log.info("Sent network request %s with %s " % (key, network_specifier))
Roshan Piusc999e5e2018-11-09 10:59:52 -08001666 # Need a delay here because UI interaction should only start once wifi
1667 # starts processing the request.
1668 time.sleep(wifi_constants.NETWORK_REQUEST_CB_REGISTER_DELAY_SEC)
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001669 _wait_for_wifi_connect_after_network_request(ad, network, key, num_of_tries)
1670 return key
Roshan Piusc999e5e2018-11-09 10:59:52 -08001671
1672
Omar El Ayach8c017902020-10-18 10:26:57 -07001673def wait_for_wifi_connect_after_network_request(ad,
1674 network,
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001675 key,
Omar El Ayach8c017902020-10-18 10:26:57 -07001676 num_of_tries=3,
Roshan Piusc999e5e2018-11-09 10:59:52 -08001677 assert_on_fail=True):
1678 """
1679 Simulate and verify the connection flow after initiating the network
1680 request.
1681
1682 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1683 event contain the specified network, then simulate the user granting the
1684 request with the specified network selected. Then wait for the "onAvailable"
1685 network callback indicating successful connection to network.
1686
1687 Args:
1688 ad: android_device object to initiate connection on.
1689 network: A dictionary representing the network to connect to. The
1690 dictionary must have the key "SSID".
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001691 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001692 num_of_tries: An integer that is the number of times to try before
1693 delaring failure.
1694 assert_on_fail: If True, error checks in this function will raise test
1695 failure signals.
1696
1697 Returns:
1698 Returns a value only if assert_on_fail is false.
1699 Returns True if the connection was successful, False otherwise.
1700 """
1701 _assert_on_fail_handler(_wait_for_wifi_connect_after_network_request,
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001702 assert_on_fail, ad, network, key, num_of_tries)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001703
1704
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001705def _wait_for_wifi_connect_after_network_request(ad, network, key, num_of_tries=3):
Roshan Piusc999e5e2018-11-09 10:59:52 -08001706 """
1707 Simulate and verify the connection flow after initiating the network
1708 request.
1709
1710 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1711 event contain the specified network, then simulate the user granting the
1712 request with the specified network selected. Then wait for the "onAvailable"
1713 network callback indicating successful connection to network.
1714
1715 Args:
1716 ad: android_device object to initiate connection on.
1717 network: A dictionary representing the network to connect to. The
1718 dictionary must have the key "SSID".
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001719 key: Key corresponding to network request.
Roshan Piusc999e5e2018-11-09 10:59:52 -08001720 num_of_tries: An integer that is the number of times to try before
1721 delaring failure.
1722 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001723 asserts.assert_true(
1724 WifiEnums.SSID_KEY in network,
1725 "Key '%s' must be present in network definition." % WifiEnums.SSID_KEY)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001726 ad.droid.wifiStartTrackingStateChange()
1727 expected_ssid = network[WifiEnums.SSID_KEY]
1728 ad.droid.wifiRegisterNetworkRequestMatchCallback()
1729 # Wait for the platform to scan and return a list of networks
1730 # matching the request
1731 try:
1732 matched_network = None
Omar El Ayach8c017902020-10-18 10:26:57 -07001733 for _ in [0, num_of_tries]:
Roshan Piusc999e5e2018-11-09 10:59:52 -08001734 on_match_event = ad.ed.pop_event(
1735 wifi_constants.WIFI_NETWORK_REQUEST_MATCH_CB_ON_MATCH, 60)
1736 asserts.assert_true(on_match_event,
1737 "Network request on match not received.")
1738 matched_scan_results = on_match_event["data"]
1739 ad.log.debug("Network request on match results %s",
1740 matched_scan_results)
1741 matched_network = match_networks(
1742 {WifiEnums.SSID_KEY: network[WifiEnums.SSID_KEY]},
1743 matched_scan_results)
1744 if matched_network:
Omar El Ayach8c017902020-10-18 10:26:57 -07001745 break
Roshan Piusc999e5e2018-11-09 10:59:52 -08001746
Omar El Ayach8c017902020-10-18 10:26:57 -07001747 asserts.assert_true(matched_network,
1748 "Target network %s not found" % network)
Roshan Piusc999e5e2018-11-09 10:59:52 -08001749
1750 ad.droid.wifiSendUserSelectionForNetworkRequestMatch(network)
1751 ad.log.info("Sent user selection for network request %s",
1752 expected_ssid)
1753
1754 # Wait for the platform to connect to the network.
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001755 autils.wait_for_event_with_keys(
1756 ad, cconsts.EVENT_NETWORK_CALLBACK,
1757 60,
1758 (cconsts.NETWORK_CB_KEY_ID, key),
1759 (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_AVAILABLE))
1760 on_capabilities_changed = autils.wait_for_event_with_keys(
1761 ad, cconsts.EVENT_NETWORK_CALLBACK,
1762 10,
1763 (cconsts.NETWORK_CB_KEY_ID, key),
1764 (cconsts.NETWORK_CB_KEY_EVENT,
1765 cconsts.NETWORK_CB_CAPABILITIES_CHANGED))
1766 connected_network =\
1767 on_capabilities_changed["data"][cconsts.NETWORK_CB_KEY_TRANSPORT_INFO]
Roshan Piusc999e5e2018-11-09 10:59:52 -08001768 ad.log.info("Connected to network %s", connected_network)
Omar El Ayach8c017902020-10-18 10:26:57 -07001769 asserts.assert_equal(
1770 connected_network[WifiEnums.SSID_KEY], expected_ssid,
1771 "Connected to the wrong network."
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001772 "Expected %s, but got %s."
1773 % (network, connected_network))
Roshan Piusc999e5e2018-11-09 10:59:52 -08001774 except Empty:
1775 asserts.fail("Failed to connect to %s" % expected_ssid)
1776 except Exception as error:
Roshan Pius5fd42eb2021-01-21 12:26:31 -08001777 ad.log.error("Failed to connect to %s with error %s" %
Roshan Piusc999e5e2018-11-09 10:59:52 -08001778 (expected_ssid, error))
1779 raise signals.TestFailure("Failed to connect to %s network" % network)
1780 finally:
1781 ad.droid.wifiStopTrackingStateChange()
1782
1783
Omar El Ayach8c017902020-10-18 10:26:57 -07001784def wifi_passpoint_connect(ad,
1785 passpoint_network,
1786 num_of_tries=1,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001787 assert_on_fail=True):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001788 """Connect an Android device to a wifi network.
1789
1790 Initiate connection to a wifi network, wait for the "connected" event, then
1791 confirm the connected ssid is the one requested.
1792
1793 This will directly fail a test if anything goes wrong.
1794
1795 Args:
1796 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001797 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001798 num_of_tries: An integer that is the number of times to try before
1799 delaring failure. Default is 1.
1800 assert_on_fail: If True, error checks in this function will raise test
1801 failure signals.
1802
1803 Returns:
1804 If assert_on_fail is False, function returns network id, if the connect was
1805 successful, False otherwise. If assert_on_fail is True, no return value.
1806 """
Omar El Ayach8c017902020-10-18 10:26:57 -07001807 _assert_on_fail_handler(_wifi_passpoint_connect,
1808 assert_on_fail,
1809 ad,
1810 passpoint_network,
1811 num_of_tries=num_of_tries)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001812
1813
Oscar Shucb9af9b2019-05-02 20:01:49 +00001814def _wifi_passpoint_connect(ad, passpoint_network, num_of_tries=1):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001815 """Connect an Android device to a wifi network.
1816
1817 Initiate connection to a wifi network, wait for the "connected" event, then
1818 confirm the connected ssid is the one requested.
1819
1820 This will directly fail a test if anything goes wrong.
1821
1822 Args:
1823 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001824 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001825 num_of_tries: An integer that is the number of times to try before
1826 delaring failure. Default is 1.
1827 """
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001828 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001829 expected_ssid = passpoint_network
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001830 ad.log.info("Starting connection process to passpoint %s", expected_ssid)
1831
1832 try:
Omar El Ayach8c017902020-10-18 10:26:57 -07001833 connect_result = _wait_for_connect_event(ad, expected_ssid,
1834 num_of_tries)
1835 asserts.assert_true(
1836 connect_result, "Failed to connect to WiFi passpoint network %s on"
1837 " %s" % (expected_ssid, ad.serial))
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001838 ad.log.info("Wi-Fi connection result: %s.", connect_result)
1839 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07001840 asserts.assert_equal(
1841 actual_ssid, expected_ssid,
1842 "Connected to the wrong network on %s." % ad.serial)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001843 ad.log.info("Connected to Wi-Fi passpoint network %s.", actual_ssid)
1844
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001845 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1846 if not internet:
1847 raise signals.TestFailure("Failed to connect to internet on %s" %
1848 expected_ssid)
1849 except Exception as error:
1850 ad.log.error("Failed to connect to passpoint network %s with error %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07001851 expected_ssid, error)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001852 raise signals.TestFailure("Failed to connect to %s passpoint network" %
Omar El Ayach8c017902020-10-18 10:26:57 -07001853 expected_ssid)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001854
1855 finally:
1856 ad.droid.wifiStopTrackingStateChange()
1857
1858
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001859def delete_passpoint(ad, fqdn):
1860 """Delete a required Passpoint configuration."""
1861 try:
1862 ad.droid.removePasspointConfig(fqdn)
1863 return True
1864 except Exception as error:
Omar El Ayach8c017902020-10-18 10:26:57 -07001865 ad.log.error(
1866 "Failed to remove passpoint configuration with FQDN=%s "
1867 "and error=%s", fqdn, error)
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001868 return False
1869
1870
Ang Li73697b32015-12-03 00:41:53 +00001871def start_wifi_single_scan(ad, scan_setting):
1872 """Starts wifi single shot scan.
1873
1874 Args:
1875 ad: android_device object to initiate connection on.
1876 scan_setting: A dict representing the settings of the scan.
1877
1878 Returns:
1879 If scan was started successfully, event data of success event is returned.
1880 """
Ang Li82522812016-06-02 13:57:21 -07001881 idx = ad.droid.wifiScannerStartScan(scan_setting)
1882 event = ad.ed.pop_event("WifiScannerScan%sonSuccess" % idx, SHORT_TIMEOUT)
Ang Li31b00782016-06-21 13:04:23 -07001883 ad.log.debug("Got event %s", event)
Ang Li73697b32015-12-03 00:41:53 +00001884 return event['data']
1885
Ang Li82522812016-06-02 13:57:21 -07001886
Ang Li73697b32015-12-03 00:41:53 +00001887def track_connection(ad, network_ssid, check_connection_count):
1888 """Track wifi connection to network changes for given number of counts
1889
1890 Args:
1891 ad: android_device object for forget network.
1892 network_ssid: network ssid to which connection would be tracked
1893 check_connection_count: Integer for maximum number network connection
Ang Li82522812016-06-02 13:57:21 -07001894 check.
Ang Li73697b32015-12-03 00:41:53 +00001895 Returns:
Ang Li73697b32015-12-03 00:41:53 +00001896 True if connection to given network happen, else return False.
1897 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001898 ad.droid.wifiStartTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001899 while check_connection_count > 0:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001900 connect_network = ad.ed.pop_event("WifiNetworkConnected", 120)
Ang Li31b00782016-06-21 13:04:23 -07001901 ad.log.info("Connected to network %s", connect_network)
Ang Li82522812016-06-02 13:57:21 -07001902 if (WifiEnums.SSID_KEY in connect_network['data'] and
1903 connect_network['data'][WifiEnums.SSID_KEY] == network_ssid):
1904 return True
Ang Li8e767182015-12-09 17:29:24 -08001905 check_connection_count -= 1
Girish Moturu40d7dc22016-11-02 12:14:56 -07001906 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001907 return False
1908
Ang Li82522812016-06-02 13:57:21 -07001909
Ang Li73697b32015-12-03 00:41:53 +00001910def get_scan_time_and_channels(wifi_chs, scan_setting, stime_channel):
1911 """Calculate the scan time required based on the band or channels in scan
1912 setting
1913
1914 Args:
1915 wifi_chs: Object of channels supported
1916 scan_setting: scan setting used for start scan
1917 stime_channel: scan time per channel
1918
1919 Returns:
1920 scan_time: time required for completing a scan
1921 scan_channels: channel used for scanning
1922 """
1923 scan_time = 0
1924 scan_channels = []
1925 if "band" in scan_setting and "channels" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001926 scan_channels = wifi_chs.band_to_freq(scan_setting["band"])
Ang Li73697b32015-12-03 00:41:53 +00001927 elif "channels" in scan_setting and "band" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001928 scan_channels = scan_setting["channels"]
Ang Li73697b32015-12-03 00:41:53 +00001929 scan_time = len(scan_channels) * stime_channel
1930 for channel in scan_channels:
Ang Li8e767182015-12-09 17:29:24 -08001931 if channel in WifiEnums.DFS_5G_FREQUENCIES:
Ang Li82522812016-06-02 13:57:21 -07001932 scan_time += 132 #passive scan time on DFS
Ang Li73697b32015-12-03 00:41:53 +00001933 return scan_time, scan_channels
1934
Ang Li82522812016-06-02 13:57:21 -07001935
Ang Li73697b32015-12-03 00:41:53 +00001936def start_wifi_track_bssid(ad, track_setting):
1937 """Start tracking Bssid for the given settings.
1938
1939 Args:
1940 ad: android_device object.
1941 track_setting: Setting for which the bssid tracking should be started
1942
1943 Returns:
1944 If tracking started successfully, event data of success event is returned.
1945 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001946 idx = ad.droid.wifiScannerStartTrackingBssids(
Ang Li82522812016-06-02 13:57:21 -07001947 track_setting["bssidInfos"], track_setting["apLostThreshold"])
Girish Moturu40d7dc22016-11-02 12:14:56 -07001948 event = ad.ed.pop_event("WifiScannerBssid{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -08001949 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +00001950 return event['data']
1951
Ang Li82522812016-06-02 13:57:21 -07001952
Ang Li73697b32015-12-03 00:41:53 +00001953def convert_pem_key_to_pkcs8(in_file, out_file):
1954 """Converts the key file generated by us to the format required by
1955 Android using openssl.
1956
1957 The input file must have the extension "pem". The output file must
1958 have the extension "der".
1959
1960 Args:
1961 in_file: The original key file.
1962 out_file: The full path to the converted key file, including
1963 filename.
1964 """
Ang Li82522812016-06-02 13:57:21 -07001965 asserts.assert_true(in_file.endswith(".pem"), "Input file has to be .pem.")
Omar El Ayach8c017902020-10-18 10:26:57 -07001966 asserts.assert_true(out_file.endswith(".der"),
1967 "Output file has to be .der.")
Ang Li73697b32015-12-03 00:41:53 +00001968 cmd = ("openssl pkcs8 -inform PEM -in {} -outform DER -out {} -nocrypt"
1969 " -topk8").format(in_file, out_file)
Ang Lifee28402016-07-13 13:43:29 -07001970 utils.exe_cmd(cmd)
Ang Li73697b32015-12-03 00:41:53 +00001971
Ang Li82522812016-06-02 13:57:21 -07001972
Omar El Ayach8c017902020-10-18 10:26:57 -07001973def validate_connection(ad,
1974 ping_addr=DEFAULT_PING_ADDR,
1975 wait_time=15,
Girish Moturu804a3492020-02-17 14:32:02 -08001976 ping_gateway=True):
Ang Li73697b32015-12-03 00:41:53 +00001977 """Validate internet connection by pinging the address provided.
1978
1979 Args:
1980 ad: android_device object.
1981 ping_addr: address on internet for pinging.
Girish Moturua2a5bf22019-08-16 09:52:29 -07001982 wait_time: wait for some time before validating connection
Ang Li73697b32015-12-03 00:41:53 +00001983
1984 Returns:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001985 ping output if successful, NULL otherwise.
Ang Li73697b32015-12-03 00:41:53 +00001986 """
Girish Moturua2a5bf22019-08-16 09:52:29 -07001987 # wait_time to allow for DHCP to complete.
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08001988 for i in range(wait_time):
Girish Moturuacf35002020-11-09 23:37:35 -08001989 if ad.droid.connectivityNetworkIsConnected(
Omar El Ayach8c017902020-10-18 10:26:57 -07001990 ) and ad.droid.connectivityGetIPv4DefaultGateway():
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08001991 break
1992 time.sleep(1)
Girish Moturu804a3492020-02-17 14:32:02 -08001993 ping = False
1994 try:
1995 ping = ad.droid.httpPing(ping_addr)
1996 ad.log.info("Http ping result: %s.", ping)
1997 except:
1998 pass
1999 if not ping and ping_gateway:
2000 ad.log.info("Http ping failed. Pinging default gateway")
2001 gw = ad.droid.connectivityGetIPv4DefaultGateway()
2002 result = ad.adb.shell("ping -c 6 {}".format(gw))
2003 ad.log.info("Default gateway ping result: %s" % result)
2004 ping = False if "100% packet loss" in result else True
Ang Li73697b32015-12-03 00:41:53 +00002005 return ping
2006
Ang Li82522812016-06-02 13:57:21 -07002007
Ang Li73697b32015-12-03 00:41:53 +00002008#TODO(angli): This can only verify if an actual value is exactly the same.
2009# Would be nice to be able to verify an actual value is one of serveral.
2010def verify_wifi_connection_info(ad, expected_con):
2011 """Verifies that the information of the currently connected wifi network is
2012 as expected.
2013
2014 Args:
2015 expected_con: A dict representing expected key-value pairs for wifi
2016 connection. e.g. {"SSID": "test_wifi"}
2017 """
2018 current_con = ad.droid.wifiGetConnectionInfo()
Ang Li374d7602016-02-08 17:27:27 -08002019 case_insensitive = ["BSSID", "supplicant_state"]
Ang Li31b00782016-06-21 13:04:23 -07002020 ad.log.debug("Current connection: %s", current_con)
Ang Li73697b32015-12-03 00:41:53 +00002021 for k, expected_v in expected_con.items():
Ang Li9a66de72016-02-08 15:26:38 -08002022 # Do not verify authentication related fields.
2023 if k == "password":
2024 continue
Ang Li82522812016-06-02 13:57:21 -07002025 msg = "Field %s does not exist in wifi connection info %s." % (
2026 k, current_con)
Ang Li374d7602016-02-08 17:27:27 -08002027 if k not in current_con:
2028 raise signals.TestFailure(msg)
2029 actual_v = current_con[k]
2030 if k in case_insensitive:
2031 actual_v = actual_v.lower()
2032 expected_v = expected_v.lower()
Ang Li73697b32015-12-03 00:41:53 +00002033 msg = "Expected %s to be %s, actual %s is %s." % (k, expected_v, k,
Ang Li82522812016-06-02 13:57:21 -07002034 actual_v)
Ang Li374d7602016-02-08 17:27:27 -08002035 if actual_v != expected_v:
2036 raise signals.TestFailure(msg)
Ang Li73697b32015-12-03 00:41:53 +00002037
Ang Li82522812016-06-02 13:57:21 -07002038
Omar El Ayach8c017902020-10-18 10:26:57 -07002039def check_autoconnect_to_open_network(
2040 ad, conn_timeout=WIFI_CONNECTION_TIMEOUT_DEFAULT):
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08002041 """Connects to any open WiFI AP
2042 Args:
2043 timeout value in sec to wait for UE to connect to a WiFi AP
2044 Returns:
2045 True if UE connects to WiFi AP (supplicant_state = completed)
2046 False if UE fails to complete connection within WIFI_CONNECTION_TIMEOUT time.
2047 """
2048 if ad.droid.wifiCheckState():
2049 return True
2050 ad.droid.wifiToggleState()
2051 wifi_connection_state = None
2052 timeout = time.time() + conn_timeout
2053 while wifi_connection_state != "completed":
Omar El Ayach8c017902020-10-18 10:26:57 -07002054 wifi_connection_state = ad.droid.wifiGetConnectionInfo(
2055 )['supplicant_state']
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08002056 if time.time() > timeout:
2057 ad.log.warning("Failed to connect to WiFi AP")
2058 return False
2059 return True
2060
2061
Ang Li73697b32015-12-03 00:41:53 +00002062def expand_enterprise_config_by_phase2(config):
2063 """Take an enterprise config and generate a list of configs, each with
2064 a different phase2 auth type.
2065
2066 Args:
2067 config: A dict representing enterprise config.
2068
2069 Returns
2070 A list of enterprise configs.
2071 """
2072 results = []
Ang Li0e7e58f2016-02-22 12:15:02 -08002073 phase2_types = WifiEnums.EapPhase2
2074 if config[WifiEnums.Enterprise.EAP] == WifiEnums.Eap.PEAP:
2075 # Skip unsupported phase2 types for PEAP.
2076 phase2_types = [WifiEnums.EapPhase2.GTC, WifiEnums.EapPhase2.MSCHAPV2]
2077 for phase2_type in phase2_types:
Ang Li73697b32015-12-03 00:41:53 +00002078 # Skip a special case for passpoint TTLS.
Omar El Ayach8c017902020-10-18 10:26:57 -07002079 if (WifiEnums.Enterprise.FQDN in config
2080 and phase2_type == WifiEnums.EapPhase2.GTC):
Ang Li73697b32015-12-03 00:41:53 +00002081 continue
2082 c = dict(config)
Girish Moturu150d32f2017-02-14 12:27:07 -08002083 c[WifiEnums.Enterprise.PHASE2] = phase2_type.value
Ang Li73697b32015-12-03 00:41:53 +00002084 results.append(c)
2085 return results
Ang Li2d3fe982016-06-08 10:00:43 -07002086
2087
Girish Moturub48a13c2017-02-27 11:36:42 -08002088def generate_eap_test_name(config, ad=None):
Girish Moturu150d32f2017-02-14 12:27:07 -08002089 """ Generates a test case name based on an EAP configuration.
2090
2091 Args:
2092 config: A dict representing an EAP credential.
Girish Moturub48a13c2017-02-27 11:36:42 -08002093 ad object: Redundant but required as the same param is passed
2094 to test_func in run_generated_tests
Girish Moturu150d32f2017-02-14 12:27:07 -08002095
2096 Returns:
2097 A string representing the name of a generated EAP test case.
2098 """
2099 eap = WifiEnums.Eap
2100 eap_phase2 = WifiEnums.EapPhase2
Girish Moturub48a13c2017-02-27 11:36:42 -08002101 Ent = WifiEnums.Enterprise
Girish Moturu150d32f2017-02-14 12:27:07 -08002102 name = "test_connect-"
2103 eap_name = ""
2104 for e in eap:
2105 if e.value == config[Ent.EAP]:
2106 eap_name = e.name
2107 break
2108 if "peap0" in config[WifiEnums.SSID_KEY].lower():
2109 eap_name = "PEAP0"
2110 if "peap1" in config[WifiEnums.SSID_KEY].lower():
2111 eap_name = "PEAP1"
2112 name += eap_name
2113 if Ent.PHASE2 in config:
2114 for e in eap_phase2:
2115 if e.value == config[Ent.PHASE2]:
2116 name += "-{}".format(e.name)
2117 break
2118 return name
2119
2120
Ang Li2d3fe982016-06-08 10:00:43 -07002121def group_attenuators(attenuators):
2122 """Groups a list of attenuators into attenuator groups for backward
2123 compatibility reasons.
2124
2125 Most legacy Wi-Fi setups have two attenuators each connected to a separate
2126 AP. The new Wi-Fi setup has four attenuators, each connected to one channel
2127 on an AP, so two of them are connected to one AP.
2128
2129 To make the existing scripts work in the new setup, when the script needs
2130 to attenuate one AP, it needs to set attenuation on both attenuators
2131 connected to the same AP.
2132
2133 This function groups attenuators properly so the scripts work in both
2134 legacy and new Wi-Fi setups.
2135
2136 Args:
2137 attenuators: A list of attenuator objects, either two or four in length.
2138
2139 Raises:
2140 signals.TestFailure is raised if the attenuator list does not have two
2141 or four objects.
2142 """
2143 attn0 = attenuator.AttenuatorGroup("AP0")
2144 attn1 = attenuator.AttenuatorGroup("AP1")
2145 # Legacy testbed setup has two attenuation channels.
2146 num_of_attns = len(attenuators)
2147 if num_of_attns == 2:
2148 attn0.add(attenuators[0])
2149 attn1.add(attenuators[1])
2150 elif num_of_attns == 4:
2151 attn0.add(attenuators[0])
2152 attn0.add(attenuators[1])
2153 attn1.add(attenuators[2])
2154 attn1.add(attenuators[3])
2155 else:
2156 asserts.fail(("Either two or four attenuators are required for this "
2157 "test, but found %s") % num_of_attns)
2158 return [attn0, attn1]
Jong Wook Kim92356922018-02-06 18:32:49 -08002159
Bindu Mahadevff295782019-02-08 16:17:48 -08002160
Girish Moturu36348a32019-12-10 08:41:54 -08002161def set_attns(attenuator, attn_val_name, roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002162 """Sets attenuation values on attenuators used in this test.
2163
2164 Args:
2165 attenuator: The attenuator object.
2166 attn_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002167 roaming_attn: Dictionary specifying the attenuation params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002168 """
2169 logging.info("Set attenuation values to %s", roaming_attn[attn_val_name])
2170 try:
2171 attenuator[0].set_atten(roaming_attn[attn_val_name][0])
2172 attenuator[1].set_atten(roaming_attn[attn_val_name][1])
2173 attenuator[2].set_atten(roaming_attn[attn_val_name][2])
2174 attenuator[3].set_atten(roaming_attn[attn_val_name][3])
2175 except:
2176 logging.exception("Failed to set attenuation values %s.",
Omar El Ayach8c017902020-10-18 10:26:57 -07002177 attn_val_name)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002178 raise
2179
Omar El Ayach8c017902020-10-18 10:26:57 -07002180
Girish Moturu36348a32019-12-10 08:41:54 -08002181def set_attns_steps(attenuators,
2182 atten_val_name,
2183 roaming_attn=ROAMING_ATTN,
2184 steps=10,
2185 wait_time=12):
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002186 """Set attenuation values on attenuators used in this test. It will change
2187 the attenuation values linearly from current value to target value step by
2188 step.
2189
2190 Args:
2191 attenuators: The list of attenuator objects that you want to change
2192 their attenuation value.
2193 atten_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002194 roaming_attn: Dictionary specifying the attenuation params.
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002195 steps: Number of attenuator changes to reach the target value.
2196 wait_time: Sleep time for each change of attenuator.
2197 """
2198 logging.info("Set attenuation values to %s in %d step(s)",
Omar El Ayach8c017902020-10-18 10:26:57 -07002199 roaming_attn[atten_val_name], steps)
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002200 start_atten = [attenuator.get_atten() for attenuator in attenuators]
2201 target_atten = roaming_attn[atten_val_name]
2202 for current_step in range(steps):
2203 progress = (current_step + 1) / steps
2204 for i, attenuator in enumerate(attenuators):
2205 amount_since_start = (target_atten[i] - start_atten[i]) * progress
2206 attenuator.set_atten(round(start_atten[i] + amount_since_start))
2207 time.sleep(wait_time)
2208
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002209
Girish Moturu36348a32019-12-10 08:41:54 -08002210def trigger_roaming_and_validate(dut,
2211 attenuator,
2212 attn_val_name,
2213 expected_con,
2214 roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002215 """Sets attenuators to trigger roaming and validate the DUT connected
2216 to the BSSID expected.
2217
2218 Args:
2219 attenuator: The attenuator object.
2220 attn_val_name: Name of the attenuation value pair to use.
2221 expected_con: The network information of the expected network.
Girish Moturu36348a32019-12-10 08:41:54 -08002222 roaming_attn: Dictionary specifying the attenaution params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002223 """
2224 expected_con = {
2225 WifiEnums.SSID_KEY: expected_con[WifiEnums.SSID_KEY],
2226 WifiEnums.BSSID_KEY: expected_con["bssid"],
2227 }
Girish Moturu36348a32019-12-10 08:41:54 -08002228 set_attns_steps(attenuator, attn_val_name, roaming_attn)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002229
Hsiu-Chang Chenef856402018-09-18 12:32:49 +08002230 verify_wifi_connection_info(dut, expected_con)
2231 expected_bssid = expected_con[WifiEnums.BSSID_KEY]
2232 logging.info("Roamed to %s successfully", expected_bssid)
2233 if not validate_connection(dut):
2234 raise signals.TestFailure("Fail to connect to internet on %s" %
Omar El Ayach8c017902020-10-18 10:26:57 -07002235 expected_bssid)
2236
Jong Wook Kim92356922018-02-06 18:32:49 -08002237
2238def create_softap_config():
2239 """Create a softap config with random ssid and password."""
2240 ap_ssid = "softap_" + utils.rand_ascii_str(8)
2241 ap_password = utils.rand_ascii_str(8)
2242 logging.info("softap setup: %s %s", ap_ssid, ap_password)
2243 config = {
2244 WifiEnums.SSID_KEY: ap_ssid,
2245 WifiEnums.PWD_KEY: ap_password,
2246 }
2247 return config
Girish Moturucf4dccd2018-08-27 12:22:00 -07002248
Omar El Ayach8c017902020-10-18 10:26:57 -07002249
Bindu Mahadevff295782019-02-08 16:17:48 -08002250def start_softap_and_verify(ad, band):
2251 """Bring-up softap and verify AP mode and in scan results.
2252
2253 Args:
2254 band: The band to use for softAP.
2255
2256 Returns: dict, the softAP config.
2257
2258 """
lesl2f0fb232019-11-05 16:35:28 +08002259 # Register before start the test.
2260 callbackId = ad.dut.droid.registerSoftApCallback()
2261 # Check softap info value is default
2262 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2263 asserts.assert_true(frequency == 0, "Softap frequency is not reset")
2264 asserts.assert_true(bandwdith == 0, "Softap bandwdith is not reset")
2265
Bindu Mahadevff295782019-02-08 16:17:48 -08002266 config = create_softap_config()
2267 start_wifi_tethering(ad.dut,
2268 config[WifiEnums.SSID_KEY],
Omar El Ayach8c017902020-10-18 10:26:57 -07002269 config[WifiEnums.PWD_KEY],
2270 band=band)
Bindu Mahadevff295782019-02-08 16:17:48 -08002271 asserts.assert_true(ad.dut.droid.wifiIsApEnabled(),
Omar El Ayach8c017902020-10-18 10:26:57 -07002272 "SoftAp is not reported as running")
2273 start_wifi_connection_scan_and_ensure_network_found(
2274 ad.dut_client, config[WifiEnums.SSID_KEY])
lesl2f0fb232019-11-05 16:35:28 +08002275
2276 # Check softap info can get from callback succeed and assert value should be
2277 # valid.
2278 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2279 asserts.assert_true(frequency > 0, "Softap frequency is not valid")
2280 asserts.assert_true(bandwdith > 0, "Softap bandwdith is not valid")
2281 # Unregister callback
2282 ad.dut.droid.unregisterSoftApCallback(callbackId)
2283
Bindu Mahadevff295782019-02-08 16:17:48 -08002284 return config
2285
Omar El Ayach8c017902020-10-18 10:26:57 -07002286
lesle8e3c0a2019-02-22 17:06:04 +08002287def wait_for_expected_number_of_softap_clients(ad, callbackId,
Omar El Ayach8c017902020-10-18 10:26:57 -07002288 expected_num_of_softap_clients):
lesle8e3c0a2019-02-22 17:06:04 +08002289 """Wait for the number of softap clients to be updated as expected.
2290 Args:
2291 callbackId: Id of the callback associated with registering.
2292 expected_num_of_softap_clients: expected number of softap clients.
2293 """
2294 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002295 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
James Mattis5a5dd492020-05-14 13:09:43 -07002296 clientData = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data']
2297 clientCount = clientData[wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
Omar El Ayach8c017902020-10-18 10:26:57 -07002298 clientMacAddresses = clientData[
2299 wifi_constants.SOFTAP_CLIENTS_MACS_CALLBACK_KEY]
2300 asserts.assert_equal(
2301 clientCount, expected_num_of_softap_clients,
2302 "The number of softap clients doesn't match the expected number")
2303 asserts.assert_equal(
2304 len(clientMacAddresses), expected_num_of_softap_clients,
2305 "The number of mac addresses doesn't match the expected number")
James Mattis5a5dd492020-05-14 13:09:43 -07002306 for macAddress in clientMacAddresses:
Omar El Ayach8c017902020-10-18 10:26:57 -07002307 asserts.assert_true(checkMacAddress(macAddress),
2308 "An invalid mac address was returned")
2309
James Mattis5a5dd492020-05-14 13:09:43 -07002310
2311def checkMacAddress(input):
2312 """Validate whether a string is a valid mac address or not.
2313
2314 Args:
2315 input: The string to validate.
2316
2317 Returns: True/False, returns true for a valid mac address and false otherwise.
2318 """
2319 macValidationRegex = "[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$"
2320 if re.match(macValidationRegex, input.lower()):
2321 return True
2322 return False
lesle8e3c0a2019-02-22 17:06:04 +08002323
Omar El Ayach8c017902020-10-18 10:26:57 -07002324
lesle8e3c0a2019-02-22 17:06:04 +08002325def wait_for_expected_softap_state(ad, callbackId, expected_softap_state):
2326 """Wait for the expected softap state change.
2327 Args:
2328 callbackId: Id of the callback associated with registering.
2329 expected_softap_state: The expected softap state.
2330 """
2331 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002332 callbackId) + wifi_constants.SOFTAP_STATE_CHANGED
2333 asserts.assert_equal(
2334 ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data'][
2335 wifi_constants.SOFTAP_STATE_CHANGE_CALLBACK_KEY],
2336 expected_softap_state,
2337 "Softap state doesn't match with expected state")
2338
lesle8e3c0a2019-02-22 17:06:04 +08002339
2340def get_current_number_of_softap_clients(ad, callbackId):
2341 """pop up all of softap client updated event from queue.
2342 Args:
2343 callbackId: Id of the callback associated with registering.
2344
2345 Returns:
2346 If exist aleast callback, returns last updated number_of_softap_clients.
2347 Returns None when no any match callback event in queue.
2348 """
2349 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002350 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
lesle8e3c0a2019-02-22 17:06:04 +08002351 events = ad.ed.pop_all(eventStr)
2352 for event in events:
Omar El Ayach8c017902020-10-18 10:26:57 -07002353 num_of_clients = event['data'][
2354 wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
lesle8e3c0a2019-02-22 17:06:04 +08002355 if len(events) == 0:
2356 return None
2357 return num_of_clients
Bindu Mahadevff295782019-02-08 16:17:48 -08002358
Omar El Ayach8c017902020-10-18 10:26:57 -07002359
lesl2f0fb232019-11-05 16:35:28 +08002360def get_current_softap_info(ad, callbackId, least_one):
2361 """pop up all of softap info changed event from queue.
2362 Args:
2363 callbackId: Id of the callback associated with registering.
2364 least_one: Wait for the info callback event before pop all.
2365 Returns:
2366 Returns last updated information of softap.
2367 """
2368 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
Omar El Ayach8c017902020-10-18 10:26:57 -07002369 callbackId) + wifi_constants.SOFTAP_INFO_CHANGED
2370 ad.log.info("softap info dump from eventStr %s", eventStr)
lesl2f0fb232019-11-05 16:35:28 +08002371 frequency = 0
2372 bandwidth = 0
2373 if (least_one):
2374 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
Omar El Ayach8c017902020-10-18 10:26:57 -07002375 frequency = event['data'][
2376 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2377 bandwidth = event['data'][
2378 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
lesl2f0fb232019-11-05 16:35:28 +08002379 ad.log.info("softap info updated, frequency is %s, bandwidth is %s",
Omar El Ayach8c017902020-10-18 10:26:57 -07002380 frequency, bandwidth)
lesl2f0fb232019-11-05 16:35:28 +08002381
2382 events = ad.ed.pop_all(eventStr)
2383 for event in events:
Omar El Ayach8c017902020-10-18 10:26:57 -07002384 frequency = event['data'][
2385 wifi_constants.SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2386 bandwidth = event['data'][
2387 wifi_constants.SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
2388 ad.log.info("softap info, frequency is %s, bandwidth is %s", frequency,
2389 bandwidth)
lesl2f0fb232019-11-05 16:35:28 +08002390 return frequency, bandwidth
2391
2392
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002393def get_ssrdumps(ad):
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002394 """Pulls dumps in the ssrdump dir
2395 Args:
2396 ad: android device object.
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002397 """
2398 logs = ad.get_file_names("/data/vendor/ssrdump/")
2399 if logs:
2400 ad.log.info("Pulling ssrdumps %s", logs)
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002401 log_path = os.path.join(ad.device_log_path, "SSRDUMPS_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002402 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002403 ad.pull_files(logs, log_path)
Hsiu-Chang Chen769bef12020-10-10 06:07:52 +00002404 ad.adb.shell("find /data/vendor/ssrdump/ -type f -delete",
Omar El Ayach8c017902020-10-18 10:26:57 -07002405 ignore_status=True)
2406
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002407
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002408def start_pcap(pcap, wifi_band, test_name):
Girish Moturucf4dccd2018-08-27 12:22:00 -07002409 """Start packet capture in monitor mode.
2410
2411 Args:
2412 pcap: packet capture object
2413 wifi_band: '2g' or '5g' or 'dual'
Bindu Mahadev76551c12018-12-13 19:42:14 +00002414 test_name: test name to be used for pcap file name
2415
2416 Returns:
xianyuanjia0431ba32018-12-14 09:56:42 -08002417 Dictionary with wifi band as key and the tuple
2418 (pcap Process object, log directory) as the value
Girish Moturucf4dccd2018-08-27 12:22:00 -07002419 """
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002420 log_dir = os.path.join(
Xianyuan Jia5cd06bb2019-06-10 16:29:57 -07002421 context.get_current_context().get_full_output_path(), 'PacketCapture')
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002422 os.makedirs(log_dir, exist_ok=True)
Girish Moturucf4dccd2018-08-27 12:22:00 -07002423 if wifi_band == 'dual':
2424 bands = [BAND_2G, BAND_5G]
2425 else:
2426 bands = [wifi_band]
xianyuanjia0431ba32018-12-14 09:56:42 -08002427 procs = {}
Girish Moturucf4dccd2018-08-27 12:22:00 -07002428 for band in bands:
xianyuanjia0431ba32018-12-14 09:56:42 -08002429 proc = pcap.start_packet_capture(band, log_dir, test_name)
2430 procs[band] = (proc, os.path.join(log_dir, test_name))
2431 return procs
Girish Moturucf4dccd2018-08-27 12:22:00 -07002432
Bindu Mahadevff295782019-02-08 16:17:48 -08002433
xianyuanjia0431ba32018-12-14 09:56:42 -08002434def stop_pcap(pcap, procs, test_status=None):
Bindu Mahadev76551c12018-12-13 19:42:14 +00002435 """Stop packet capture in monitor mode.
2436
2437 Since, the pcap logs in monitor mode can be very large, we will
2438 delete them if they are not required. 'test_status' if True, will delete
2439 the pcap files. If False, we will keep them.
Girish Moturucf4dccd2018-08-27 12:22:00 -07002440
2441 Args:
2442 pcap: packet capture object
xianyuanjia0431ba32018-12-14 09:56:42 -08002443 procs: dictionary returned by start_pcap
Bindu Mahadev76551c12018-12-13 19:42:14 +00002444 test_status: status of the test case
Girish Moturucf4dccd2018-08-27 12:22:00 -07002445 """
xianyuanjia0431ba32018-12-14 09:56:42 -08002446 for proc, fname in procs.values():
2447 pcap.stop_packet_capture(proc)
Bindu Mahadev76551c12018-12-13 19:42:14 +00002448
2449 if test_status:
xianyuanjia0431ba32018-12-14 09:56:42 -08002450 shutil.rmtree(os.path.dirname(fname))
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002451
Omar El Ayach8c017902020-10-18 10:26:57 -07002452
Jaineel95887fd2019-10-16 16:19:01 -07002453def verify_mac_not_found_in_pcap(ad, mac, packets):
xshuf7267682019-06-03 14:41:56 -07002454 """Verify that a mac address is not found in the captured packets.
2455
2456 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002457 ad: android device object
xshuf7267682019-06-03 14:41:56 -07002458 mac: string representation of the mac address
2459 packets: packets obtained by rdpcap(pcap_fname)
2460 """
2461 for pkt in packets:
2462 logging.debug("Packet Summary = %s", pkt.summary())
2463 if mac in pkt.summary():
Jaineel95887fd2019-10-16 16:19:01 -07002464 asserts.fail("Device %s caught Factory MAC: %s in packet sniffer."
2465 "Packet = %s" % (ad.serial, mac, pkt.show()))
Bindu Mahadevff295782019-02-08 16:17:48 -08002466
Omar El Ayach8c017902020-10-18 10:26:57 -07002467
Jaineel95887fd2019-10-16 16:19:01 -07002468def verify_mac_is_found_in_pcap(ad, mac, packets):
Nate Jiangc2c09c62019-06-05 17:26:08 -07002469 """Verify that a mac address is found in the captured packets.
2470
2471 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002472 ad: android device object
Nate Jiangc2c09c62019-06-05 17:26:08 -07002473 mac: string representation of the mac address
2474 packets: packets obtained by rdpcap(pcap_fname)
2475 """
2476 for pkt in packets:
2477 if mac in pkt.summary():
2478 return
Jaineel95887fd2019-10-16 16:19:01 -07002479 asserts.fail("Did not find MAC = %s in packet sniffer."
2480 "for device %s" % (mac, ad.serial))
Nate Jiangc2c09c62019-06-05 17:26:08 -07002481
Omar El Ayach8c017902020-10-18 10:26:57 -07002482
Girish Moturuddc0d382020-08-24 12:08:41 -07002483def start_cnss_diags(ads, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002484 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002485 start_cnss_diag(ad, cnss_diag_file, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002486
Bindu Mahadevff295782019-02-08 16:17:48 -08002487
Girish Moturuddc0d382020-08-24 12:08:41 -07002488def start_cnss_diag(ad, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002489 """Start cnss_diag to record extra wifi logs
2490
2491 Args:
2492 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002493 cnss_diag_file: cnss diag config file to push to device.
2494 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002495 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002496 if ad.model not in pixel_models:
2497 ad.log.info("Device not supported to collect pixel logger")
2498 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002499 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2500 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2501 else:
2502 prop = wifi_constants.CNSS_DIAG_PROP
2503 if ad.adb.getprop(prop) != 'true':
Omar El Ayach8c017902020-10-18 10:26:57 -07002504 if not int(
2505 ad.adb.shell("ls -l %s%s | wc -l" %
2506 (CNSS_DIAG_CONFIG_PATH, CNSS_DIAG_CONFIG_FILE))):
Girish Moturuddc0d382020-08-24 12:08:41 -07002507 ad.adb.push("%s %s" % (cnss_diag_file, CNSS_DIAG_CONFIG_PATH))
Omar El Ayach8c017902020-10-18 10:26:57 -07002508 ad.adb.shell(
2509 "find /data/vendor/wifi/cnss_diag/wlan_logs/ -type f -delete",
2510 ignore_status=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002511 ad.adb.shell("setprop %s true" % prop, ignore_status=True)
2512
Bindu Mahadevff295782019-02-08 16:17:48 -08002513
Girish Moturuddc0d382020-08-24 12:08:41 -07002514def stop_cnss_diags(ads, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002515 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002516 stop_cnss_diag(ad, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002517
Bindu Mahadevff295782019-02-08 16:17:48 -08002518
Girish Moturuddc0d382020-08-24 12:08:41 -07002519def stop_cnss_diag(ad, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002520 """Stops cnss_diag
2521
2522 Args:
2523 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002524 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002525 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002526 if ad.model not in pixel_models:
2527 ad.log.info("Device not supported to collect pixel logger")
2528 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002529 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2530 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2531 else:
2532 prop = wifi_constants.CNSS_DIAG_PROP
2533 ad.adb.shell("setprop %s false" % prop, ignore_status=True)
2534
Bindu Mahadevff295782019-02-08 16:17:48 -08002535
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002536def get_cnss_diag_log(ad):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002537 """Pulls the cnss_diag logs in the wlan_logs dir
2538 Args:
2539 ad: android device object.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002540 """
2541 logs = ad.get_file_names("/data/vendor/wifi/cnss_diag/wlan_logs/")
2542 if logs:
2543 ad.log.info("Pulling cnss_diag logs %s", logs)
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002544 log_path = os.path.join(ad.device_log_path, "CNSS_DIAG_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002545 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002546 ad.pull_files(logs, log_path)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002547
Bindu Mahadevff295782019-02-08 16:17:48 -08002548
Omar El Ayach8c017902020-10-18 10:26:57 -07002549LinkProbeResult = namedtuple(
2550 'LinkProbeResult',
2551 ('is_success', 'stdout', 'elapsed_time', 'failure_reason'))
David Sue4cd9c22019-03-26 18:07:26 -07002552
2553
2554def send_link_probe(ad):
2555 """Sends a link probe to the currently connected AP, and returns whether the
2556 probe succeeded or not.
2557
2558 Args:
2559 ad: android device object
2560 Returns:
2561 LinkProbeResult namedtuple
2562 """
2563 stdout = ad.adb.shell('cmd wifi send-link-probe')
2564 asserts.assert_false('Error' in stdout or 'Exception' in stdout,
2565 'Exception while sending link probe: ' + stdout)
2566
2567 is_success = False
2568 elapsed_time = None
2569 failure_reason = None
2570 if 'succeeded' in stdout:
2571 is_success = True
2572 elapsed_time = next(
2573 (int(token) for token in stdout.split() if token.isdigit()), None)
2574 elif 'failed with reason' in stdout:
2575 failure_reason = next(
2576 (int(token) for token in stdout.split() if token.isdigit()), None)
2577 else:
2578 asserts.fail('Unexpected link probe result: ' + stdout)
2579
Omar El Ayach8c017902020-10-18 10:26:57 -07002580 return LinkProbeResult(is_success=is_success,
2581 stdout=stdout,
2582 elapsed_time=elapsed_time,
2583 failure_reason=failure_reason)
David Sue4cd9c22019-03-26 18:07:26 -07002584
2585
2586def send_link_probes(ad, num_probes, delay_sec):
2587 """Sends a sequence of link probes to the currently connected AP, and
2588 returns whether the probes succeeded or not.
2589
2590 Args:
2591 ad: android device object
2592 num_probes: number of probes to perform
2593 delay_sec: delay time between probes, in seconds
2594 Returns:
2595 List[LinkProbeResult] one LinkProbeResults for each probe
2596 """
2597 logging.info('Sending link probes')
2598 results = []
2599 for _ in range(num_probes):
2600 # send_link_probe() will also fail the test if it sees an exception
2601 # in the stdout of the adb shell command
2602 result = send_link_probe(ad)
2603 logging.info('link probe results: ' + str(result))
2604 results.append(result)
2605 time.sleep(delay_sec)
2606
2607 return results
2608
2609
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002610def ap_setup(test, index, ap, network, bandwidth=80, channel=6):
Omar El Ayach8c017902020-10-18 10:26:57 -07002611 """Set up the AP with provided network info.
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002612
2613 Args:
2614 test: the calling test class object.
2615 index: int, index of the AP.
2616 ap: access_point object of the AP.
2617 network: dict with information of the network, including ssid,
2618 password and bssid.
2619 bandwidth: the operation bandwidth for the AP, default 80MHz.
2620 channel: the channel number for the AP.
2621 Returns:
2622 brconfigs: the bridge interface configs
2623 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002624 bss_settings = []
2625 ssid = network[WifiEnums.SSID_KEY]
2626 test.access_points[index].close()
2627 time.sleep(5)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002628
Omar El Ayach8c017902020-10-18 10:26:57 -07002629 # Configure AP as required.
2630 if "password" in network.keys():
2631 password = network["password"]
2632 security = hostapd_security.Security(security_mode="wpa",
2633 password=password)
2634 else:
2635 security = hostapd_security.Security(security_mode=None, password=None)
2636 config = hostapd_ap_preset.create_ap_preset(channel=channel,
2637 ssid=ssid,
2638 security=security,
2639 bss_settings=bss_settings,
2640 vht_bandwidth=bandwidth,
2641 profile_name='whirlwind',
2642 iface_wlan_2g=ap.wlan_2g,
2643 iface_wlan_5g=ap.wlan_5g)
2644 ap.start_ap(config)
2645 logging.info("AP started on channel {} with SSID {}".format(channel, ssid))
Bindu Mahadevff295782019-02-08 16:17:48 -08002646
2647
2648def turn_ap_off(test, AP):
2649 """Bring down hostapd on the Access Point.
2650 Args:
2651 test: The test class object.
2652 AP: int, indicating which AP to turn OFF.
2653 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002654 hostapd_2g = test.access_points[AP - 1]._aps['wlan0'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002655 if hostapd_2g.is_alive():
2656 hostapd_2g.stop()
2657 logging.debug('Turned WLAN0 AP%d off' % AP)
Omar El Ayach8c017902020-10-18 10:26:57 -07002658 hostapd_5g = test.access_points[AP - 1]._aps['wlan1'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002659 if hostapd_5g.is_alive():
2660 hostapd_5g.stop()
2661 logging.debug('Turned WLAN1 AP%d off' % AP)
2662
2663
2664def turn_ap_on(test, AP):
2665 """Bring up hostapd on the Access Point.
2666 Args:
2667 test: The test class object.
2668 AP: int, indicating which AP to turn ON.
2669 """
Omar El Ayach8c017902020-10-18 10:26:57 -07002670 hostapd_2g = test.access_points[AP - 1]._aps['wlan0'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002671 if not hostapd_2g.is_alive():
2672 hostapd_2g.start(hostapd_2g.config)
2673 logging.debug('Turned WLAN0 AP%d on' % AP)
Omar El Ayach8c017902020-10-18 10:26:57 -07002674 hostapd_5g = test.access_points[AP - 1]._aps['wlan1'].hostapd
Bindu Mahadevff295782019-02-08 16:17:48 -08002675 if not hostapd_5g.is_alive():
2676 hostapd_5g.start(hostapd_5g.config)
2677 logging.debug('Turned WLAN1 AP%d on' % AP)
Joe Brennan48c3f692019-04-11 08:30:16 -07002678
2679
2680def turn_location_off_and_scan_toggle_off(ad):
2681 """Turns off wifi location scans."""
2682 utils.set_location_service(ad, False)
2683 ad.droid.wifiScannerToggleAlwaysAvailable(False)
2684 msg = "Failed to turn off location service's scan."
2685 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
Alfie Chen675be872020-06-04 10:48:14 +08002686
2687
2688def set_softap_channel(dut, ap_iface='wlan1', cs_count=10, channel=2462):
2689 """ Set SoftAP mode channel
2690
2691 Args:
2692 dut: android device object
2693 ap_iface: interface of SoftAP mode.
2694 cs_count: how many beacon frames before switch channel, default = 10
2695 channel: a wifi channel.
2696 """
2697 chan_switch_cmd = 'hostapd_cli -i {} chan_switch {} {}'
Omar El Ayach8c017902020-10-18 10:26:57 -07002698 chan_switch_cmd_show = chan_switch_cmd.format(ap_iface, cs_count, channel)
Alfie Chen675be872020-06-04 10:48:14 +08002699 dut.log.info('adb shell {}'.format(chan_switch_cmd_show))
Omar El Ayach8c017902020-10-18 10:26:57 -07002700 chan_switch_result = dut.adb.shell(
2701 chan_switch_cmd.format(ap_iface, cs_count, channel))
Alfie Chen675be872020-06-04 10:48:14 +08002702 if chan_switch_result == 'OK':
2703 dut.log.info('switch hotspot channel to {}'.format(channel))
2704 return chan_switch_result
2705
2706 asserts.fail("Failed to switch hotspot channel")