blob: 3c3f5542600ac21e63b68d8f03da900d7425b5fc [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
Bindu Mahadev4e710362016-11-17 16:17:11 -080036from acts.test_utils.wifi import wifi_constants
Rebecca Silberstein8c422e62016-07-19 15:04:46 -070037from acts.test_utils.tel import tel_defines
Ang Li73697b32015-12-03 00:41:53 +000038
Bindu Mahadev1d3991e2017-03-20 18:06:54 -070039# Default timeout used for reboot, toggle WiFi and Airplane mode,
40# for the system to settle down after the operation.
41DEFAULT_TIMEOUT = 10
Ang Li73697b32015-12-03 00:41:53 +000042# Number of seconds to wait for events that are supposed to happen quickly.
43# Like onSuccess for start background scan and confirmation on wifi state
44# change.
45SHORT_TIMEOUT = 30
Bindu Mahadev7060a9f2018-05-04 13:48:12 -070046ROAMING_TIMEOUT = 30
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -080047WIFI_CONNECTION_TIMEOUT_DEFAULT = 30
Ang Li73697b32015-12-03 00:41:53 +000048# Speed of light in m/s.
49SPEED_OF_LIGHT = 299792458
50
Qi Jiang8b443672018-03-16 14:46:50 -070051DEFAULT_PING_ADDR = "https://www.google.com/robots.txt"
Ang Li73697b32015-12-03 00:41:53 +000052
Girish Moturuddc0d382020-08-24 12:08:41 -070053CNSS_DIAG_CONFIG_PATH = "/data/vendor/wifi/cnss_diag/"
54CNSS_DIAG_CONFIG_FILE = "cnss_diag.conf"
55
Girish Moturu36348a32019-12-10 08:41:54 -080056ROAMING_ATTN = {
Bindu Mahadev7060a9f2018-05-04 13:48:12 -070057 "AP1_on_AP2_off": [
58 0,
59 0,
Girish Moturu8adc02f2020-07-08 16:01:29 -070060 95,
61 95
Bindu Mahadev7060a9f2018-05-04 13:48:12 -070062 ],
63 "AP1_off_AP2_on": [
Girish Moturu8adc02f2020-07-08 16:01:29 -070064 95,
65 95,
Bindu Mahadev7060a9f2018-05-04 13:48:12 -070066 0,
67 0
68 ],
69 "default": [
70 0,
71 0,
72 0,
73 0
74 ]
75 }
Ang Li82522812016-06-02 13:57:21 -070076
Xianyuan Jia0e39e552019-01-24 17:17:47 -080077
Ang Li73697b32015-12-03 00:41:53 +000078class WifiEnums():
79
leslce9cf6d2020-02-19 16:37:07 +080080 SSID_KEY = "SSID" # Used for Wifi & SoftAp
Roshan Piusc999e5e2018-11-09 10:59:52 -080081 SSID_PATTERN_KEY = "ssidPattern"
Bindu Mahadev4c94b532019-01-09 12:20:10 -080082 NETID_KEY = "network_id"
leslce9cf6d2020-02-19 16:37:07 +080083 BSSID_KEY = "BSSID" # Used for Wifi & SoftAp
Roshan Piusc999e5e2018-11-09 10:59:52 -080084 BSSID_PATTERN_KEY = "bssidPattern"
leslce9cf6d2020-02-19 16:37:07 +080085 PWD_KEY = "password" # Used for Wifi & SoftAp
Ang Li73697b32015-12-03 00:41:53 +000086 frequency_key = "frequency"
lesl6d30a172020-03-05 15:05:22 +080087 HIDDEN_KEY = "hiddenSSID" # Used for Wifi & SoftAp
Roshan Piusd1204442018-11-12 12:20:39 -080088 IS_APP_INTERACTION_REQUIRED = "isAppInteractionRequired"
89 IS_USER_INTERACTION_REQUIRED = "isUserInteractionRequired"
Roshan Pius55fb7c42020-04-03 14:47:18 -070090 IS_SUGGESTION_METERED = "isMetered"
Roshan Piusd1204442018-11-12 12:20:39 -080091 PRIORITY = "priority"
leslce9cf6d2020-02-19 16:37:07 +080092 SECURITY = "security" # Used for Wifi & SoftAp
Ang Li73697b32015-12-03 00:41:53 +000093
leslce9cf6d2020-02-19 16:37:07 +080094 # Used for SoftAp
lesl6d30a172020-03-05 15:05:22 +080095 AP_BAND_KEY = "apBand"
96 AP_CHANNEL_KEY = "apChannel"
97 AP_MAXCLIENTS_KEY = "MaxNumberOfClients"
98 AP_SHUTDOWNTIMEOUT_KEY = "ShutdownTimeoutMillis"
99 AP_SHUTDOWNTIMEOUTENABLE_KEY = "AutoShutdownEnabled"
100 AP_CLIENTCONTROL_KEY = "ClientControlByUserEnabled"
101 AP_ALLOWEDLIST_KEY = "AllowedClientList"
102 AP_BLOCKEDLIST_KEY = "BlockedClientList"
103
leslce9cf6d2020-02-19 16:37:07 +0800104 WIFI_CONFIG_SOFTAP_BAND_2G = 1
105 WIFI_CONFIG_SOFTAP_BAND_5G = 2
106 WIFI_CONFIG_SOFTAP_BAND_2G_5G = 3
107 WIFI_CONFIG_SOFTAP_BAND_6G = 4
108 WIFI_CONFIG_SOFTAP_BAND_2G_6G = 5
109 WIFI_CONFIG_SOFTAP_BAND_5G_6G = 6
110 WIFI_CONFIG_SOFTAP_BAND_ANY = 7
111
112 # DO NOT USE IT for new test case! Replaced by WIFI_CONFIG_SOFTAP_BAND_
113 WIFI_CONFIG_APBAND_2G = WIFI_CONFIG_SOFTAP_BAND_2G
114 WIFI_CONFIG_APBAND_5G = WIFI_CONFIG_SOFTAP_BAND_5G
115 WIFI_CONFIG_APBAND_AUTO = WIFI_CONFIG_SOFTAP_BAND_2G_5G
116
117 WIFI_CONFIG_APBAND_2G_OLD = 0
118 WIFI_CONFIG_APBAND_5G_OLD = 1
119 WIFI_CONFIG_APBAND_AUTO_OLD = -1
Ang Li73697b32015-12-03 00:41:53 +0000120
Ang Li82522812016-06-02 13:57:21 -0700121 WIFI_WPS_INFO_PBC = 0
122 WIFI_WPS_INFO_DISPLAY = 1
123 WIFI_WPS_INFO_KEYPAD = 2
124 WIFI_WPS_INFO_LABEL = 3
125 WIFI_WPS_INFO_INVALID = 4
Ang Li73697b32015-12-03 00:41:53 +0000126
lesl6d30a172020-03-05 15:05:22 +0800127 class SoftApSecurityType():
128 OPEN = "NONE"
129 WPA2 = "WPA2_PSK"
130 WPA3_SAE_TRANSITION = "WPA3_SAE_TRANSITION"
131 WPA3_SAE = "WPA3_SAE"
132
Ang Li73697b32015-12-03 00:41:53 +0000133 class CountryCode():
134 CHINA = "CN"
135 JAPAN = "JP"
136 UK = "GB"
137 US = "US"
138 UNKNOWN = "UNKNOWN"
139
140 # Start of Macros for EAP
141 # EAP types
142 class Eap(IntEnum):
143 NONE = -1
144 PEAP = 0
Ang Li82522812016-06-02 13:57:21 -0700145 TLS = 1
Ang Li73697b32015-12-03 00:41:53 +0000146 TTLS = 2
Ang Li82522812016-06-02 13:57:21 -0700147 PWD = 3
148 SIM = 4
149 AKA = 5
150 AKA_PRIME = 6
151 UNAUTH_TLS = 7
Ang Li73697b32015-12-03 00:41:53 +0000152
153 # EAP Phase2 types
154 class EapPhase2(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700155 NONE = 0
156 PAP = 1
157 MSCHAP = 2
158 MSCHAPV2 = 3
159 GTC = 4
Ang Li73697b32015-12-03 00:41:53 +0000160
161 class Enterprise:
Ang Li82522812016-06-02 13:57:21 -0700162 # Enterprise Config Macros
163 EMPTY_VALUE = "NULL"
164 EAP = "eap"
165 PHASE2 = "phase2"
166 IDENTITY = "identity"
167 ANON_IDENTITY = "anonymous_identity"
168 PASSWORD = "password"
169 SUBJECT_MATCH = "subject_match"
Ang Li73697b32015-12-03 00:41:53 +0000170 ALTSUBJECT_MATCH = "altsubject_match"
171 DOM_SUFFIX_MATCH = "domain_suffix_match"
Ang Li82522812016-06-02 13:57:21 -0700172 CLIENT_CERT = "client_cert"
173 CA_CERT = "ca_cert"
174 ENGINE = "engine"
175 ENGINE_ID = "engine_id"
176 PRIVATE_KEY_ID = "key_id"
177 REALM = "realm"
178 PLMN = "plmn"
179 FQDN = "FQDN"
180 FRIENDLY_NAME = "providerFriendlyName"
181 ROAMING_IDS = "roamingConsortiumIds"
Jimmy Chen7baec622020-06-23 19:00:33 +0800182 OCSP = "ocsp"
Ang Li73697b32015-12-03 00:41:53 +0000183 # End of Macros for EAP
184
185 # Macros for wifi p2p.
186 WIFI_P2P_SERVICE_TYPE_ALL = 0
187 WIFI_P2P_SERVICE_TYPE_BONJOUR = 1
188 WIFI_P2P_SERVICE_TYPE_UPNP = 2
189 WIFI_P2P_SERVICE_TYPE_VENDOR_SPECIFIC = 255
190
191 class ScanResult:
192 CHANNEL_WIDTH_20MHZ = 0
193 CHANNEL_WIDTH_40MHZ = 1
194 CHANNEL_WIDTH_80MHZ = 2
195 CHANNEL_WIDTH_160MHZ = 3
196 CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4
197
198 # Macros for wifi rtt.
199 class RttType(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700200 TYPE_ONE_SIDED = 1
201 TYPE_TWO_SIDED = 2
Ang Li73697b32015-12-03 00:41:53 +0000202
203 class RttPeerType(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700204 PEER_TYPE_AP = 1
205 PEER_TYPE_STA = 2 # Requires NAN.
206 PEER_P2P_GO = 3
207 PEER_P2P_CLIENT = 4
208 PEER_NAN = 5
Ang Li73697b32015-12-03 00:41:53 +0000209
210 class RttPreamble(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700211 PREAMBLE_LEGACY = 0x01
212 PREAMBLE_HT = 0x02
213 PREAMBLE_VHT = 0x04
Ang Li73697b32015-12-03 00:41:53 +0000214
215 class RttBW(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700216 BW_5_SUPPORT = 0x01
217 BW_10_SUPPORT = 0x02
218 BW_20_SUPPORT = 0x04
219 BW_40_SUPPORT = 0x08
220 BW_80_SUPPORT = 0x10
Ang Li73697b32015-12-03 00:41:53 +0000221 BW_160_SUPPORT = 0x20
222
223 class Rtt(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700224 STATUS_SUCCESS = 0
225 STATUS_FAILURE = 1
226 STATUS_FAIL_NO_RSP = 2
227 STATUS_FAIL_REJECTED = 3
228 STATUS_FAIL_NOT_SCHEDULED_YET = 4
229 STATUS_FAIL_TM_TIMEOUT = 5
230 STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6
231 STATUS_FAIL_NO_CAPABILITY = 7
232 STATUS_ABORTED = 8
233 STATUS_FAIL_INVALID_TS = 9
234 STATUS_FAIL_PROTOCOL = 10
235 STATUS_FAIL_SCHEDULE = 11
236 STATUS_FAIL_BUSY_TRY_LATER = 12
237 STATUS_INVALID_REQ = 13
238 STATUS_NO_WIFI = 14
239 STATUS_FAIL_FTM_PARAM_OVERRIDE = 15
Ang Li73697b32015-12-03 00:41:53 +0000240
Ang Li82522812016-06-02 13:57:21 -0700241 REASON_UNSPECIFIED = -1
242 REASON_NOT_AVAILABLE = -2
243 REASON_INVALID_LISTENER = -3
244 REASON_INVALID_REQUEST = -4
Ang Li73697b32015-12-03 00:41:53 +0000245
246 class RttParam:
247 device_type = "deviceType"
248 request_type = "requestType"
249 BSSID = "bssid"
250 channel_width = "channelWidth"
251 frequency = "frequency"
252 center_freq0 = "centerFreq0"
253 center_freq1 = "centerFreq1"
254 number_burst = "numberBurst"
255 interval = "interval"
256 num_samples_per_burst = "numSamplesPerBurst"
257 num_retries_per_measurement_frame = "numRetriesPerMeasurementFrame"
258 num_retries_per_FTMR = "numRetriesPerFTMR"
259 lci_request = "LCIRequest"
260 lcr_request = "LCRRequest"
261 burst_timeout = "burstTimeout"
262 preamble = "preamble"
263 bandwidth = "bandwidth"
264 margin = "margin"
265
266 RTT_MARGIN_OF_ERROR = {
267 RttBW.BW_80_SUPPORT: 2,
268 RttBW.BW_40_SUPPORT: 5,
269 RttBW.BW_20_SUPPORT: 5
270 }
271
272 # Macros as specified in the WifiScanner code.
Ang Li82522812016-06-02 13:57:21 -0700273 WIFI_BAND_UNSPECIFIED = 0 # not specified
274 WIFI_BAND_24_GHZ = 1 # 2.4 GHz band
275 WIFI_BAND_5_GHZ = 2 # 5 GHz band without DFS channels
276 WIFI_BAND_5_GHZ_DFS_ONLY = 4 # 5 GHz band with DFS channels
277 WIFI_BAND_5_GHZ_WITH_DFS = 6 # 5 GHz band with DFS channels
278 WIFI_BAND_BOTH = 3 # both bands without DFS channels
279 WIFI_BAND_BOTH_WITH_DFS = 7 # both bands with DFS channels
Ang Li73697b32015-12-03 00:41:53 +0000280
281 REPORT_EVENT_AFTER_BUFFER_FULL = 0
282 REPORT_EVENT_AFTER_EACH_SCAN = 1
283 REPORT_EVENT_FULL_SCAN_RESULT = 2
284
xshuaabcfeb2018-02-14 11:43:24 -0800285 SCAN_TYPE_LOW_LATENCY = 0
286 SCAN_TYPE_LOW_POWER = 1
287 SCAN_TYPE_HIGH_ACCURACY = 2
288
Ang Li73697b32015-12-03 00:41:53 +0000289 # US Wifi frequencies
290 ALL_2G_FREQUENCIES = [2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452,
291 2457, 2462]
292 DFS_5G_FREQUENCIES = [5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580,
293 5600, 5620, 5640, 5660, 5680, 5700, 5720]
294 NONE_DFS_5G_FREQUENCIES = [5180, 5200, 5220, 5240, 5745, 5765, 5785, 5805,
295 5825]
296 ALL_5G_FREQUENCIES = DFS_5G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES
297
298 band_to_frequencies = {
Ang Li82522812016-06-02 13:57:21 -0700299 WIFI_BAND_24_GHZ: ALL_2G_FREQUENCIES,
300 WIFI_BAND_5_GHZ: NONE_DFS_5G_FREQUENCIES,
301 WIFI_BAND_5_GHZ_DFS_ONLY: DFS_5G_FREQUENCIES,
302 WIFI_BAND_5_GHZ_WITH_DFS: ALL_5G_FREQUENCIES,
303 WIFI_BAND_BOTH: ALL_2G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES,
304 WIFI_BAND_BOTH_WITH_DFS: ALL_5G_FREQUENCIES + ALL_2G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000305 }
306
307 # All Wifi frequencies to channels lookup.
308 freq_to_channel = {
309 2412: 1,
310 2417: 2,
311 2422: 3,
312 2427: 4,
313 2432: 5,
314 2437: 6,
315 2442: 7,
316 2447: 8,
317 2452: 9,
318 2457: 10,
319 2462: 11,
320 2467: 12,
321 2472: 13,
322 2484: 14,
323 4915: 183,
324 4920: 184,
325 4925: 185,
326 4935: 187,
327 4940: 188,
328 4945: 189,
329 4960: 192,
330 4980: 196,
331 5035: 7,
332 5040: 8,
333 5045: 9,
334 5055: 11,
335 5060: 12,
336 5080: 16,
337 5170: 34,
338 5180: 36,
339 5190: 38,
340 5200: 40,
341 5210: 42,
342 5220: 44,
343 5230: 46,
344 5240: 48,
345 5260: 52,
346 5280: 56,
347 5300: 60,
348 5320: 64,
349 5500: 100,
350 5520: 104,
351 5540: 108,
352 5560: 112,
353 5580: 116,
354 5600: 120,
355 5620: 124,
356 5640: 128,
357 5660: 132,
358 5680: 136,
359 5700: 140,
360 5745: 149,
361 5765: 153,
362 5785: 157,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700363 5795: 159,
Ang Li73697b32015-12-03 00:41:53 +0000364 5805: 161,
365 5825: 165,
366 }
367
368 # All Wifi channels to frequencies lookup.
369 channel_2G_to_freq = {
370 1: 2412,
371 2: 2417,
372 3: 2422,
373 4: 2427,
374 5: 2432,
375 6: 2437,
376 7: 2442,
377 8: 2447,
378 9: 2452,
379 10: 2457,
380 11: 2462,
381 12: 2467,
382 13: 2472,
383 14: 2484
384 }
385
386 channel_5G_to_freq = {
387 183: 4915,
388 184: 4920,
389 185: 4925,
390 187: 4935,
391 188: 4940,
392 189: 4945,
393 192: 4960,
394 196: 4980,
395 7: 5035,
396 8: 5040,
397 9: 5045,
398 11: 5055,
399 12: 5060,
400 16: 5080,
401 34: 5170,
402 36: 5180,
403 38: 5190,
404 40: 5200,
405 42: 5210,
406 44: 5220,
407 46: 5230,
408 48: 5240,
409 52: 5260,
410 56: 5280,
411 60: 5300,
412 64: 5320,
413 100: 5500,
414 104: 5520,
415 108: 5540,
416 112: 5560,
417 116: 5580,
418 120: 5600,
419 124: 5620,
420 128: 5640,
421 132: 5660,
422 136: 5680,
423 140: 5700,
424 149: 5745,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700425 151: 5755,
Ang Li73697b32015-12-03 00:41:53 +0000426 153: 5765,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700427 155: 5775,
Ang Li73697b32015-12-03 00:41:53 +0000428 157: 5785,
Omar El Ayachdb8463b2020-05-15 18:08:23 -0700429 159: 5795,
Ang Li73697b32015-12-03 00:41:53 +0000430 161: 5805,
431 165: 5825
432 }
433
Ang Li82522812016-06-02 13:57:21 -0700434
Ang Li73697b32015-12-03 00:41:53 +0000435class WifiChannelBase:
436 ALL_2G_FREQUENCIES = []
437 DFS_5G_FREQUENCIES = []
438 NONE_DFS_5G_FREQUENCIES = []
439 ALL_5G_FREQUENCIES = DFS_5G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES
440 MIX_CHANNEL_SCAN = []
441
442 def band_to_freq(self, band):
443 _band_to_frequencies = {
444 WifiEnums.WIFI_BAND_24_GHZ: self.ALL_2G_FREQUENCIES,
445 WifiEnums.WIFI_BAND_5_GHZ: self.NONE_DFS_5G_FREQUENCIES,
446 WifiEnums.WIFI_BAND_5_GHZ_DFS_ONLY: self.DFS_5G_FREQUENCIES,
447 WifiEnums.WIFI_BAND_5_GHZ_WITH_DFS: self.ALL_5G_FREQUENCIES,
Ang Li82522812016-06-02 13:57:21 -0700448 WifiEnums.WIFI_BAND_BOTH:
449 self.ALL_2G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES,
450 WifiEnums.WIFI_BAND_BOTH_WITH_DFS:
451 self.ALL_5G_FREQUENCIES + self.ALL_2G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000452 }
453 return _band_to_frequencies[band]
454
Ang Li82522812016-06-02 13:57:21 -0700455
Ang Li73697b32015-12-03 00:41:53 +0000456class WifiChannelUS(WifiChannelBase):
457 # US Wifi frequencies
458 ALL_2G_FREQUENCIES = [2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452,
459 2457, 2462]
460 NONE_DFS_5G_FREQUENCIES = [5180, 5200, 5220, 5240, 5745, 5765, 5785, 5805,
461 5825]
Ang Li82522812016-06-02 13:57:21 -0700462 MIX_CHANNEL_SCAN = [2412, 2437, 2462, 5180, 5200, 5280, 5260, 5300, 5500,
463 5320, 5520, 5560, 5700, 5745, 5805]
Ang Li73697b32015-12-03 00:41:53 +0000464
465 def __init__(self, model=None):
Girish Moturu0c567b02017-08-11 16:20:01 -0700466 self.DFS_5G_FREQUENCIES = [5260, 5280, 5300, 5320, 5500, 5520,
467 5540, 5560, 5580, 5600, 5620, 5640,
468 5660, 5680, 5700, 5720]
469 self.ALL_5G_FREQUENCIES = self.DFS_5G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000470
Bindu Mahadevff295782019-02-08 16:17:48 -0800471
Girish Moturuf02fa1d2017-05-21 09:51:23 +0530472class WifiReferenceNetworks:
473 """ Class to parse and return networks of different band and
474 auth type from reference_networks
475 """
476 def __init__(self, obj):
477 self.reference_networks = obj
478 self.WIFI_2G = "2g"
479 self.WIFI_5G = "5g"
480
481 self.secure_networks_2g = []
482 self.secure_networks_5g = []
483 self.open_networks_2g = []
484 self.open_networks_5g = []
485 self._parse_networks()
486
487 def _parse_networks(self):
488 for network in self.reference_networks:
489 for key in network:
490 if key == self.WIFI_2G:
491 if "password" in network[key]:
492 self.secure_networks_2g.append(network[key])
493 else:
494 self.open_networks_2g.append(network[key])
495 else:
496 if "password" in network[key]:
497 self.secure_networks_5g.append(network[key])
498 else:
499 self.open_networks_5g.append(network[key])
500
501 def return_2g_secure_networks(self):
502 return self.secure_networks_2g
503
504 def return_5g_secure_networks(self):
505 return self.secure_networks_5g
506
507 def return_2g_open_networks(self):
508 return self.open_networks_2g
509
510 def return_5g_open_networks(self):
511 return self.open_networks_5g
512
513 def return_secure_networks(self):
514 return self.secure_networks_2g + self.secure_networks_5g
515
516 def return_open_networks(self):
517 return self.open_networks_2g + self.open_networks_5g
518
Ang Li82522812016-06-02 13:57:21 -0700519
520def _assert_on_fail_handler(func, assert_on_fail, *args, **kwargs):
521 """Wrapper function that handles the bahevior of assert_on_fail.
522
523 When assert_on_fail is True, let all test signals through, which can
524 terminate test cases directly. When assert_on_fail is False, the wrapper
525 raises no test signals and reports operation status by returning True or
526 False.
527
528 Args:
529 func: The function to wrap. This function reports operation status by
530 raising test signals.
531 assert_on_fail: A boolean that specifies if the output of the wrapper
532 is test signal based or return value based.
533 args: Positional args for func.
534 kwargs: Name args for func.
535
536 Returns:
537 If assert_on_fail is True, returns True/False to signal operation
538 status, otherwise return nothing.
539 """
540 try:
541 func(*args, **kwargs)
542 if not assert_on_fail:
543 return True
544 except signals.TestSignal:
545 if assert_on_fail:
546 raise
547 return False
548
549
550def assert_network_in_list(target, network_list):
551 """Makes sure a specified target Wi-Fi network exists in a list of Wi-Fi
552 networks.
553
554 Args:
555 target: A dict representing a Wi-Fi network.
556 E.g. {WifiEnums.SSID_KEY: "SomeNetwork"}
557 network_list: A list of dicts, each representing a Wi-Fi network.
558 """
559 match_results = match_networks(target, network_list)
560 asserts.assert_true(
561 match_results, "Target network %s, does not exist in network list %s" %
562 (target, network_list))
563
564
Ang Li73697b32015-12-03 00:41:53 +0000565def match_networks(target_params, networks):
566 """Finds the WiFi networks that match a given set of parameters in a list
567 of WiFi networks.
568
Girish Moturubc48d9f2016-11-01 13:24:14 -0700569 To be considered a match, the network should contain every key-value pair
570 of target_params
Ang Li73697b32015-12-03 00:41:53 +0000571
572 Args:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700573 target_params: A dict with 1 or more key-value pairs representing a Wi-Fi network.
574 E.g { 'SSID': 'wh_ap1_5g', 'BSSID': '30:b5:c2:33:e4:47' }
Ang Li73697b32015-12-03 00:41:53 +0000575 networks: A list of dict objects representing WiFi networks.
576
577 Returns:
578 The networks that match the target parameters.
579 """
580 results = []
Betty Zhou3caa0982017-02-22 19:26:20 -0800581 asserts.assert_true(target_params,
582 "Expected networks object 'target_params' is empty")
Ang Li73697b32015-12-03 00:41:53 +0000583 for n in networks:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700584 add_network = 1
Ang Li9a66de72016-02-08 15:26:38 -0800585 for k, v in target_params.items():
586 if k not in n:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700587 add_network = 0
588 break
Ang Li9a66de72016-02-08 15:26:38 -0800589 if n[k] != v:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700590 add_network = 0
591 break
592 if add_network:
Ang Li73697b32015-12-03 00:41:53 +0000593 results.append(n)
594 return results
595
Bindu Mahadevff295782019-02-08 16:17:48 -0800596
Roshan Pius93b519c2018-05-09 12:07:11 -0700597def wait_for_wifi_state(ad, state, assert_on_fail=True):
598 """Waits for the device to transition to the specified wifi state
599
600 Args:
601 ad: An AndroidDevice object.
602 state: Wifi state to wait for.
603 assert_on_fail: If True, error checks in this function will raise test
604 failure signals.
605
606 Returns:
607 If assert_on_fail is False, function returns True if the device transitions
608 to the specified state, False otherwise. If assert_on_fail is True, no return value.
609 """
610 return _assert_on_fail_handler(
611 _wait_for_wifi_state, assert_on_fail, ad, state=state)
612
613
614def _wait_for_wifi_state(ad, state):
615 """Toggles the state of wifi.
616
617 TestFailure signals are raised when something goes wrong.
618
619 Args:
620 ad: An AndroidDevice object.
621 state: Wifi state to wait for.
622 """
623 if state == ad.droid.wifiCheckState():
624 # Check if the state is already achieved, so we don't wait for the
625 # state change event by mistake.
626 return
627 ad.droid.wifiStartTrackingStateChange()
628 fail_msg = "Device did not transition to Wi-Fi state to %s on %s." % (state,
629 ad.serial)
630 try:
631 ad.ed.wait_for_event(wifi_constants.WIFI_STATE_CHANGED,
632 lambda x: x["data"]["enabled"] == state,
633 SHORT_TIMEOUT)
634 except Empty:
635 asserts.assert_equal(state, ad.droid.wifiCheckState(), fail_msg)
636 finally:
637 ad.droid.wifiStopTrackingStateChange()
Ang Li82522812016-06-02 13:57:21 -0700638
Bindu Mahadevff295782019-02-08 16:17:48 -0800639
Ang Li82522812016-06-02 13:57:21 -0700640def wifi_toggle_state(ad, new_state=None, assert_on_fail=True):
Ang Li6b557182015-11-11 17:19:17 -0800641 """Toggles the state of wifi.
Ang Li73697b32015-12-03 00:41:53 +0000642
Ang Li6b557182015-11-11 17:19:17 -0800643 Args:
644 ad: An AndroidDevice object.
645 new_state: Wifi state to set to. If None, opposite of the current state.
Ang Li82522812016-06-02 13:57:21 -0700646 assert_on_fail: If True, error checks in this function will raise test
647 failure signals.
Ang Li73697b32015-12-03 00:41:53 +0000648
Ang Li6b557182015-11-11 17:19:17 -0800649 Returns:
Ang Li82522812016-06-02 13:57:21 -0700650 If assert_on_fail is False, function returns True if the toggle was
651 successful, False otherwise. If assert_on_fail is True, no return value.
652 """
Betty Zhou3caa0982017-02-22 19:26:20 -0800653 return _assert_on_fail_handler(
654 _wifi_toggle_state, assert_on_fail, ad, new_state=new_state)
Ang Li82522812016-06-02 13:57:21 -0700655
656
657def _wifi_toggle_state(ad, new_state=None):
658 """Toggles the state of wifi.
659
660 TestFailure signals are raised when something goes wrong.
661
662 Args:
663 ad: An AndroidDevice object.
664 new_state: The state to set Wi-Fi to. If None, opposite of the current
665 state will be set.
Ang Li6b557182015-11-11 17:19:17 -0800666 """
Ang Li31b00782016-06-21 13:04:23 -0700667 if new_state is None:
668 new_state = not ad.droid.wifiCheckState()
Ang Lie5c85c92016-07-27 15:38:09 -0700669 elif new_state == ad.droid.wifiCheckState():
670 # Check if the new_state is already achieved, so we don't wait for the
671 # state change event by mistake.
672 return
673 ad.droid.wifiStartTrackingStateChange()
Ang Li31b00782016-06-21 13:04:23 -0700674 ad.log.info("Setting Wi-Fi state to %s.", new_state)
Roshan Pius5a027fa2018-05-04 13:59:38 -0700675 ad.ed.clear_all_events()
Ang Li31b00782016-06-21 13:04:23 -0700676 # Setting wifi state.
Ang Li6b557182015-11-11 17:19:17 -0800677 ad.droid.wifiToggleState(new_state)
Jaineel3bd9bea2019-12-13 12:44:17 -0800678 time.sleep(2)
Ang Lie2e93a22016-06-22 16:43:28 -0700679 fail_msg = "Failed to set Wi-Fi state to %s on %s." % (new_state,
680 ad.serial)
Ang Li73697b32015-12-03 00:41:53 +0000681 try:
Roshan Pius5a027fa2018-05-04 13:59:38 -0700682 ad.ed.wait_for_event(wifi_constants.WIFI_STATE_CHANGED,
683 lambda x: x["data"]["enabled"] == new_state,
684 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +0000685 except Empty:
Ang Li82522812016-06-02 13:57:21 -0700686 asserts.assert_equal(new_state, ad.droid.wifiCheckState(), fail_msg)
Ang Li6b557182015-11-11 17:19:17 -0800687 finally:
688 ad.droid.wifiStopTrackingStateChange()
689
Ang Li82522812016-06-02 13:57:21 -0700690
Ang Li6b557182015-11-11 17:19:17 -0800691def reset_wifi(ad):
Ang Li1179fa72016-06-16 09:44:06 -0700692 """Clears all saved Wi-Fi networks on a device.
693
694 This will turn Wi-Fi on.
Ang Li6b557182015-11-11 17:19:17 -0800695
696 Args:
697 ad: An AndroidDevice object.
698
Ang Li6b557182015-11-11 17:19:17 -0800699 """
Ang Li6b557182015-11-11 17:19:17 -0800700 networks = ad.droid.wifiGetConfiguredNetworks()
701 if not networks:
702 return
703 for n in networks:
704 ad.droid.wifiForgetNetwork(n['networkId'])
705 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800706 event = ad.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS,
Ang Li82522812016-06-02 13:57:21 -0700707 SHORT_TIMEOUT)
Ang Li6b557182015-11-11 17:19:17 -0800708 except Empty:
Ang Li1179fa72016-06-16 09:44:06 -0700709 logging.warning("Could not confirm the removal of network %s.", n)
710 # Check again to see if there's any network left.
Betty Zhou3caa0982017-02-22 19:26:20 -0800711 asserts.assert_true(
712 not ad.droid.wifiGetConfiguredNetworks(),
713 "Failed to remove these configured Wi-Fi networks: %s" % networks)
Ang Li82522812016-06-02 13:57:21 -0700714
Ang Li73697b32015-12-03 00:41:53 +0000715
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700716def toggle_airplane_mode_on_and_off(ad):
717 """Turn ON and OFF Airplane mode.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800718
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700719 ad: An AndroidDevice object.
720 Returns: Assert if turning on/off Airplane mode fails.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800721
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700722 """
723 ad.log.debug("Toggling Airplane mode ON.")
724 asserts.assert_true(
725 utils.force_airplane_mode(ad, True),
726 "Can not turn on airplane mode on: %s" % ad.serial)
727 time.sleep(DEFAULT_TIMEOUT)
728 ad.log.debug("Toggling Airplane mode OFF.")
729 asserts.assert_true(
730 utils.force_airplane_mode(ad, False),
731 "Can not turn on airplane mode on: %s" % ad.serial)
732 time.sleep(DEFAULT_TIMEOUT)
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800733
734
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700735def toggle_wifi_off_and_on(ad):
736 """Turn OFF and ON WiFi.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800737
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700738 ad: An AndroidDevice object.
739 Returns: Assert if turning off/on WiFi fails.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800740
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700741 """
742 ad.log.debug("Toggling wifi OFF.")
743 wifi_toggle_state(ad, False)
744 time.sleep(DEFAULT_TIMEOUT)
745 ad.log.debug("Toggling wifi ON.")
746 wifi_toggle_state(ad, True)
747 time.sleep(DEFAULT_TIMEOUT)
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800748
749
Ang Li73697b32015-12-03 00:41:53 +0000750def wifi_forget_network(ad, net_ssid):
Ang Li8e767182015-12-09 17:29:24 -0800751 """Remove configured Wifi network on an android device.
Ang Li73697b32015-12-03 00:41:53 +0000752
Ang Li8e767182015-12-09 17:29:24 -0800753 Args:
754 ad: android_device object for forget network.
755 net_ssid: ssid of network to be forget
Ang Li73697b32015-12-03 00:41:53 +0000756
Ang Li8e767182015-12-09 17:29:24 -0800757 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700758 networks = ad.droid.wifiGetConfiguredNetworks()
Ang Li8e767182015-12-09 17:29:24 -0800759 if not networks:
760 return
761 for n in networks:
762 if net_ssid in n[WifiEnums.SSID_KEY]:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700763 ad.droid.wifiForgetNetwork(n['networkId'])
Ang Li8e767182015-12-09 17:29:24 -0800764 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800765 event = ad.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS,
Betty Zhou3caa0982017-02-22 19:26:20 -0800766 SHORT_TIMEOUT)
Ang Li8e767182015-12-09 17:29:24 -0800767 except Empty:
Girish Moturu1bf82302016-11-01 13:27:00 -0700768 asserts.fail("Failed to remove network %s." % n)
Ang Li73697b32015-12-03 00:41:53 +0000769
Ang Li82522812016-06-02 13:57:21 -0700770
Ang Li73697b32015-12-03 00:41:53 +0000771def wifi_test_device_init(ad):
772 """Initializes an android device for wifi testing.
773
774 0. Make sure SL4A connection is established on the android device.
775 1. Disable location service's WiFi scan.
776 2. Turn WiFi on.
777 3. Clear all saved networks.
778 4. Set country code to US.
779 5. Enable WiFi verbose logging.
780 6. Sync device time with computer time.
781 7. Turn off cellular data.
Ang Lifee28402016-07-13 13:43:29 -0700782 8. Turn off ambient display.
Ang Li73697b32015-12-03 00:41:53 +0000783 """
Ang Lifee28402016-07-13 13:43:29 -0700784 utils.require_sl4a((ad, ))
Ang Li73697b32015-12-03 00:41:53 +0000785 ad.droid.wifiScannerToggleAlwaysAvailable(False)
786 msg = "Failed to turn off location service's scan."
Ang Li82522812016-06-02 13:57:21 -0700787 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
788 wifi_toggle_state(ad, True)
Ang Li6b557182015-11-11 17:19:17 -0800789 reset_wifi(ad)
Ang Li73697b32015-12-03 00:41:53 +0000790 ad.droid.wifiEnableVerboseLogging(1)
Ang Li8e767182015-12-09 17:29:24 -0800791 msg = "Failed to enable WiFi verbose logging."
Ang Li82522812016-06-02 13:57:21 -0700792 asserts.assert_equal(ad.droid.wifiGetVerboseLoggingLevel(), 1, msg)
Ang Li73697b32015-12-03 00:41:53 +0000793 # We don't verify the following settings since they are not critical.
Ang Lie2e93a22016-06-22 16:43:28 -0700794 # Set wpa_supplicant log level to EXCESSIVE.
795 output = ad.adb.shell("wpa_cli -i wlan0 -p -g@android:wpa_wlan0 IFNAME="
796 "wlan0 log_level EXCESSIVE")
797 ad.log.info("wpa_supplicant log change status: %s", output)
Ang Lifee28402016-07-13 13:43:29 -0700798 utils.sync_device_time(ad)
Ang Li0bf8e022016-01-04 17:34:48 -0800799 ad.droid.telephonyToggleDataConnection(False)
Roshan Pius48df08c2019-09-13 08:07:30 -0700800 set_wifi_country_code(ad, WifiEnums.CountryCode.US)
Ang Lifee28402016-07-13 13:43:29 -0700801 utils.set_ambient_display(ad, False)
Ang Li73697b32015-12-03 00:41:53 +0000802
Roshan Pius48df08c2019-09-13 08:07:30 -0700803def set_wifi_country_code(ad, country_code):
804 """Sets the wifi country code on the device.
805
806 Args:
807 ad: An AndroidDevice object.
808 country_code: 2 letter ISO country code
codycaldwell35b87182020-01-16 14:08:01 -0800809
810 Raises:
811 An RpcException if unable to set the country code.
Roshan Pius48df08c2019-09-13 08:07:30 -0700812 """
Jaineelc5b56a62019-10-10 17:12:02 -0700813 try:
codycaldwell35b87182020-01-16 14:08:01 -0800814 ad.adb.shell("cmd wifi force-country-code enabled %s" % country_code)
815 except ad.adb.AdbError as e:
Jaineelc5b56a62019-10-10 17:12:02 -0700816 ad.droid.wifiSetCountryCode(WifiEnums.CountryCode.US)
Roshan Pius48df08c2019-09-13 08:07:30 -0700817
Ang Li82522812016-06-02 13:57:21 -0700818
Ang Li6b557182015-11-11 17:19:17 -0800819def start_wifi_connection_scan(ad):
Ang Li73697b32015-12-03 00:41:53 +0000820 """Starts a wifi connection scan and wait for results to become available.
821
822 Args:
Ang Li6b557182015-11-11 17:19:17 -0800823 ad: An AndroidDevice object.
Ang Li73697b32015-12-03 00:41:53 +0000824 """
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800825 ad.ed.clear_all_events()
Ang Li6b557182015-11-11 17:19:17 -0800826 ad.droid.wifiStartScan()
Ang Li82522812016-06-02 13:57:21 -0700827 try:
828 ad.ed.pop_event("WifiManagerScanResultsAvailable", 60)
829 except Empty:
830 asserts.fail("Wi-Fi results did not become available within 60s.")
831
Ang Li73697b32015-12-03 00:41:53 +0000832
Roshan Piuscb9bc482018-02-01 14:27:09 -0800833def start_wifi_connection_scan_and_return_status(ad):
834 """
835 Starts a wifi connection scan and wait for results to become available
836 or a scan failure to be reported.
837
838 Args:
839 ad: An AndroidDevice object.
840 Returns:
841 True: if scan succeeded & results are available
842 False: if scan failed
843 """
844 ad.ed.clear_all_events()
845 ad.droid.wifiStartScan()
846 try:
847 events = ad.ed.pop_events(
848 "WifiManagerScan(ResultsAvailable|Failure)", 60)
849 except Empty:
850 asserts.fail(
851 "Wi-Fi scan results/failure did not become available within 60s.")
852 # If there are multiple matches, we check for atleast one success.
853 for event in events:
854 if event["name"] == "WifiManagerScanResultsAvailable":
855 return True
856 elif event["name"] == "WifiManagerScanFailure":
857 ad.log.debug("Scan failure received")
858 return False
859
860
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800861def start_wifi_connection_scan_and_check_for_network(ad, network_ssid,
Roshan Piuscb9bc482018-02-01 14:27:09 -0800862 max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800863 """
864 Start connectivity scans & checks if the |network_ssid| is seen in
865 scan results. The method performs a max of |max_tries| connectivity scans
866 to find the network.
867
868 Args:
869 ad: An AndroidDevice object.
870 network_ssid: SSID of the network we are looking for.
871 max_tries: Number of scans to try.
872 Returns:
873 True: if network_ssid is found in scan results.
874 False: if network_ssid is not found in scan results.
875 """
876 for num_tries in range(max_tries):
Roshan Piuscb9bc482018-02-01 14:27:09 -0800877 if start_wifi_connection_scan_and_return_status(ad):
878 scan_results = ad.droid.wifiGetScanResults()
879 match_results = match_networks(
880 {WifiEnums.SSID_KEY: network_ssid}, scan_results)
881 if len(match_results) > 0:
882 return True
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800883 return False
884
885
886def start_wifi_connection_scan_and_ensure_network_found(ad, network_ssid,
Roshan Piuscb9bc482018-02-01 14:27:09 -0800887 max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800888 """
889 Start connectivity scans & ensure the |network_ssid| is seen in
890 scan results. The method performs a max of |max_tries| connectivity scans
891 to find the network.
892 This method asserts on failure!
893
894 Args:
895 ad: An AndroidDevice object.
896 network_ssid: SSID of the network we are looking for.
897 max_tries: Number of scans to try.
898 """
899 ad.log.info("Starting scans to ensure %s is present", network_ssid)
900 assert_msg = "Failed to find " + network_ssid + " in scan results" \
901 " after " + str(max_tries) + " tries"
902 asserts.assert_true(start_wifi_connection_scan_and_check_for_network(
903 ad, network_ssid, max_tries), assert_msg)
904
905
906def start_wifi_connection_scan_and_ensure_network_not_found(ad, network_ssid,
Roshan Piuscb9bc482018-02-01 14:27:09 -0800907 max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800908 """
909 Start connectivity scans & ensure the |network_ssid| is not seen in
910 scan results. The method performs a max of |max_tries| connectivity scans
911 to find the network.
912 This method asserts on failure!
913
914 Args:
915 ad: An AndroidDevice object.
916 network_ssid: SSID of the network we are looking for.
917 max_tries: Number of scans to try.
918 """
919 ad.log.info("Starting scans to ensure %s is not present", network_ssid)
920 assert_msg = "Found " + network_ssid + " in scan results" \
921 " after " + str(max_tries) + " tries"
922 asserts.assert_false(start_wifi_connection_scan_and_check_for_network(
923 ad, network_ssid, max_tries), assert_msg)
924
925
Ang Li73697b32015-12-03 00:41:53 +0000926def start_wifi_background_scan(ad, scan_setting):
927 """Starts wifi background scan.
928
929 Args:
930 ad: android_device object to initiate connection on.
931 scan_setting: A dict representing the settings of the scan.
932
933 Returns:
934 If scan was started successfully, event data of success event is returned.
935 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700936 idx = ad.droid.wifiScannerStartBackgroundScan(scan_setting)
937 event = ad.ed.pop_event("WifiScannerScan{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -0800938 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +0000939 return event['data']
940
Ang Li82522812016-06-02 13:57:21 -0700941
Roshan Piusce821342018-01-10 11:03:04 -0800942def start_wifi_tethering(ad, ssid, password, band=None, hidden=None):
Ang Li73697b32015-12-03 00:41:53 +0000943 """Starts wifi tethering on an android_device.
944
945 Args:
946 ad: android_device to start wifi tethering on.
947 ssid: The SSID the soft AP should broadcast.
948 password: The password the soft AP should use.
949 band: The band the soft AP should be set on. It should be either
950 WifiEnums.WIFI_CONFIG_APBAND_2G or WifiEnums.WIFI_CONFIG_APBAND_5G.
Roshan Piusce821342018-01-10 11:03:04 -0800951 hidden: boolean to indicate if the AP needs to be hidden or not.
Ang Li73697b32015-12-03 00:41:53 +0000952
953 Returns:
Girish Moturu3581d612016-11-02 15:08:51 -0700954 No return value. Error checks in this function will raise test failure signals
Ang Li73697b32015-12-03 00:41:53 +0000955 """
Ang Li82522812016-06-02 13:57:21 -0700956 config = {WifiEnums.SSID_KEY: ssid}
Ang Li73697b32015-12-03 00:41:53 +0000957 if password:
958 config[WifiEnums.PWD_KEY] = password
959 if band:
lesl6d30a172020-03-05 15:05:22 +0800960 config[WifiEnums.AP_BAND_KEY] = band
Roshan Piusce821342018-01-10 11:03:04 -0800961 if hidden:
962 config[WifiEnums.HIDDEN_KEY] = hidden
Betty Zhou3caa0982017-02-22 19:26:20 -0800963 asserts.assert_true(
964 ad.droid.wifiSetWifiApConfiguration(config),
965 "Failed to update WifiAp Configuration")
Girish Moturu40d7dc22016-11-02 12:14:56 -0700966 ad.droid.wifiStartTrackingTetherStateChange()
967 ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
Rebecca Silbersteina2889852016-08-11 00:48:53 -0700968 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700969 ad.ed.pop_event("ConnectivityManagerOnTetheringStarted")
970 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -0800971 lambda x: x["data"]["ACTIVE_TETHER"], 30)
Ang Li76216d12016-09-20 14:51:57 -0700972 ad.log.debug("Tethering started successfully.")
Rebecca Silbersteina2889852016-08-11 00:48:53 -0700973 except Empty:
974 msg = "Failed to receive confirmation of wifi tethering starting"
975 asserts.fail(msg)
976 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700977 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li73697b32015-12-03 00:41:53 +0000978
Bindu Mahadevff295782019-02-08 16:17:48 -0800979
lesl6d30a172020-03-05 15:05:22 +0800980def save_wifi_soft_ap_config(ad, wifi_config, band=None, hidden=None,
981 security=None, password=None,
982 channel=None, max_clients=None,
983 shutdown_timeout_enable=None,
984 shutdown_timeout_millis=None,
985 client_control_enable=None,
986 allowedList=None, blockedList=None):
987 """ Save a soft ap configuration and verified
988 Args:
989 ad: android_device to set soft ap configuration.
990 wifi_config: a soft ap configuration object, at least include SSID.
991 band: specifies the band for the soft ap.
992 hidden: specifies the soft ap need to broadcast its SSID or not.
993 security: specifies the security type for the soft ap.
994 password: specifies the password for the soft ap.
995 channel: specifies the channel for the soft ap.
996 max_clients: specifies the maximum connected client number.
997 shutdown_timeout_enable: specifies the auto shut down enable or not.
998 shutdown_timeout_millis: specifies the shut down timeout value.
999 client_control_enable: specifies the client control enable or not.
1000 allowedList: specifies allowed clients list.
1001 blockedList: specifies blocked clients list.
1002 """
1003 if security and password:
1004 wifi_config[WifiEnums.SECURITY] = security
1005 wifi_config[WifiEnums.PWD_KEY] = password
Girish Moturu528b5442018-06-07 10:48:14 -07001006 if band:
lesl6d30a172020-03-05 15:05:22 +08001007 wifi_config[WifiEnums.AP_BAND_KEY] = band
Girish Moturu528b5442018-06-07 10:48:14 -07001008 if hidden:
1009 wifi_config[WifiEnums.HIDDEN_KEY] = hidden
lesl6d30a172020-03-05 15:05:22 +08001010 if channel and band:
1011 wifi_config[WifiEnums.AP_BAND_KEY] = band
1012 wifi_config[WifiEnums.AP_CHANNEL_KEY] = channel
1013 if max_clients:
1014 wifi_config[WifiEnums.AP_MAXCLIENTS_KEY] = max_clients
1015 if shutdown_timeout_enable:
1016 wifi_config[
1017 WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] = shutdown_timeout_enable
1018 if shutdown_timeout_millis:
1019 wifi_config[
1020 WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] = shutdown_timeout_millis
1021 if client_control_enable:
1022 wifi_config[WifiEnums.AP_CLIENTCONTROL_KEY] = client_control_enable
1023 if allowedList:
1024 wifi_config[WifiEnums.AP_ALLOWEDLIST_KEY] = allowedList
1025 if blockedList:
1026 wifi_config[WifiEnums.AP_BLOCKEDLIST_KEY] = blockedList
1027
1028 if WifiEnums.AP_CHANNEL_KEY in wifi_config and wifi_config[
1029 WifiEnums.AP_CHANNEL_KEY] == 0:
1030 del wifi_config[WifiEnums.AP_CHANNEL_KEY]
1031
1032 if WifiEnums.SECURITY in wifi_config and wifi_config[
1033 WifiEnums.SECURITY] == WifiEnums.SoftApSecurityType.OPEN:
1034 del wifi_config[WifiEnums.SECURITY]
1035 del wifi_config[WifiEnums.PWD_KEY]
1036
Girish Moturu528b5442018-06-07 10:48:14 -07001037 asserts.assert_true(ad.droid.wifiSetWifiApConfiguration(wifi_config),
1038 "Failed to set WifiAp Configuration")
1039
1040 wifi_ap = ad.droid.wifiGetApConfiguration()
1041 asserts.assert_true(
1042 wifi_ap[WifiEnums.SSID_KEY] == wifi_config[WifiEnums.SSID_KEY],
lesl6d30a172020-03-05 15:05:22 +08001043 "Hotspot SSID doesn't match")
1044 if WifiEnums.SECURITY in wifi_config:
1045 asserts.assert_true(
1046 wifi_ap[WifiEnums.SECURITY] == wifi_config[WifiEnums.SECURITY],
1047 "Hotspot Security doesn't match")
1048 if WifiEnums.PWD_KEY in wifi_config:
1049 asserts.assert_true(
1050 wifi_ap[WifiEnums.PWD_KEY] == wifi_config[WifiEnums.PWD_KEY],
1051 "Hotspot Password doesn't match")
Girish Moturu528b5442018-06-07 10:48:14 -07001052
lesl6d30a172020-03-05 15:05:22 +08001053 if WifiEnums.HIDDEN_KEY in wifi_config:
1054 asserts.assert_true(
1055 wifi_ap[WifiEnums.HIDDEN_KEY] == wifi_config[WifiEnums.HIDDEN_KEY],
1056 "Hotspot hidden setting doesn't match")
1057
1058 if WifiEnums.AP_BAND_KEY in wifi_config:
1059 asserts.assert_true(
1060 wifi_ap[WifiEnums.AP_BAND_KEY] == wifi_config[WifiEnums.AP_BAND_KEY],
1061 "Hotspot Band doesn't match")
1062 if WifiEnums.AP_CHANNEL_KEY in wifi_config:
1063 asserts.assert_true(
1064 wifi_ap[WifiEnums.AP_CHANNEL_KEY] == wifi_config[
1065 WifiEnums.AP_CHANNEL_KEY], "Hotspot Channel doesn't match")
1066 if WifiEnums.AP_MAXCLIENTS_KEY in wifi_config:
1067 asserts.assert_true(
1068 wifi_ap[WifiEnums.AP_MAXCLIENTS_KEY] == wifi_config[
1069 WifiEnums.AP_MAXCLIENTS_KEY], "Hotspot Max Clients doesn't match")
1070 if WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY in wifi_config:
1071 asserts.assert_true(
1072 wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] == wifi_config[
1073 WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY],
1074 "Hotspot ShutDown feature flag doesn't match")
1075 if WifiEnums.AP_SHUTDOWNTIMEOUT_KEY in wifi_config:
1076 asserts.assert_true(
1077 wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] == wifi_config[
1078 WifiEnums.AP_SHUTDOWNTIMEOUT_KEY],
1079 "Hotspot ShutDown timeout setting doesn't match")
1080 if WifiEnums.AP_CLIENTCONTROL_KEY in wifi_config:
1081 asserts.assert_true(
1082 wifi_ap[WifiEnums.AP_CLIENTCONTROL_KEY] == wifi_config[
1083 WifiEnums.AP_CLIENTCONTROL_KEY],
1084 "Hotspot Client control flag doesn't match")
1085 if WifiEnums.AP_ALLOWEDLIST_KEY in wifi_config:
1086 asserts.assert_true(
1087 wifi_ap[WifiEnums.AP_ALLOWEDLIST_KEY] == wifi_config[
1088 WifiEnums.AP_ALLOWEDLIST_KEY],
1089 "Hotspot Allowed List doesn't match")
1090 if WifiEnums.AP_BLOCKEDLIST_KEY in wifi_config:
1091 asserts.assert_true(
1092 wifi_ap[WifiEnums.AP_BLOCKEDLIST_KEY] == wifi_config[
1093 WifiEnums.AP_BLOCKEDLIST_KEY],
1094 "Hotspot Blocked List doesn't match")
Bindu Mahadevff295782019-02-08 16:17:48 -08001095
Girish Moturu528b5442018-06-07 10:48:14 -07001096def start_wifi_tethering_saved_config(ad):
1097 """ Turn on wifi hotspot with a config that is already saved """
1098 ad.droid.wifiStartTrackingTetherStateChange()
1099 ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
1100 try:
1101 ad.ed.pop_event("ConnectivityManagerOnTetheringStarted")
1102 ad.ed.wait_for_event("TetherStateChanged",
1103 lambda x: x["data"]["ACTIVE_TETHER"], 30)
1104 except:
1105 asserts.fail("Didn't receive wifi tethering starting confirmation")
1106 finally:
1107 ad.droid.wifiStopTrackingTetherStateChange()
Betty Zhou3caa0982017-02-22 19:26:20 -08001108
Bindu Mahadevff295782019-02-08 16:17:48 -08001109
Ang Li73697b32015-12-03 00:41:53 +00001110def stop_wifi_tethering(ad):
1111 """Stops wifi tethering on an android_device.
Ang Li73697b32015-12-03 00:41:53 +00001112 Args:
1113 ad: android_device to stop wifi tethering on.
1114 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001115 ad.droid.wifiStartTrackingTetherStateChange()
1116 ad.droid.connectivityStopTethering(tel_defines.TETHERING_WIFI)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001117 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001118 ad.ed.pop_event("WifiManagerApDisabled", 30)
1119 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -08001120 lambda x: not x["data"]["ACTIVE_TETHER"], 30)
Rebecca Silbersteina2889852016-08-11 00:48:53 -07001121 except Empty:
1122 msg = "Failed to receive confirmation of wifi tethering stopping"
1123 asserts.fail(msg)
1124 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001125 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li82522812016-06-02 13:57:21 -07001126
Ang Li76216d12016-09-20 14:51:57 -07001127
Roshan Pius58916a32016-06-16 16:26:44 -07001128def toggle_wifi_and_wait_for_reconnection(ad,
1129 network,
1130 num_of_tries=1,
1131 assert_on_fail=True):
1132 """Toggle wifi state and then wait for Android device to reconnect to
1133 the provided wifi network.
1134
1135 This expects the device to be already connected to the provided network.
1136
1137 Logic steps are
1138 1. Ensure that we're connected to the network.
1139 2. Turn wifi off.
1140 3. Wait for 10 seconds.
1141 4. Turn wifi on.
1142 5. Wait for the "connected" event, then confirm the connected ssid is the
1143 one requested.
1144
1145 Args:
1146 ad: android_device object to initiate connection on.
1147 network: A dictionary representing the network to await connection. The
1148 dictionary must have the key "SSID".
1149 num_of_tries: An integer that is the number of times to try before
1150 delaring failure. Default is 1.
1151 assert_on_fail: If True, error checks in this function will raise test
1152 failure signals.
1153
1154 Returns:
1155 If assert_on_fail is False, function returns True if the toggle was
1156 successful, False otherwise. If assert_on_fail is True, no return value.
1157 """
Betty Zhou3caa0982017-02-22 19:26:20 -08001158 return _assert_on_fail_handler(
1159 _toggle_wifi_and_wait_for_reconnection,
1160 assert_on_fail,
1161 ad,
1162 network,
1163 num_of_tries=num_of_tries)
Roshan Pius58916a32016-06-16 16:26:44 -07001164
1165
Girish Moturu5d9f4202019-12-03 15:29:21 -08001166def _toggle_wifi_and_wait_for_reconnection(ad, network, num_of_tries=3):
Roshan Pius58916a32016-06-16 16:26:44 -07001167 """Toggle wifi state and then wait for Android device to reconnect to
1168 the provided wifi network.
1169
1170 This expects the device to be already connected to the provided network.
1171
1172 Logic steps are
1173 1. Ensure that we're connected to the network.
1174 2. Turn wifi off.
1175 3. Wait for 10 seconds.
1176 4. Turn wifi on.
1177 5. Wait for the "connected" event, then confirm the connected ssid is the
1178 one requested.
1179
1180 This will directly fail a test if anything goes wrong.
1181
1182 Args:
1183 ad: android_device object to initiate connection on.
1184 network: A dictionary representing the network to await connection. The
1185 dictionary must have the key "SSID".
1186 num_of_tries: An integer that is the number of times to try before
1187 delaring failure. Default is 1.
1188 """
Roshan Pius58916a32016-06-16 16:26:44 -07001189 expected_ssid = network[WifiEnums.SSID_KEY]
1190 # First ensure that we're already connected to the provided network.
1191 verify_con = {WifiEnums.SSID_KEY: expected_ssid}
1192 verify_wifi_connection_info(ad, verify_con)
1193 # Now toggle wifi state and wait for the connection event.
1194 wifi_toggle_state(ad, False)
1195 time.sleep(10)
1196 wifi_toggle_state(ad, True)
1197 ad.droid.wifiStartTrackingStateChange()
1198 try:
1199 connect_result = None
1200 for i in range(num_of_tries):
1201 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -08001202 connect_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
Roshan Pius58916a32016-06-16 16:26:44 -07001203 30)
1204 break
1205 except Empty:
1206 pass
1207 asserts.assert_true(connect_result,
1208 "Failed to connect to Wi-Fi network %s on %s" %
Girish Moturu40d7dc22016-11-02 12:14:56 -07001209 (network, ad.serial))
Betty Zhou3caa0982017-02-22 19:26:20 -08001210 logging.debug("Connection result on %s: %s.", ad.serial,
1211 connect_result)
Roshan Pius58916a32016-06-16 16:26:44 -07001212 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1213 asserts.assert_equal(actual_ssid, expected_ssid,
1214 "Connected to the wrong network on %s."
1215 "Expected %s, but got %s." %
Girish Moturu40d7dc22016-11-02 12:14:56 -07001216 (ad.serial, expected_ssid, actual_ssid))
Betty Zhou3caa0982017-02-22 19:26:20 -08001217 logging.info("Connected to Wi-Fi network %s on %s", actual_ssid,
1218 ad.serial)
Roshan Pius58916a32016-06-16 16:26:44 -07001219 finally:
1220 ad.droid.wifiStopTrackingStateChange()
1221
1222
Roshan Piusd1204442018-11-12 12:20:39 -08001223def wait_for_connect(ad, expected_ssid=None, expected_id=None, tries=2,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001224 assert_on_fail=True):
Roshan Piusd1204442018-11-12 12:20:39 -08001225 """Wait for a connect event.
1226
1227 This will directly fail a test if anything goes wrong.
1228
1229 Args:
1230 ad: An Android device object.
1231 expected_ssid: SSID of the network to connect to.
1232 expected_id: Network Id of the network to connect to.
1233 tries: An integer that is the number of times to try before failing.
1234 assert_on_fail: If True, error checks in this function will raise test
1235 failure signals.
1236
1237 Returns:
1238 Returns a value only if assert_on_fail is false.
1239 Returns True if the connection was successful, False otherwise.
1240 """
1241 return _assert_on_fail_handler(
1242 _wait_for_connect, assert_on_fail, ad, expected_ssid, expected_id,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001243 tries)
Roshan Piusd1204442018-11-12 12:20:39 -08001244
1245
Oscar Shucb9af9b2019-05-02 20:01:49 +00001246def _wait_for_connect(ad, expected_ssid=None, expected_id=None, tries=2):
Roshan Piusd1204442018-11-12 12:20:39 -08001247 """Wait for a connect event.
1248
1249 Args:
1250 ad: An Android device object.
1251 expected_ssid: SSID of the network to connect to.
1252 expected_id: Network Id of the network to connect to.
1253 tries: An integer that is the number of times to try before failing.
1254 """
1255 ad.droid.wifiStartTrackingStateChange()
1256 try:
1257 connect_result = _wait_for_connect_event(
Oscar Shucb9af9b2019-05-02 20:01:49 +00001258 ad, ssid=expected_ssid, id=expected_id, tries=tries)
Roshan Piusd1204442018-11-12 12:20:39 -08001259 asserts.assert_true(connect_result,
1260 "Failed to connect to Wi-Fi network %s" %
1261 expected_ssid)
1262 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
1263 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1264 if expected_ssid:
1265 asserts.assert_equal(actual_ssid, expected_ssid,
1266 "Connected to the wrong network")
1267 actual_id = connect_result['data'][WifiEnums.NETID_KEY]
1268 if expected_id:
1269 asserts.assert_equal(actual_id, expected_id,
1270 "Connected to the wrong network")
1271 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
1272 except Empty:
1273 asserts.fail("Failed to start connection process to %s" %
1274 expected_ssid)
1275 except Exception as error:
1276 ad.log.error("Failed to connect to %s with error %s", expected_ssid,
1277 error)
1278 raise signals.TestFailure("Failed to connect to %s network" %
1279 expected_ssid)
1280 finally:
1281 ad.droid.wifiStopTrackingStateChange()
1282
1283
Oscar Shucb9af9b2019-05-02 20:01:49 +00001284def _wait_for_connect_event(ad, ssid=None, id=None, tries=1):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001285 """Wait for a connect event on queue and pop when available.
1286
1287 Args:
1288 ad: An Android device object.
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001289 ssid: SSID of the network to connect to.
1290 id: Network Id of the network to connect to.
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001291 tries: An integer that is the number of times to try before failing.
1292
1293 Returns:
1294 A dict with details of the connection data, which looks like this:
1295 {
1296 'time': 1485460337798,
1297 'name': 'WifiNetworkConnected',
1298 'data': {
1299 'rssi': -27,
1300 'is_24ghz': True,
1301 'mac_address': '02:00:00:00:00:00',
1302 'network_id': 1,
1303 'BSSID': '30:b5:c2:33:d3:fc',
1304 'ip_address': 117483712,
1305 'link_speed': 54,
1306 'supplicant_state': 'completed',
1307 'hidden_ssid': False,
1308 'SSID': 'wh_ap1_2g',
1309 'is_5ghz': False}
1310 }
1311
1312 """
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001313 conn_result = None
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001314
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001315 # If ssid and network id is None, just wait for any connect event.
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001316 if id is None and ssid is None:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001317 for i in range(tries):
1318 try:
1319 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED, 30)
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001320 break
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001321 except Empty:
1322 pass
1323 else:
1324 # If ssid or network id is specified, wait for specific connect event.
1325 for i in range(tries):
1326 try:
1327 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED, 30)
1328 if id and conn_result['data'][WifiEnums.NETID_KEY] == id:
1329 break
1330 elif ssid and conn_result['data'][WifiEnums.SSID_KEY] == ssid:
1331 break
1332 except Empty:
1333 pass
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001334
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001335 return conn_result
1336
Bindu Mahadevff295782019-02-08 16:17:48 -08001337
Roshan Piusffc29912019-01-18 13:39:49 -08001338def wait_for_disconnect(ad, timeout=10):
1339 """Wait for a disconnect event within the specified timeout.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001340
1341 Args:
1342 ad: Android device object.
Roshan Piusffc29912019-01-18 13:39:49 -08001343 timeout: Timeout in seconds.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001344
1345 """
1346 try:
1347 ad.droid.wifiStartTrackingStateChange()
Roshan Piusffc29912019-01-18 13:39:49 -08001348 event = ad.ed.pop_event("WifiNetworkDisconnected", timeout)
Roshan Piusbf7e3982018-02-15 12:37:41 -08001349 except Empty:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001350 raise signals.TestFailure("Device did not disconnect from the network")
Roshan Piusffc29912019-01-18 13:39:49 -08001351 finally:
1352 ad.droid.wifiStopTrackingStateChange()
1353
1354
1355def ensure_no_disconnect(ad, duration=10):
1356 """Ensure that there is no disconnect for the specified duration.
1357
1358 Args:
1359 ad: Android device object.
1360 duration: Duration in seconds.
1361
1362 """
1363 try:
1364 ad.droid.wifiStartTrackingStateChange()
1365 event = ad.ed.pop_event("WifiNetworkDisconnected", duration)
1366 raise signals.TestFailure("Device disconnected from the network")
1367 except Empty:
1368 pass
1369 finally:
1370 ad.droid.wifiStopTrackingStateChange()
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001371
1372
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001373def connect_to_wifi_network(ad, network, assert_on_fail=True,
Joe Brennan48c3f692019-04-11 08:30:16 -07001374 check_connectivity=True, hidden=False):
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001375 """Connection logic for open and psk wifi networks.
1376
1377 Args:
Jong Wook Kim92356922018-02-06 18:32:49 -08001378 ad: AndroidDevice to use for connection
1379 network: network info of the network to connect to
1380 assert_on_fail: If true, errors from wifi_connect will raise
1381 test failure signals.
Joe Brennan48c3f692019-04-11 08:30:16 -07001382 hidden: Is the Wifi network hidden.
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001383 """
Joe Brennan48c3f692019-04-11 08:30:16 -07001384 if hidden:
1385 start_wifi_connection_scan_and_ensure_network_not_found(
1386 ad, network[WifiEnums.SSID_KEY])
1387 else:
1388 start_wifi_connection_scan_and_ensure_network_found(
1389 ad, network[WifiEnums.SSID_KEY])
Jong Wook Kim92356922018-02-06 18:32:49 -08001390 wifi_connect(ad,
1391 network,
1392 num_of_tries=3,
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001393 assert_on_fail=assert_on_fail,
1394 check_connectivity=check_connectivity)
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001395
1396
1397def connect_to_wifi_network_with_id(ad, network_id, network_ssid):
1398 """Connect to the given network using network id and verify SSID.
1399
1400 Args:
1401 network_id: int Network Id of the network.
1402 network_ssid: string SSID of the network.
1403
1404 Returns: True if connect using network id was successful;
1405 False otherwise.
1406
1407 """
Jong Wook Kim92356922018-02-06 18:32:49 -08001408 start_wifi_connection_scan_and_ensure_network_found(ad, network_ssid)
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001409 wifi_connect_by_id(ad, network_id)
1410 connect_data = ad.droid.wifiGetConnectionInfo()
1411 connect_ssid = connect_data[WifiEnums.SSID_KEY]
1412 ad.log.debug("Expected SSID = %s Connected SSID = %s" %
1413 (network_ssid, connect_ssid))
1414 if connect_ssid != network_ssid:
1415 return False
1416 return True
1417
1418
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001419def wifi_connect(ad, network, num_of_tries=1, assert_on_fail=True,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001420 check_connectivity=True):
Ang Li99d8c6d2015-12-09 15:56:13 -08001421 """Connect an Android device to a wifi network.
Ang Li73697b32015-12-03 00:41:53 +00001422
1423 Initiate connection to a wifi network, wait for the "connected" event, then
Ang Li99d8c6d2015-12-09 15:56:13 -08001424 confirm the connected ssid is the one requested.
Ang Li73697b32015-12-03 00:41:53 +00001425
Ang Li82522812016-06-02 13:57:21 -07001426 This will directly fail a test if anything goes wrong.
1427
Ang Li73697b32015-12-03 00:41:53 +00001428 Args:
1429 ad: android_device object to initiate connection on.
Ang Li99d8c6d2015-12-09 15:56:13 -08001430 network: A dictionary representing the network to connect to. The
Ang Li82522812016-06-02 13:57:21 -07001431 dictionary must have the key "SSID".
1432 num_of_tries: An integer that is the number of times to try before
1433 delaring failure. Default is 1.
1434 assert_on_fail: If True, error checks in this function will raise test
1435 failure signals.
1436
1437 Returns:
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001438 Returns a value only if assert_on_fail is false.
1439 Returns True if the connection was successful, False otherwise.
Ang Li73697b32015-12-03 00:41:53 +00001440 """
Betty Zhou3caa0982017-02-22 19:26:20 -08001441 return _assert_on_fail_handler(
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001442 _wifi_connect, assert_on_fail, ad, network, num_of_tries=num_of_tries,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001443 check_connectivity=check_connectivity)
Ang Li82522812016-06-02 13:57:21 -07001444
1445
Oscar Shucb9af9b2019-05-02 20:01:49 +00001446def _wifi_connect(ad, network, num_of_tries=1, check_connectivity=True):
Ang Li82522812016-06-02 13:57:21 -07001447 """Connect an Android device to a wifi network.
1448
1449 Initiate connection to a wifi network, wait for the "connected" event, then
1450 confirm the connected ssid is the one requested.
1451
1452 This will directly fail a test if anything goes wrong.
1453
1454 Args:
1455 ad: android_device object to initiate connection on.
1456 network: A dictionary representing the network to connect to. The
1457 dictionary must have the key "SSID".
1458 num_of_tries: An integer that is the number of times to try before
1459 delaring failure. Default is 1.
1460 """
Ang Li82522812016-06-02 13:57:21 -07001461 asserts.assert_true(WifiEnums.SSID_KEY in network,
1462 "Key '%s' must be present in network definition." %
1463 WifiEnums.SSID_KEY)
Ang Li99d8c6d2015-12-09 15:56:13 -08001464 ad.droid.wifiStartTrackingStateChange()
Betty Zhoud35dab82016-12-06 15:24:23 -08001465 expected_ssid = network[WifiEnums.SSID_KEY]
Bindu Mahadev50374df2017-01-04 11:03:32 -08001466 ad.droid.wifiConnectByConfig(network)
1467 ad.log.info("Starting connection process to %s", expected_ssid)
Ang Li73697b32015-12-03 00:41:53 +00001468 try:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001469 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_CONFIG_SUCCESS, 30)
Roshan Piusd1204442018-11-12 12:20:39 -08001470 connect_result = _wait_for_connect_event(
Oscar Shucb9af9b2019-05-02 20:01:49 +00001471 ad, ssid=expected_ssid, tries=num_of_tries)
Ang Li82522812016-06-02 13:57:21 -07001472 asserts.assert_true(connect_result,
1473 "Failed to connect to Wi-Fi network %s on %s" %
Girish Moturubc48d9f2016-11-01 13:24:14 -07001474 (network, ad.serial))
Ang Li31b00782016-06-21 13:04:23 -07001475 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
Ang Li99d8c6d2015-12-09 15:56:13 -08001476 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Ang Li82522812016-06-02 13:57:21 -07001477 asserts.assert_equal(actual_ssid, expected_ssid,
Betty Zhou3caa0982017-02-22 19:26:20 -08001478 "Connected to the wrong network on %s." %
1479 ad.serial)
Ang Li31b00782016-06-21 13:04:23 -07001480 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
Bindu Mahadev50374df2017-01-04 11:03:32 -08001481
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001482 if check_connectivity:
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08001483 internet = validate_connection(ad, DEFAULT_PING_ADDR)
Bindu Mahadev27c2d292018-03-19 16:13:08 -07001484 if not internet:
1485 raise signals.TestFailure("Failed to connect to internet on %s" %
1486 expected_ssid)
Bindu Mahadev50374df2017-01-04 11:03:32 -08001487 except Empty:
1488 asserts.fail("Failed to start connection process to %s on %s" %
1489 (network, ad.serial))
Bindu Mahadev4e710362016-11-17 16:17:11 -08001490 except Exception as error:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001491 ad.log.error("Failed to connect to %s with error %s", expected_ssid,
1492 error)
1493 raise signals.TestFailure("Failed to connect to %s network" % network)
1494
Ang Li73697b32015-12-03 00:41:53 +00001495 finally:
Ang Li99d8c6d2015-12-09 15:56:13 -08001496 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001497
Bindu Mahadev50374df2017-01-04 11:03:32 -08001498
Oscar Shucb9af9b2019-05-02 20:01:49 +00001499def wifi_connect_by_id(ad, network_id, num_of_tries=3, assert_on_fail=True):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001500 """Connect an Android device to a wifi network using network Id.
1501
1502 Start connection to the wifi network, with the given network Id, wait for
1503 the "connected" event, then verify the connected network is the one requested.
1504
1505 This will directly fail a test if anything goes wrong.
1506
1507 Args:
1508 ad: android_device object to initiate connection on.
1509 network_id: Integer specifying the network id of the network.
1510 num_of_tries: An integer that is the number of times to try before
1511 delaring failure. Default is 1.
1512 assert_on_fail: If True, error checks in this function will raise test
1513 failure signals.
1514
1515 Returns:
1516 Returns a value only if assert_on_fail is false.
1517 Returns True if the connection was successful, False otherwise.
1518 """
1519 _assert_on_fail_handler(_wifi_connect_by_id, assert_on_fail, ad,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001520 network_id, num_of_tries)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001521
1522
Oscar Shucb9af9b2019-05-02 20:01:49 +00001523def _wifi_connect_by_id(ad, network_id, num_of_tries=1):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001524 """Connect an Android device to a wifi network using it's network id.
1525
1526 Start connection to the wifi network, with the given network id, wait for
1527 the "connected" event, then verify the connected network is the one requested.
1528
1529 Args:
1530 ad: android_device object to initiate connection on.
1531 network_id: Integer specifying the network id of the network.
1532 num_of_tries: An integer that is the number of times to try before
1533 delaring failure. Default is 1.
1534 """
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001535 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001536 # Clear all previous events.
1537 ad.ed.clear_all_events()
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001538 ad.droid.wifiConnectByNetworkId(network_id)
1539 ad.log.info("Starting connection to network with id %d", network_id)
1540 try:
1541 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_NETID_SUCCESS, 60)
Roshan Piusd1204442018-11-12 12:20:39 -08001542 connect_result = _wait_for_connect_event(
Oscar Shucb9af9b2019-05-02 20:01:49 +00001543 ad, id=network_id, tries=num_of_tries)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001544 asserts.assert_true(connect_result,
1545 "Failed to connect to Wi-Fi network using network id")
1546 ad.log.debug("Wi-Fi connection result: %s", connect_result)
1547 actual_id = connect_result['data'][WifiEnums.NETID_KEY]
1548 asserts.assert_equal(actual_id, network_id,
1549 "Connected to the wrong network on %s."
1550 "Expected network id = %d, but got %d." %
1551 (ad.serial, network_id, actual_id))
1552 expected_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1553 ad.log.info("Connected to Wi-Fi network %s with %d network id.",
1554 expected_ssid, network_id)
1555
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001556 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1557 if not internet:
1558 raise signals.TestFailure("Failed to connect to internet on %s" %
1559 expected_ssid)
1560 except Empty:
1561 asserts.fail("Failed to connect to network with id %d on %s" %
1562 (network_id, ad.serial))
1563 except Exception as error:
1564 ad.log.error("Failed to connect to network with id %d with error %s",
1565 network_id, error)
1566 raise signals.TestFailure("Failed to connect to network with network"
1567 " id %d" % network_id)
1568 finally:
1569 ad.droid.wifiStopTrackingStateChange()
1570
Oscar Shu0b5ff4d2019-08-07 18:11:56 +00001571
Roshan Piusc999e5e2018-11-09 10:59:52 -08001572def wifi_connect_using_network_request(ad, network, network_specifier,
1573 num_of_tries=3, assert_on_fail=True):
1574 """Connect an Android device to a wifi network using network request.
1575
1576 Trigger a network request with the provided network specifier,
1577 wait for the "onMatch" event, ensure that the scan results in "onMatch"
1578 event contain the specified network, then simulate the user granting the
1579 request with the specified network selected. Then wait for the "onAvailable"
1580 network callback indicating successful connection to network.
1581
1582 This will directly fail a test if anything goes wrong.
1583
1584 Args:
1585 ad: android_device object to initiate connection on.
1586 network_specifier: A dictionary representing the network specifier to
1587 use.
1588 network: A dictionary representing the network to connect to. The
1589 dictionary must have the key "SSID".
1590 num_of_tries: An integer that is the number of times to try before
1591 delaring failure.
1592 assert_on_fail: If True, error checks in this function will raise test
1593 failure signals.
1594
1595 Returns:
1596 Returns a value only if assert_on_fail is false.
1597 Returns True if the connection was successful, False otherwise.
1598 """
1599 _assert_on_fail_handler(_wifi_connect_using_network_request, assert_on_fail,
1600 ad, network, network_specifier, num_of_tries)
1601
1602
1603def _wifi_connect_using_network_request(ad, network, network_specifier,
1604 num_of_tries=3):
1605 """Connect an Android device to a wifi network using network request.
1606
1607 Trigger a network request with the provided network specifier,
1608 wait for the "onMatch" event, ensure that the scan results in "onMatch"
1609 event contain the specified network, then simulate the user granting the
1610 request with the specified network selected. Then wait for the "onAvailable"
1611 network callback indicating successful connection to network.
1612
1613 Args:
1614 ad: android_device object to initiate connection on.
1615 network_specifier: A dictionary representing the network specifier to
1616 use.
1617 network: A dictionary representing the network to connect to. The
1618 dictionary must have the key "SSID".
1619 num_of_tries: An integer that is the number of times to try before
1620 delaring failure.
1621 """
1622 ad.droid.wifiRequestNetworkWithSpecifier(network_specifier)
1623 ad.log.info("Sent network request with %s", network_specifier)
1624 # Need a delay here because UI interaction should only start once wifi
1625 # starts processing the request.
1626 time.sleep(wifi_constants.NETWORK_REQUEST_CB_REGISTER_DELAY_SEC)
1627 _wait_for_wifi_connect_after_network_request(ad, network, num_of_tries)
1628
1629
1630def wait_for_wifi_connect_after_network_request(ad, network, num_of_tries=3,
1631 assert_on_fail=True):
1632 """
1633 Simulate and verify the connection flow after initiating the network
1634 request.
1635
1636 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1637 event contain the specified network, then simulate the user granting the
1638 request with the specified network selected. Then wait for the "onAvailable"
1639 network callback indicating successful connection to network.
1640
1641 Args:
1642 ad: android_device object to initiate connection on.
1643 network: A dictionary representing the network to connect to. The
1644 dictionary must have the key "SSID".
1645 num_of_tries: An integer that is the number of times to try before
1646 delaring failure.
1647 assert_on_fail: If True, error checks in this function will raise test
1648 failure signals.
1649
1650 Returns:
1651 Returns a value only if assert_on_fail is false.
1652 Returns True if the connection was successful, False otherwise.
1653 """
1654 _assert_on_fail_handler(_wait_for_wifi_connect_after_network_request,
1655 assert_on_fail, ad, network, num_of_tries)
1656
1657
1658def _wait_for_wifi_connect_after_network_request(ad, network, num_of_tries=3):
1659 """
1660 Simulate and verify the connection flow after initiating the network
1661 request.
1662
1663 Wait for the "onMatch" event, ensure that the scan results in "onMatch"
1664 event contain the specified network, then simulate the user granting the
1665 request with the specified network selected. Then wait for the "onAvailable"
1666 network callback indicating successful connection to network.
1667
1668 Args:
1669 ad: android_device object to initiate connection on.
1670 network: A dictionary representing the network to connect to. The
1671 dictionary must have the key "SSID".
1672 num_of_tries: An integer that is the number of times to try before
1673 delaring failure.
1674 """
1675 asserts.assert_true(WifiEnums.SSID_KEY in network,
1676 "Key '%s' must be present in network definition." %
1677 WifiEnums.SSID_KEY)
1678 ad.droid.wifiStartTrackingStateChange()
1679 expected_ssid = network[WifiEnums.SSID_KEY]
1680 ad.droid.wifiRegisterNetworkRequestMatchCallback()
1681 # Wait for the platform to scan and return a list of networks
1682 # matching the request
1683 try:
1684 matched_network = None
1685 for _ in [0, num_of_tries]:
1686 on_match_event = ad.ed.pop_event(
1687 wifi_constants.WIFI_NETWORK_REQUEST_MATCH_CB_ON_MATCH, 60)
1688 asserts.assert_true(on_match_event,
1689 "Network request on match not received.")
1690 matched_scan_results = on_match_event["data"]
1691 ad.log.debug("Network request on match results %s",
1692 matched_scan_results)
1693 matched_network = match_networks(
1694 {WifiEnums.SSID_KEY: network[WifiEnums.SSID_KEY]},
1695 matched_scan_results)
1696 if matched_network:
1697 break;
1698
1699 asserts.assert_true(
1700 matched_network, "Target network %s not found" % network)
1701
1702 ad.droid.wifiSendUserSelectionForNetworkRequestMatch(network)
1703 ad.log.info("Sent user selection for network request %s",
1704 expected_ssid)
1705
1706 # Wait for the platform to connect to the network.
1707 on_available_event = ad.ed.pop_event(
1708 wifi_constants.WIFI_NETWORK_CB_ON_AVAILABLE, 60)
1709 asserts.assert_true(on_available_event,
1710 "Network request on available not received.")
1711 connected_network = on_available_event["data"]
1712 ad.log.info("Connected to network %s", connected_network)
1713 asserts.assert_equal(connected_network[WifiEnums.SSID_KEY],
1714 expected_ssid,
1715 "Connected to the wrong network."
1716 "Expected %s, but got %s." %
1717 (network, connected_network))
1718 except Empty:
1719 asserts.fail("Failed to connect to %s" % expected_ssid)
1720 except Exception as error:
1721 ad.log.error("Failed to connect to %s with error %s",
1722 (expected_ssid, error))
1723 raise signals.TestFailure("Failed to connect to %s network" % network)
1724 finally:
1725 ad.droid.wifiStopTrackingStateChange()
1726
1727
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001728def wifi_passpoint_connect(ad, passpoint_network, num_of_tries=1,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001729 assert_on_fail=True):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001730 """Connect an Android device to a wifi network.
1731
1732 Initiate connection to a wifi network, wait for the "connected" event, then
1733 confirm the connected ssid is the one requested.
1734
1735 This will directly fail a test if anything goes wrong.
1736
1737 Args:
1738 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001739 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001740 num_of_tries: An integer that is the number of times to try before
1741 delaring failure. Default is 1.
1742 assert_on_fail: If True, error checks in this function will raise test
1743 failure signals.
1744
1745 Returns:
1746 If assert_on_fail is False, function returns network id, if the connect was
1747 successful, False otherwise. If assert_on_fail is True, no return value.
1748 """
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001749 _assert_on_fail_handler(_wifi_passpoint_connect, assert_on_fail, ad,
Oscar Shucb9af9b2019-05-02 20:01:49 +00001750 passpoint_network, num_of_tries = num_of_tries)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001751
1752
Oscar Shucb9af9b2019-05-02 20:01:49 +00001753def _wifi_passpoint_connect(ad, passpoint_network, num_of_tries=1):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001754 """Connect an Android device to a wifi network.
1755
1756 Initiate connection to a wifi network, wait for the "connected" event, then
1757 confirm the connected ssid is the one requested.
1758
1759 This will directly fail a test if anything goes wrong.
1760
1761 Args:
1762 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001763 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001764 num_of_tries: An integer that is the number of times to try before
1765 delaring failure. Default is 1.
1766 """
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001767 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001768 expected_ssid = passpoint_network
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001769 ad.log.info("Starting connection process to passpoint %s", expected_ssid)
1770
1771 try:
Roshan Piusd1204442018-11-12 12:20:39 -08001772 connect_result = _wait_for_connect_event(
Oscar Shucb9af9b2019-05-02 20:01:49 +00001773 ad, expected_ssid, num_of_tries)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001774 asserts.assert_true(connect_result,
1775 "Failed to connect to WiFi passpoint network %s on"
1776 " %s" % (expected_ssid, ad.serial))
1777 ad.log.info("Wi-Fi connection result: %s.", connect_result)
1778 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1779 asserts.assert_equal(actual_ssid, expected_ssid,
1780 "Connected to the wrong network on %s." % ad.serial)
1781 ad.log.info("Connected to Wi-Fi passpoint network %s.", actual_ssid)
1782
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001783 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1784 if not internet:
1785 raise signals.TestFailure("Failed to connect to internet on %s" %
1786 expected_ssid)
1787 except Exception as error:
1788 ad.log.error("Failed to connect to passpoint network %s with error %s",
1789 expected_ssid, error)
1790 raise signals.TestFailure("Failed to connect to %s passpoint network" %
1791 expected_ssid)
1792
1793 finally:
1794 ad.droid.wifiStopTrackingStateChange()
1795
1796
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001797def delete_passpoint(ad, fqdn):
1798 """Delete a required Passpoint configuration."""
1799 try:
1800 ad.droid.removePasspointConfig(fqdn)
1801 return True
1802 except Exception as error:
1803 ad.log.error("Failed to remove passpoint configuration with FQDN=%s "
1804 "and error=%s" , fqdn, error)
1805 return False
1806
1807
Ang Li73697b32015-12-03 00:41:53 +00001808def start_wifi_single_scan(ad, scan_setting):
1809 """Starts wifi single shot scan.
1810
1811 Args:
1812 ad: android_device object to initiate connection on.
1813 scan_setting: A dict representing the settings of the scan.
1814
1815 Returns:
1816 If scan was started successfully, event data of success event is returned.
1817 """
Ang Li82522812016-06-02 13:57:21 -07001818 idx = ad.droid.wifiScannerStartScan(scan_setting)
1819 event = ad.ed.pop_event("WifiScannerScan%sonSuccess" % idx, SHORT_TIMEOUT)
Ang Li31b00782016-06-21 13:04:23 -07001820 ad.log.debug("Got event %s", event)
Ang Li73697b32015-12-03 00:41:53 +00001821 return event['data']
1822
Ang Li82522812016-06-02 13:57:21 -07001823
Ang Li73697b32015-12-03 00:41:53 +00001824def track_connection(ad, network_ssid, check_connection_count):
1825 """Track wifi connection to network changes for given number of counts
1826
1827 Args:
1828 ad: android_device object for forget network.
1829 network_ssid: network ssid to which connection would be tracked
1830 check_connection_count: Integer for maximum number network connection
Ang Li82522812016-06-02 13:57:21 -07001831 check.
Ang Li73697b32015-12-03 00:41:53 +00001832 Returns:
Ang Li73697b32015-12-03 00:41:53 +00001833 True if connection to given network happen, else return False.
1834 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001835 ad.droid.wifiStartTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001836 while check_connection_count > 0:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001837 connect_network = ad.ed.pop_event("WifiNetworkConnected", 120)
Ang Li31b00782016-06-21 13:04:23 -07001838 ad.log.info("Connected to network %s", connect_network)
Ang Li82522812016-06-02 13:57:21 -07001839 if (WifiEnums.SSID_KEY in connect_network['data'] and
1840 connect_network['data'][WifiEnums.SSID_KEY] == network_ssid):
1841 return True
Ang Li8e767182015-12-09 17:29:24 -08001842 check_connection_count -= 1
Girish Moturu40d7dc22016-11-02 12:14:56 -07001843 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001844 return False
1845
Ang Li82522812016-06-02 13:57:21 -07001846
Ang Li73697b32015-12-03 00:41:53 +00001847def get_scan_time_and_channels(wifi_chs, scan_setting, stime_channel):
1848 """Calculate the scan time required based on the band or channels in scan
1849 setting
1850
1851 Args:
1852 wifi_chs: Object of channels supported
1853 scan_setting: scan setting used for start scan
1854 stime_channel: scan time per channel
1855
1856 Returns:
1857 scan_time: time required for completing a scan
1858 scan_channels: channel used for scanning
1859 """
1860 scan_time = 0
1861 scan_channels = []
1862 if "band" in scan_setting and "channels" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001863 scan_channels = wifi_chs.band_to_freq(scan_setting["band"])
Ang Li73697b32015-12-03 00:41:53 +00001864 elif "channels" in scan_setting and "band" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001865 scan_channels = scan_setting["channels"]
Ang Li73697b32015-12-03 00:41:53 +00001866 scan_time = len(scan_channels) * stime_channel
1867 for channel in scan_channels:
Ang Li8e767182015-12-09 17:29:24 -08001868 if channel in WifiEnums.DFS_5G_FREQUENCIES:
Ang Li82522812016-06-02 13:57:21 -07001869 scan_time += 132 #passive scan time on DFS
Ang Li73697b32015-12-03 00:41:53 +00001870 return scan_time, scan_channels
1871
Ang Li82522812016-06-02 13:57:21 -07001872
Ang Li73697b32015-12-03 00:41:53 +00001873def start_wifi_track_bssid(ad, track_setting):
1874 """Start tracking Bssid for the given settings.
1875
1876 Args:
1877 ad: android_device object.
1878 track_setting: Setting for which the bssid tracking should be started
1879
1880 Returns:
1881 If tracking started successfully, event data of success event is returned.
1882 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001883 idx = ad.droid.wifiScannerStartTrackingBssids(
Ang Li82522812016-06-02 13:57:21 -07001884 track_setting["bssidInfos"], track_setting["apLostThreshold"])
Girish Moturu40d7dc22016-11-02 12:14:56 -07001885 event = ad.ed.pop_event("WifiScannerBssid{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -08001886 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +00001887 return event['data']
1888
Ang Li82522812016-06-02 13:57:21 -07001889
Ang Li73697b32015-12-03 00:41:53 +00001890def convert_pem_key_to_pkcs8(in_file, out_file):
1891 """Converts the key file generated by us to the format required by
1892 Android using openssl.
1893
1894 The input file must have the extension "pem". The output file must
1895 have the extension "der".
1896
1897 Args:
1898 in_file: The original key file.
1899 out_file: The full path to the converted key file, including
1900 filename.
1901 """
Ang Li82522812016-06-02 13:57:21 -07001902 asserts.assert_true(in_file.endswith(".pem"), "Input file has to be .pem.")
1903 asserts.assert_true(
1904 out_file.endswith(".der"), "Output file has to be .der.")
Ang Li73697b32015-12-03 00:41:53 +00001905 cmd = ("openssl pkcs8 -inform PEM -in {} -outform DER -out {} -nocrypt"
1906 " -topk8").format(in_file, out_file)
Ang Lifee28402016-07-13 13:43:29 -07001907 utils.exe_cmd(cmd)
Ang Li73697b32015-12-03 00:41:53 +00001908
Ang Li82522812016-06-02 13:57:21 -07001909
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08001910def validate_connection(ad, ping_addr=DEFAULT_PING_ADDR, wait_time=15,
Girish Moturu804a3492020-02-17 14:32:02 -08001911 ping_gateway=True):
Ang Li73697b32015-12-03 00:41:53 +00001912 """Validate internet connection by pinging the address provided.
1913
1914 Args:
1915 ad: android_device object.
1916 ping_addr: address on internet for pinging.
Girish Moturua2a5bf22019-08-16 09:52:29 -07001917 wait_time: wait for some time before validating connection
Ang Li73697b32015-12-03 00:41:53 +00001918
1919 Returns:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001920 ping output if successful, NULL otherwise.
Ang Li73697b32015-12-03 00:41:53 +00001921 """
Girish Moturua2a5bf22019-08-16 09:52:29 -07001922 # wait_time to allow for DHCP to complete.
Hsiu-Chang Chend7b3c572020-06-12 12:19:30 +08001923 for i in range(wait_time):
1924 if ad.droid.connectivityNetworkIsConnected():
1925 break
1926 time.sleep(1)
Girish Moturu804a3492020-02-17 14:32:02 -08001927 ping = False
1928 try:
1929 ping = ad.droid.httpPing(ping_addr)
1930 ad.log.info("Http ping result: %s.", ping)
1931 except:
1932 pass
1933 if not ping and ping_gateway:
1934 ad.log.info("Http ping failed. Pinging default gateway")
1935 gw = ad.droid.connectivityGetIPv4DefaultGateway()
1936 result = ad.adb.shell("ping -c 6 {}".format(gw))
1937 ad.log.info("Default gateway ping result: %s" % result)
1938 ping = False if "100% packet loss" in result else True
Ang Li73697b32015-12-03 00:41:53 +00001939 return ping
1940
Ang Li82522812016-06-02 13:57:21 -07001941
Ang Li73697b32015-12-03 00:41:53 +00001942#TODO(angli): This can only verify if an actual value is exactly the same.
1943# Would be nice to be able to verify an actual value is one of serveral.
1944def verify_wifi_connection_info(ad, expected_con):
1945 """Verifies that the information of the currently connected wifi network is
1946 as expected.
1947
1948 Args:
1949 expected_con: A dict representing expected key-value pairs for wifi
1950 connection. e.g. {"SSID": "test_wifi"}
1951 """
1952 current_con = ad.droid.wifiGetConnectionInfo()
Ang Li374d7602016-02-08 17:27:27 -08001953 case_insensitive = ["BSSID", "supplicant_state"]
Ang Li31b00782016-06-21 13:04:23 -07001954 ad.log.debug("Current connection: %s", current_con)
Ang Li73697b32015-12-03 00:41:53 +00001955 for k, expected_v in expected_con.items():
Ang Li9a66de72016-02-08 15:26:38 -08001956 # Do not verify authentication related fields.
1957 if k == "password":
1958 continue
Ang Li82522812016-06-02 13:57:21 -07001959 msg = "Field %s does not exist in wifi connection info %s." % (
1960 k, current_con)
Ang Li374d7602016-02-08 17:27:27 -08001961 if k not in current_con:
1962 raise signals.TestFailure(msg)
1963 actual_v = current_con[k]
1964 if k in case_insensitive:
1965 actual_v = actual_v.lower()
1966 expected_v = expected_v.lower()
Ang Li73697b32015-12-03 00:41:53 +00001967 msg = "Expected %s to be %s, actual %s is %s." % (k, expected_v, k,
Ang Li82522812016-06-02 13:57:21 -07001968 actual_v)
Ang Li374d7602016-02-08 17:27:27 -08001969 if actual_v != expected_v:
1970 raise signals.TestFailure(msg)
Ang Li73697b32015-12-03 00:41:53 +00001971
Ang Li82522812016-06-02 13:57:21 -07001972
Preetesh Barrettoe8c428b2019-02-14 09:15:44 -08001973def check_autoconnect_to_open_network(ad, conn_timeout=WIFI_CONNECTION_TIMEOUT_DEFAULT):
1974 """Connects to any open WiFI AP
1975 Args:
1976 timeout value in sec to wait for UE to connect to a WiFi AP
1977 Returns:
1978 True if UE connects to WiFi AP (supplicant_state = completed)
1979 False if UE fails to complete connection within WIFI_CONNECTION_TIMEOUT time.
1980 """
1981 if ad.droid.wifiCheckState():
1982 return True
1983 ad.droid.wifiToggleState()
1984 wifi_connection_state = None
1985 timeout = time.time() + conn_timeout
1986 while wifi_connection_state != "completed":
1987 wifi_connection_state = ad.droid.wifiGetConnectionInfo()[
1988 'supplicant_state']
1989 if time.time() > timeout:
1990 ad.log.warning("Failed to connect to WiFi AP")
1991 return False
1992 return True
1993
1994
Ang Li73697b32015-12-03 00:41:53 +00001995def expand_enterprise_config_by_phase2(config):
1996 """Take an enterprise config and generate a list of configs, each with
1997 a different phase2 auth type.
1998
1999 Args:
2000 config: A dict representing enterprise config.
2001
2002 Returns
2003 A list of enterprise configs.
2004 """
2005 results = []
Ang Li0e7e58f2016-02-22 12:15:02 -08002006 phase2_types = WifiEnums.EapPhase2
2007 if config[WifiEnums.Enterprise.EAP] == WifiEnums.Eap.PEAP:
2008 # Skip unsupported phase2 types for PEAP.
2009 phase2_types = [WifiEnums.EapPhase2.GTC, WifiEnums.EapPhase2.MSCHAPV2]
2010 for phase2_type in phase2_types:
Ang Li73697b32015-12-03 00:41:53 +00002011 # Skip a special case for passpoint TTLS.
2012 if (WifiEnums.Enterprise.FQDN in config and
Ang Li82522812016-06-02 13:57:21 -07002013 phase2_type == WifiEnums.EapPhase2.GTC):
Ang Li73697b32015-12-03 00:41:53 +00002014 continue
2015 c = dict(config)
Girish Moturu150d32f2017-02-14 12:27:07 -08002016 c[WifiEnums.Enterprise.PHASE2] = phase2_type.value
Ang Li73697b32015-12-03 00:41:53 +00002017 results.append(c)
2018 return results
Ang Li2d3fe982016-06-08 10:00:43 -07002019
2020
Girish Moturub48a13c2017-02-27 11:36:42 -08002021def generate_eap_test_name(config, ad=None):
Girish Moturu150d32f2017-02-14 12:27:07 -08002022 """ Generates a test case name based on an EAP configuration.
2023
2024 Args:
2025 config: A dict representing an EAP credential.
Girish Moturub48a13c2017-02-27 11:36:42 -08002026 ad object: Redundant but required as the same param is passed
2027 to test_func in run_generated_tests
Girish Moturu150d32f2017-02-14 12:27:07 -08002028
2029 Returns:
2030 A string representing the name of a generated EAP test case.
2031 """
2032 eap = WifiEnums.Eap
2033 eap_phase2 = WifiEnums.EapPhase2
Girish Moturub48a13c2017-02-27 11:36:42 -08002034 Ent = WifiEnums.Enterprise
Girish Moturu150d32f2017-02-14 12:27:07 -08002035 name = "test_connect-"
2036 eap_name = ""
2037 for e in eap:
2038 if e.value == config[Ent.EAP]:
2039 eap_name = e.name
2040 break
2041 if "peap0" in config[WifiEnums.SSID_KEY].lower():
2042 eap_name = "PEAP0"
2043 if "peap1" in config[WifiEnums.SSID_KEY].lower():
2044 eap_name = "PEAP1"
2045 name += eap_name
2046 if Ent.PHASE2 in config:
2047 for e in eap_phase2:
2048 if e.value == config[Ent.PHASE2]:
2049 name += "-{}".format(e.name)
2050 break
2051 return name
2052
2053
Ang Li2d3fe982016-06-08 10:00:43 -07002054def group_attenuators(attenuators):
2055 """Groups a list of attenuators into attenuator groups for backward
2056 compatibility reasons.
2057
2058 Most legacy Wi-Fi setups have two attenuators each connected to a separate
2059 AP. The new Wi-Fi setup has four attenuators, each connected to one channel
2060 on an AP, so two of them are connected to one AP.
2061
2062 To make the existing scripts work in the new setup, when the script needs
2063 to attenuate one AP, it needs to set attenuation on both attenuators
2064 connected to the same AP.
2065
2066 This function groups attenuators properly so the scripts work in both
2067 legacy and new Wi-Fi setups.
2068
2069 Args:
2070 attenuators: A list of attenuator objects, either two or four in length.
2071
2072 Raises:
2073 signals.TestFailure is raised if the attenuator list does not have two
2074 or four objects.
2075 """
2076 attn0 = attenuator.AttenuatorGroup("AP0")
2077 attn1 = attenuator.AttenuatorGroup("AP1")
2078 # Legacy testbed setup has two attenuation channels.
2079 num_of_attns = len(attenuators)
2080 if num_of_attns == 2:
2081 attn0.add(attenuators[0])
2082 attn1.add(attenuators[1])
2083 elif num_of_attns == 4:
2084 attn0.add(attenuators[0])
2085 attn0.add(attenuators[1])
2086 attn1.add(attenuators[2])
2087 attn1.add(attenuators[3])
2088 else:
2089 asserts.fail(("Either two or four attenuators are required for this "
2090 "test, but found %s") % num_of_attns)
2091 return [attn0, attn1]
Jong Wook Kim92356922018-02-06 18:32:49 -08002092
Bindu Mahadevff295782019-02-08 16:17:48 -08002093
Girish Moturu36348a32019-12-10 08:41:54 -08002094def set_attns(attenuator, attn_val_name, roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002095 """Sets attenuation values on attenuators used in this test.
2096
2097 Args:
2098 attenuator: The attenuator object.
2099 attn_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002100 roaming_attn: Dictionary specifying the attenuation params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002101 """
2102 logging.info("Set attenuation values to %s", roaming_attn[attn_val_name])
2103 try:
2104 attenuator[0].set_atten(roaming_attn[attn_val_name][0])
2105 attenuator[1].set_atten(roaming_attn[attn_val_name][1])
2106 attenuator[2].set_atten(roaming_attn[attn_val_name][2])
2107 attenuator[3].set_atten(roaming_attn[attn_val_name][3])
2108 except:
2109 logging.exception("Failed to set attenuation values %s.",
2110 attn_val_name)
2111 raise
2112
Girish Moturu36348a32019-12-10 08:41:54 -08002113def set_attns_steps(attenuators,
2114 atten_val_name,
2115 roaming_attn=ROAMING_ATTN,
2116 steps=10,
2117 wait_time=12):
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002118 """Set attenuation values on attenuators used in this test. It will change
2119 the attenuation values linearly from current value to target value step by
2120 step.
2121
2122 Args:
2123 attenuators: The list of attenuator objects that you want to change
2124 their attenuation value.
2125 atten_val_name: Name of the attenuation value pair to use.
Girish Moturu36348a32019-12-10 08:41:54 -08002126 roaming_attn: Dictionary specifying the attenuation params.
Hsiu-Chang Chen73ea3342019-05-22 11:20:08 +08002127 steps: Number of attenuator changes to reach the target value.
2128 wait_time: Sleep time for each change of attenuator.
2129 """
2130 logging.info("Set attenuation values to %s in %d step(s)",
2131 roaming_attn[atten_val_name], steps)
2132 start_atten = [attenuator.get_atten() for attenuator in attenuators]
2133 target_atten = roaming_attn[atten_val_name]
2134 for current_step in range(steps):
2135 progress = (current_step + 1) / steps
2136 for i, attenuator in enumerate(attenuators):
2137 amount_since_start = (target_atten[i] - start_atten[i]) * progress
2138 attenuator.set_atten(round(start_atten[i] + amount_since_start))
2139 time.sleep(wait_time)
2140
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002141
Girish Moturu36348a32019-12-10 08:41:54 -08002142def trigger_roaming_and_validate(dut,
2143 attenuator,
2144 attn_val_name,
2145 expected_con,
2146 roaming_attn=ROAMING_ATTN):
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002147 """Sets attenuators to trigger roaming and validate the DUT connected
2148 to the BSSID expected.
2149
2150 Args:
2151 attenuator: The attenuator object.
2152 attn_val_name: Name of the attenuation value pair to use.
2153 expected_con: The network information of the expected network.
Girish Moturu36348a32019-12-10 08:41:54 -08002154 roaming_attn: Dictionary specifying the attenaution params.
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002155 """
2156 expected_con = {
2157 WifiEnums.SSID_KEY: expected_con[WifiEnums.SSID_KEY],
2158 WifiEnums.BSSID_KEY: expected_con["bssid"],
2159 }
Girish Moturu36348a32019-12-10 08:41:54 -08002160 set_attns_steps(attenuator, attn_val_name, roaming_attn)
Bindu Mahadev7060a9f2018-05-04 13:48:12 -07002161
Hsiu-Chang Chenef856402018-09-18 12:32:49 +08002162 verify_wifi_connection_info(dut, expected_con)
2163 expected_bssid = expected_con[WifiEnums.BSSID_KEY]
2164 logging.info("Roamed to %s successfully", expected_bssid)
2165 if not validate_connection(dut):
2166 raise signals.TestFailure("Fail to connect to internet on %s" %
2167 expected_bssid)
Jong Wook Kim92356922018-02-06 18:32:49 -08002168
2169def create_softap_config():
2170 """Create a softap config with random ssid and password."""
2171 ap_ssid = "softap_" + utils.rand_ascii_str(8)
2172 ap_password = utils.rand_ascii_str(8)
2173 logging.info("softap setup: %s %s", ap_ssid, ap_password)
2174 config = {
2175 WifiEnums.SSID_KEY: ap_ssid,
2176 WifiEnums.PWD_KEY: ap_password,
2177 }
2178 return config
Girish Moturucf4dccd2018-08-27 12:22:00 -07002179
Bindu Mahadevff295782019-02-08 16:17:48 -08002180def start_softap_and_verify(ad, band):
2181 """Bring-up softap and verify AP mode and in scan results.
2182
2183 Args:
2184 band: The band to use for softAP.
2185
2186 Returns: dict, the softAP config.
2187
2188 """
lesl2f0fb232019-11-05 16:35:28 +08002189 # Register before start the test.
2190 callbackId = ad.dut.droid.registerSoftApCallback()
2191 # Check softap info value is default
2192 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2193 asserts.assert_true(frequency == 0, "Softap frequency is not reset")
2194 asserts.assert_true(bandwdith == 0, "Softap bandwdith is not reset")
2195
Bindu Mahadevff295782019-02-08 16:17:48 -08002196 config = create_softap_config()
2197 start_wifi_tethering(ad.dut,
2198 config[WifiEnums.SSID_KEY],
2199 config[WifiEnums.PWD_KEY], band=band)
2200 asserts.assert_true(ad.dut.droid.wifiIsApEnabled(),
2201 "SoftAp is not reported as running")
2202 start_wifi_connection_scan_and_ensure_network_found(ad.dut_client,
2203 config[WifiEnums.SSID_KEY])
lesl2f0fb232019-11-05 16:35:28 +08002204
2205 # Check softap info can get from callback succeed and assert value should be
2206 # valid.
2207 frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True)
2208 asserts.assert_true(frequency > 0, "Softap frequency is not valid")
2209 asserts.assert_true(bandwdith > 0, "Softap bandwdith is not valid")
2210 # Unregister callback
2211 ad.dut.droid.unregisterSoftApCallback(callbackId)
2212
Bindu Mahadevff295782019-02-08 16:17:48 -08002213 return config
2214
lesle8e3c0a2019-02-22 17:06:04 +08002215def wait_for_expected_number_of_softap_clients(ad, callbackId,
2216 expected_num_of_softap_clients):
2217 """Wait for the number of softap clients to be updated as expected.
2218 Args:
2219 callbackId: Id of the callback associated with registering.
2220 expected_num_of_softap_clients: expected number of softap clients.
2221 """
2222 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
2223 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
James Mattis5a5dd492020-05-14 13:09:43 -07002224 clientData = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data']
2225 clientCount = clientData[wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
2226 clientMacAddresses = clientData[wifi_constants.SOFTAP_CLIENTS_MACS_CALLBACK_KEY]
2227 asserts.assert_equal(clientCount, expected_num_of_softap_clients,
2228 "The number of softap clients doesn't match the expected number")
2229 asserts.assert_equal(len(clientMacAddresses), expected_num_of_softap_clients,
2230 "The number of mac addresses doesn't match the expected number")
2231 for macAddress in clientMacAddresses:
2232 asserts.assert_true(checkMacAddress(macAddress), "An invalid mac address was returned")
2233
2234def checkMacAddress(input):
2235 """Validate whether a string is a valid mac address or not.
2236
2237 Args:
2238 input: The string to validate.
2239
2240 Returns: True/False, returns true for a valid mac address and false otherwise.
2241 """
2242 macValidationRegex = "[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$"
2243 if re.match(macValidationRegex, input.lower()):
2244 return True
2245 return False
lesle8e3c0a2019-02-22 17:06:04 +08002246
2247def wait_for_expected_softap_state(ad, callbackId, expected_softap_state):
2248 """Wait for the expected softap state change.
2249 Args:
2250 callbackId: Id of the callback associated with registering.
2251 expected_softap_state: The expected softap state.
2252 """
2253 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
2254 callbackId) + wifi_constants.SOFTAP_STATE_CHANGED
2255 asserts.assert_equal(ad.ed.pop_event(eventStr,
2256 SHORT_TIMEOUT)['data'][wifi_constants.
2257 SOFTAP_STATE_CHANGE_CALLBACK_KEY],
2258 expected_softap_state,
2259 "Softap state doesn't match with expected state")
2260
2261def get_current_number_of_softap_clients(ad, callbackId):
2262 """pop up all of softap client updated event from queue.
2263 Args:
2264 callbackId: Id of the callback associated with registering.
2265
2266 Returns:
2267 If exist aleast callback, returns last updated number_of_softap_clients.
2268 Returns None when no any match callback event in queue.
2269 """
2270 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
2271 callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED
2272 events = ad.ed.pop_all(eventStr)
2273 for event in events:
2274 num_of_clients = event['data'][wifi_constants.
2275 SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY]
2276 if len(events) == 0:
2277 return None
2278 return num_of_clients
Bindu Mahadevff295782019-02-08 16:17:48 -08002279
lesl2f0fb232019-11-05 16:35:28 +08002280def get_current_softap_info(ad, callbackId, least_one):
2281 """pop up all of softap info changed event from queue.
2282 Args:
2283 callbackId: Id of the callback associated with registering.
2284 least_one: Wait for the info callback event before pop all.
2285 Returns:
2286 Returns last updated information of softap.
2287 """
2288 eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str(
2289 callbackId) + wifi_constants.SOFTAP_INFO_CHANGED
2290 ad.log.info("softap info dump from eventStr %s",
2291 eventStr)
2292 frequency = 0
2293 bandwidth = 0
2294 if (least_one):
2295 event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)
2296 frequency = event['data'][wifi_constants.
2297 SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2298 bandwidth = event['data'][wifi_constants.
2299 SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
2300 ad.log.info("softap info updated, frequency is %s, bandwidth is %s",
2301 frequency, bandwidth)
2302
2303 events = ad.ed.pop_all(eventStr)
2304 for event in events:
2305 frequency = event['data'][wifi_constants.
2306 SOFTAP_INFO_FREQUENCY_CALLBACK_KEY]
2307 bandwidth = event['data'][wifi_constants.
2308 SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY]
2309 ad.log.info("softap info, frequency is %s, bandwidth is %s",
2310 frequency, bandwidth)
2311 return frequency, bandwidth
2312
2313
2314
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002315def get_ssrdumps(ad):
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002316 """Pulls dumps in the ssrdump dir
2317 Args:
2318 ad: android device object.
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002319 """
2320 logs = ad.get_file_names("/data/vendor/ssrdump/")
2321 if logs:
2322 ad.log.info("Pulling ssrdumps %s", logs)
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002323 log_path = os.path.join(ad.device_log_path, "SSRDUMPS_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002324 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002325 ad.pull_files(logs, log_path)
Hsiu-Chang Chen769bef12020-10-10 06:07:52 +00002326 ad.adb.shell("find /data/vendor/ssrdump/ -type f -delete",
2327 ignore_status=True)
Hsiu-Chang Chen6aac0d32019-05-15 14:21:08 +08002328
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002329def start_pcap(pcap, wifi_band, test_name):
Girish Moturucf4dccd2018-08-27 12:22:00 -07002330 """Start packet capture in monitor mode.
2331
2332 Args:
2333 pcap: packet capture object
2334 wifi_band: '2g' or '5g' or 'dual'
Bindu Mahadev76551c12018-12-13 19:42:14 +00002335 test_name: test name to be used for pcap file name
2336
2337 Returns:
xianyuanjia0431ba32018-12-14 09:56:42 -08002338 Dictionary with wifi band as key and the tuple
2339 (pcap Process object, log directory) as the value
Girish Moturucf4dccd2018-08-27 12:22:00 -07002340 """
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002341 log_dir = os.path.join(
Xianyuan Jia5cd06bb2019-06-10 16:29:57 -07002342 context.get_current_context().get_full_output_path(), 'PacketCapture')
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002343 os.makedirs(log_dir, exist_ok=True)
Girish Moturucf4dccd2018-08-27 12:22:00 -07002344 if wifi_band == 'dual':
2345 bands = [BAND_2G, BAND_5G]
2346 else:
2347 bands = [wifi_band]
xianyuanjia0431ba32018-12-14 09:56:42 -08002348 procs = {}
Girish Moturucf4dccd2018-08-27 12:22:00 -07002349 for band in bands:
xianyuanjia0431ba32018-12-14 09:56:42 -08002350 proc = pcap.start_packet_capture(band, log_dir, test_name)
2351 procs[band] = (proc, os.path.join(log_dir, test_name))
2352 return procs
Girish Moturucf4dccd2018-08-27 12:22:00 -07002353
Bindu Mahadevff295782019-02-08 16:17:48 -08002354
xianyuanjia0431ba32018-12-14 09:56:42 -08002355def stop_pcap(pcap, procs, test_status=None):
Bindu Mahadev76551c12018-12-13 19:42:14 +00002356 """Stop packet capture in monitor mode.
2357
2358 Since, the pcap logs in monitor mode can be very large, we will
2359 delete them if they are not required. 'test_status' if True, will delete
2360 the pcap files. If False, we will keep them.
Girish Moturucf4dccd2018-08-27 12:22:00 -07002361
2362 Args:
2363 pcap: packet capture object
xianyuanjia0431ba32018-12-14 09:56:42 -08002364 procs: dictionary returned by start_pcap
Bindu Mahadev76551c12018-12-13 19:42:14 +00002365 test_status: status of the test case
Girish Moturucf4dccd2018-08-27 12:22:00 -07002366 """
xianyuanjia0431ba32018-12-14 09:56:42 -08002367 for proc, fname in procs.values():
2368 pcap.stop_packet_capture(proc)
Bindu Mahadev76551c12018-12-13 19:42:14 +00002369
2370 if test_status:
xianyuanjia0431ba32018-12-14 09:56:42 -08002371 shutil.rmtree(os.path.dirname(fname))
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002372
Jaineel95887fd2019-10-16 16:19:01 -07002373def verify_mac_not_found_in_pcap(ad, mac, packets):
xshuf7267682019-06-03 14:41:56 -07002374 """Verify that a mac address is not found in the captured packets.
2375
2376 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002377 ad: android device object
xshuf7267682019-06-03 14:41:56 -07002378 mac: string representation of the mac address
2379 packets: packets obtained by rdpcap(pcap_fname)
2380 """
2381 for pkt in packets:
2382 logging.debug("Packet Summary = %s", pkt.summary())
2383 if mac in pkt.summary():
Jaineel95887fd2019-10-16 16:19:01 -07002384 asserts.fail("Device %s caught Factory MAC: %s in packet sniffer."
2385 "Packet = %s" % (ad.serial, mac, pkt.show()))
Bindu Mahadevff295782019-02-08 16:17:48 -08002386
Jaineel95887fd2019-10-16 16:19:01 -07002387def verify_mac_is_found_in_pcap(ad, mac, packets):
Nate Jiangc2c09c62019-06-05 17:26:08 -07002388 """Verify that a mac address is found in the captured packets.
2389
2390 Args:
Jaineel95887fd2019-10-16 16:19:01 -07002391 ad: android device object
Nate Jiangc2c09c62019-06-05 17:26:08 -07002392 mac: string representation of the mac address
2393 packets: packets obtained by rdpcap(pcap_fname)
2394 """
2395 for pkt in packets:
2396 if mac in pkt.summary():
2397 return
Jaineel95887fd2019-10-16 16:19:01 -07002398 asserts.fail("Did not find MAC = %s in packet sniffer."
2399 "for device %s" % (mac, ad.serial))
Nate Jiangc2c09c62019-06-05 17:26:08 -07002400
Girish Moturuddc0d382020-08-24 12:08:41 -07002401def start_cnss_diags(ads, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002402 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002403 start_cnss_diag(ad, cnss_diag_file, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002404
Bindu Mahadevff295782019-02-08 16:17:48 -08002405
Girish Moturuddc0d382020-08-24 12:08:41 -07002406def start_cnss_diag(ad, cnss_diag_file, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002407 """Start cnss_diag to record extra wifi logs
2408
2409 Args:
2410 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002411 cnss_diag_file: cnss diag config file to push to device.
2412 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002413 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002414 if ad.model not in pixel_models:
2415 ad.log.info("Device not supported to collect pixel logger")
2416 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002417 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2418 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2419 else:
2420 prop = wifi_constants.CNSS_DIAG_PROP
2421 if ad.adb.getprop(prop) != 'true':
Girish Moturuddc0d382020-08-24 12:08:41 -07002422 if not int(ad.adb.shell("ls -l %s%s | wc -l" %
2423 (CNSS_DIAG_CONFIG_PATH,
2424 CNSS_DIAG_CONFIG_FILE))):
2425 ad.adb.push("%s %s" % (cnss_diag_file, CNSS_DIAG_CONFIG_PATH))
Hsiu-Chang Chen769bef12020-10-10 06:07:52 +00002426 ad.adb.shell("find /data/vendor/wifi/cnss_diag/wlan_logs/ -type f -delete",
2427 ignore_status=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002428 ad.adb.shell("setprop %s true" % prop, ignore_status=True)
2429
Bindu Mahadevff295782019-02-08 16:17:48 -08002430
Girish Moturuddc0d382020-08-24 12:08:41 -07002431def stop_cnss_diags(ads, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002432 for ad in ads:
Girish Moturuddc0d382020-08-24 12:08:41 -07002433 stop_cnss_diag(ad, pixel_models)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002434
Bindu Mahadevff295782019-02-08 16:17:48 -08002435
Girish Moturuddc0d382020-08-24 12:08:41 -07002436def stop_cnss_diag(ad, pixel_models):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002437 """Stops cnss_diag
2438
2439 Args:
2440 ad: android device object.
Girish Moturuddc0d382020-08-24 12:08:41 -07002441 pixel_models: pixel devices.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002442 """
Girish Moturuddc0d382020-08-24 12:08:41 -07002443 if ad.model not in pixel_models:
2444 ad.log.info("Device not supported to collect pixel logger")
2445 return
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002446 if ad.model in wifi_constants.DEVICES_USING_LEGACY_PROP:
2447 prop = wifi_constants.LEGACY_CNSS_DIAG_PROP
2448 else:
2449 prop = wifi_constants.CNSS_DIAG_PROP
2450 ad.adb.shell("setprop %s false" % prop, ignore_status=True)
2451
Bindu Mahadevff295782019-02-08 16:17:48 -08002452
Hsiu-Chang Chenebb239d2020-09-16 15:12:34 +08002453def get_cnss_diag_log(ad):
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002454 """Pulls the cnss_diag logs in the wlan_logs dir
2455 Args:
2456 ad: android device object.
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002457 """
2458 logs = ad.get_file_names("/data/vendor/wifi/cnss_diag/wlan_logs/")
2459 if logs:
2460 ad.log.info("Pulling cnss_diag logs %s", logs)
Xianyuan Jia0e39e552019-01-24 17:17:47 -08002461 log_path = os.path.join(ad.device_log_path, "CNSS_DIAG_%s" % ad.serial)
Mark De Ruyter72f8df92020-02-12 13:44:49 -08002462 os.makedirs(log_path, exist_ok=True)
Hsiu-Chang Chenf8578472018-09-18 12:23:42 +08002463 ad.pull_files(logs, log_path)
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002464
Bindu Mahadevff295782019-02-08 16:17:48 -08002465
David Sue4cd9c22019-03-26 18:07:26 -07002466LinkProbeResult = namedtuple('LinkProbeResult', (
2467 'is_success', 'stdout', 'elapsed_time', 'failure_reason'))
2468
2469
2470def send_link_probe(ad):
2471 """Sends a link probe to the currently connected AP, and returns whether the
2472 probe succeeded or not.
2473
2474 Args:
2475 ad: android device object
2476 Returns:
2477 LinkProbeResult namedtuple
2478 """
2479 stdout = ad.adb.shell('cmd wifi send-link-probe')
2480 asserts.assert_false('Error' in stdout or 'Exception' in stdout,
2481 'Exception while sending link probe: ' + stdout)
2482
2483 is_success = False
2484 elapsed_time = None
2485 failure_reason = None
2486 if 'succeeded' in stdout:
2487 is_success = True
2488 elapsed_time = next(
2489 (int(token) for token in stdout.split() if token.isdigit()), None)
2490 elif 'failed with reason' in stdout:
2491 failure_reason = next(
2492 (int(token) for token in stdout.split() if token.isdigit()), None)
2493 else:
2494 asserts.fail('Unexpected link probe result: ' + stdout)
2495
2496 return LinkProbeResult(
2497 is_success=is_success, stdout=stdout,
2498 elapsed_time=elapsed_time, failure_reason=failure_reason)
2499
2500
2501def send_link_probes(ad, num_probes, delay_sec):
2502 """Sends a sequence of link probes to the currently connected AP, and
2503 returns whether the probes succeeded or not.
2504
2505 Args:
2506 ad: android device object
2507 num_probes: number of probes to perform
2508 delay_sec: delay time between probes, in seconds
2509 Returns:
2510 List[LinkProbeResult] one LinkProbeResults for each probe
2511 """
2512 logging.info('Sending link probes')
2513 results = []
2514 for _ in range(num_probes):
2515 # send_link_probe() will also fail the test if it sees an exception
2516 # in the stdout of the adb shell command
2517 result = send_link_probe(ad)
2518 logging.info('link probe results: ' + str(result))
2519 results.append(result)
2520 time.sleep(delay_sec)
2521
2522 return results
2523
2524
Bindu Mahadev7e5dc682019-02-01 16:53:34 -08002525def ap_setup(test, index, ap, network, bandwidth=80, channel=6):
2526 """Set up the AP with provided network info.
2527
2528 Args:
2529 test: the calling test class object.
2530 index: int, index of the AP.
2531 ap: access_point object of the AP.
2532 network: dict with information of the network, including ssid,
2533 password and bssid.
2534 bandwidth: the operation bandwidth for the AP, default 80MHz.
2535 channel: the channel number for the AP.
2536 Returns:
2537 brconfigs: the bridge interface configs
2538 """
2539 bss_settings = []
2540 ssid = network[WifiEnums.SSID_KEY]
2541 test.access_points[index].close()
2542 time.sleep(5)
2543
2544 # Configure AP as required.
2545 if "password" in network.keys():
2546 password = network["password"]
2547 security = hostapd_security.Security(
2548 security_mode="wpa", password=password)
2549 else:
2550 security = hostapd_security.Security(security_mode=None, password=None)
2551 config = hostapd_ap_preset.create_ap_preset(
2552 channel=channel,
2553 ssid=ssid,
2554 security=security,
2555 bss_settings=bss_settings,
2556 vht_bandwidth=bandwidth,
2557 profile_name='whirlwind',
2558 iface_wlan_2g=ap.wlan_2g,
2559 iface_wlan_5g=ap.wlan_5g)
2560 ap.start_ap(config)
2561 logging.info("AP started on channel {} with SSID {}".format(channel, ssid))
Bindu Mahadevff295782019-02-08 16:17:48 -08002562
2563
2564def turn_ap_off(test, AP):
2565 """Bring down hostapd on the Access Point.
2566 Args:
2567 test: The test class object.
2568 AP: int, indicating which AP to turn OFF.
2569 """
2570 hostapd_2g = test.access_points[AP-1]._aps['wlan0'].hostapd
2571 if hostapd_2g.is_alive():
2572 hostapd_2g.stop()
2573 logging.debug('Turned WLAN0 AP%d off' % AP)
2574 hostapd_5g = test.access_points[AP-1]._aps['wlan1'].hostapd
2575 if hostapd_5g.is_alive():
2576 hostapd_5g.stop()
2577 logging.debug('Turned WLAN1 AP%d off' % AP)
2578
2579
2580def turn_ap_on(test, AP):
2581 """Bring up hostapd on the Access Point.
2582 Args:
2583 test: The test class object.
2584 AP: int, indicating which AP to turn ON.
2585 """
2586 hostapd_2g = test.access_points[AP-1]._aps['wlan0'].hostapd
2587 if not hostapd_2g.is_alive():
2588 hostapd_2g.start(hostapd_2g.config)
2589 logging.debug('Turned WLAN0 AP%d on' % AP)
2590 hostapd_5g = test.access_points[AP-1]._aps['wlan1'].hostapd
2591 if not hostapd_5g.is_alive():
2592 hostapd_5g.start(hostapd_5g.config)
2593 logging.debug('Turned WLAN1 AP%d on' % AP)
Joe Brennan48c3f692019-04-11 08:30:16 -07002594
2595
2596def turn_location_off_and_scan_toggle_off(ad):
2597 """Turns off wifi location scans."""
2598 utils.set_location_service(ad, False)
2599 ad.droid.wifiScannerToggleAlwaysAvailable(False)
2600 msg = "Failed to turn off location service's scan."
2601 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
Alfie Chen675be872020-06-04 10:48:14 +08002602
2603
2604def set_softap_channel(dut, ap_iface='wlan1', cs_count=10, channel=2462):
2605 """ Set SoftAP mode channel
2606
2607 Args:
2608 dut: android device object
2609 ap_iface: interface of SoftAP mode.
2610 cs_count: how many beacon frames before switch channel, default = 10
2611 channel: a wifi channel.
2612 """
2613 chan_switch_cmd = 'hostapd_cli -i {} chan_switch {} {}'
2614 chan_switch_cmd_show = chan_switch_cmd.format(ap_iface,cs_count,channel)
2615 dut.log.info('adb shell {}'.format(chan_switch_cmd_show))
2616 chan_switch_result = dut.adb.shell(chan_switch_cmd.format(ap_iface,
2617 cs_count,
2618 channel))
2619 if chan_switch_result == 'OK':
2620 dut.log.info('switch hotspot channel to {}'.format(channel))
2621 return chan_switch_result
2622
2623 asserts.fail("Failed to switch hotspot channel")
2624