blob: c1ae0081dc84c0272aa2ff34e84084b94b444ac4 [file] [log] [blame]
tturney1bdf77d2015-12-28 17:46:13 -08001#!/usr/bin/env python3.4
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
Ang Li73697b32015-12-03 00:41:53 +000018import time
19import pprint
20
21from enum import IntEnum
22from queue import Empty
23
Ang Li82522812016-06-02 13:57:21 -070024from acts import asserts
Ang Li374d7602016-02-08 17:27:27 -080025from acts import signals
Ang Lifee28402016-07-13 13:43:29 -070026from acts import utils
Ang Li2d3fe982016-06-08 10:00:43 -070027from acts.controllers import attenuator
Rebecca Silberstein32f0c612016-07-19 15:04:46 -070028from acts.test_utils.tel import tel_defines
Ang Li73697b32015-12-03 00:41:53 +000029
Ang Li5bd83f32016-05-23 14:39:38 -070030log = logging
Ang Li73697b32015-12-03 00:41:53 +000031
32# Number of seconds to wait for events that are supposed to happen quickly.
33# Like onSuccess for start background scan and confirmation on wifi state
34# change.
35SHORT_TIMEOUT = 30
36
37# The currently supported devices that existed before release
38#TODO: (navtejsingh) Need to clean up the below lists going forward
39K_DEVICES = ["hammerhead", "razor", "razorg"]
40L_DEVICES = ["shamu", "ryu"]
41L_TAP_DEVICES = ["volantis", "volantisg"]
42M_DEVICES = ["angler"]
43
44# Speed of light in m/s.
45SPEED_OF_LIGHT = 299792458
46
47DEFAULT_PING_ADDR = "http://www.google.com/robots.txt"
48
Ang Li82522812016-06-02 13:57:21 -070049
Ang Li73697b32015-12-03 00:41:53 +000050class WifiEnums():
51
52 SSID_KEY = "SSID"
53 BSSID_KEY = "BSSID"
54 PWD_KEY = "password"
55 frequency_key = "frequency"
56 APBAND_KEY = "apBand"
57
58 WIFI_CONFIG_APBAND_2G = 0
59 WIFI_CONFIG_APBAND_5G = 1
60
Ang Li82522812016-06-02 13:57:21 -070061 WIFI_WPS_INFO_PBC = 0
62 WIFI_WPS_INFO_DISPLAY = 1
63 WIFI_WPS_INFO_KEYPAD = 2
64 WIFI_WPS_INFO_LABEL = 3
65 WIFI_WPS_INFO_INVALID = 4
Ang Li73697b32015-12-03 00:41:53 +000066
67 class CountryCode():
68 CHINA = "CN"
69 JAPAN = "JP"
70 UK = "GB"
71 US = "US"
72 UNKNOWN = "UNKNOWN"
73
74 # Start of Macros for EAP
75 # EAP types
76 class Eap(IntEnum):
77 NONE = -1
78 PEAP = 0
Ang Li82522812016-06-02 13:57:21 -070079 TLS = 1
Ang Li73697b32015-12-03 00:41:53 +000080 TTLS = 2
Ang Li82522812016-06-02 13:57:21 -070081 PWD = 3
82 SIM = 4
83 AKA = 5
84 AKA_PRIME = 6
85 UNAUTH_TLS = 7
Ang Li73697b32015-12-03 00:41:53 +000086
87 # EAP Phase2 types
88 class EapPhase2(IntEnum):
Ang Li82522812016-06-02 13:57:21 -070089 NONE = 0
90 PAP = 1
91 MSCHAP = 2
92 MSCHAPV2 = 3
93 GTC = 4
Ang Li73697b32015-12-03 00:41:53 +000094
95 class Enterprise:
Ang Li82522812016-06-02 13:57:21 -070096 # Enterprise Config Macros
97 EMPTY_VALUE = "NULL"
98 EAP = "eap"
99 PHASE2 = "phase2"
100 IDENTITY = "identity"
101 ANON_IDENTITY = "anonymous_identity"
102 PASSWORD = "password"
103 SUBJECT_MATCH = "subject_match"
Ang Li73697b32015-12-03 00:41:53 +0000104 ALTSUBJECT_MATCH = "altsubject_match"
105 DOM_SUFFIX_MATCH = "domain_suffix_match"
Ang Li82522812016-06-02 13:57:21 -0700106 CLIENT_CERT = "client_cert"
107 CA_CERT = "ca_cert"
108 ENGINE = "engine"
109 ENGINE_ID = "engine_id"
110 PRIVATE_KEY_ID = "key_id"
111 REALM = "realm"
112 PLMN = "plmn"
113 FQDN = "FQDN"
114 FRIENDLY_NAME = "providerFriendlyName"
115 ROAMING_IDS = "roamingConsortiumIds"
Ang Li73697b32015-12-03 00:41:53 +0000116 # End of Macros for EAP
117
118 # Macros for wifi p2p.
119 WIFI_P2P_SERVICE_TYPE_ALL = 0
120 WIFI_P2P_SERVICE_TYPE_BONJOUR = 1
121 WIFI_P2P_SERVICE_TYPE_UPNP = 2
122 WIFI_P2P_SERVICE_TYPE_VENDOR_SPECIFIC = 255
123
124 class ScanResult:
125 CHANNEL_WIDTH_20MHZ = 0
126 CHANNEL_WIDTH_40MHZ = 1
127 CHANNEL_WIDTH_80MHZ = 2
128 CHANNEL_WIDTH_160MHZ = 3
129 CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4
130
131 # Macros for wifi rtt.
132 class RttType(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700133 TYPE_ONE_SIDED = 1
134 TYPE_TWO_SIDED = 2
Ang Li73697b32015-12-03 00:41:53 +0000135
136 class RttPeerType(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700137 PEER_TYPE_AP = 1
138 PEER_TYPE_STA = 2 # Requires NAN.
139 PEER_P2P_GO = 3
140 PEER_P2P_CLIENT = 4
141 PEER_NAN = 5
Ang Li73697b32015-12-03 00:41:53 +0000142
143 class RttPreamble(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700144 PREAMBLE_LEGACY = 0x01
145 PREAMBLE_HT = 0x02
146 PREAMBLE_VHT = 0x04
Ang Li73697b32015-12-03 00:41:53 +0000147
148 class RttBW(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700149 BW_5_SUPPORT = 0x01
150 BW_10_SUPPORT = 0x02
151 BW_20_SUPPORT = 0x04
152 BW_40_SUPPORT = 0x08
153 BW_80_SUPPORT = 0x10
Ang Li73697b32015-12-03 00:41:53 +0000154 BW_160_SUPPORT = 0x20
155
156 class Rtt(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700157 STATUS_SUCCESS = 0
158 STATUS_FAILURE = 1
159 STATUS_FAIL_NO_RSP = 2
160 STATUS_FAIL_REJECTED = 3
161 STATUS_FAIL_NOT_SCHEDULED_YET = 4
162 STATUS_FAIL_TM_TIMEOUT = 5
163 STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6
164 STATUS_FAIL_NO_CAPABILITY = 7
165 STATUS_ABORTED = 8
166 STATUS_FAIL_INVALID_TS = 9
167 STATUS_FAIL_PROTOCOL = 10
168 STATUS_FAIL_SCHEDULE = 11
169 STATUS_FAIL_BUSY_TRY_LATER = 12
170 STATUS_INVALID_REQ = 13
171 STATUS_NO_WIFI = 14
172 STATUS_FAIL_FTM_PARAM_OVERRIDE = 15
Ang Li73697b32015-12-03 00:41:53 +0000173
Ang Li82522812016-06-02 13:57:21 -0700174 REASON_UNSPECIFIED = -1
175 REASON_NOT_AVAILABLE = -2
176 REASON_INVALID_LISTENER = -3
177 REASON_INVALID_REQUEST = -4
Ang Li73697b32015-12-03 00:41:53 +0000178
179 class RttParam:
180 device_type = "deviceType"
181 request_type = "requestType"
182 BSSID = "bssid"
183 channel_width = "channelWidth"
184 frequency = "frequency"
185 center_freq0 = "centerFreq0"
186 center_freq1 = "centerFreq1"
187 number_burst = "numberBurst"
188 interval = "interval"
189 num_samples_per_burst = "numSamplesPerBurst"
190 num_retries_per_measurement_frame = "numRetriesPerMeasurementFrame"
191 num_retries_per_FTMR = "numRetriesPerFTMR"
192 lci_request = "LCIRequest"
193 lcr_request = "LCRRequest"
194 burst_timeout = "burstTimeout"
195 preamble = "preamble"
196 bandwidth = "bandwidth"
197 margin = "margin"
198
199 RTT_MARGIN_OF_ERROR = {
200 RttBW.BW_80_SUPPORT: 2,
201 RttBW.BW_40_SUPPORT: 5,
202 RttBW.BW_20_SUPPORT: 5
203 }
204
205 # Macros as specified in the WifiScanner code.
Ang Li82522812016-06-02 13:57:21 -0700206 WIFI_BAND_UNSPECIFIED = 0 # not specified
207 WIFI_BAND_24_GHZ = 1 # 2.4 GHz band
208 WIFI_BAND_5_GHZ = 2 # 5 GHz band without DFS channels
209 WIFI_BAND_5_GHZ_DFS_ONLY = 4 # 5 GHz band with DFS channels
210 WIFI_BAND_5_GHZ_WITH_DFS = 6 # 5 GHz band with DFS channels
211 WIFI_BAND_BOTH = 3 # both bands without DFS channels
212 WIFI_BAND_BOTH_WITH_DFS = 7 # both bands with DFS channels
Ang Li73697b32015-12-03 00:41:53 +0000213
214 REPORT_EVENT_AFTER_BUFFER_FULL = 0
215 REPORT_EVENT_AFTER_EACH_SCAN = 1
216 REPORT_EVENT_FULL_SCAN_RESULT = 2
217
218 # US Wifi frequencies
219 ALL_2G_FREQUENCIES = [2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452,
220 2457, 2462]
221 DFS_5G_FREQUENCIES = [5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580,
222 5600, 5620, 5640, 5660, 5680, 5700, 5720]
223 NONE_DFS_5G_FREQUENCIES = [5180, 5200, 5220, 5240, 5745, 5765, 5785, 5805,
224 5825]
225 ALL_5G_FREQUENCIES = DFS_5G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES
226
227 band_to_frequencies = {
Ang Li82522812016-06-02 13:57:21 -0700228 WIFI_BAND_24_GHZ: ALL_2G_FREQUENCIES,
229 WIFI_BAND_5_GHZ: NONE_DFS_5G_FREQUENCIES,
230 WIFI_BAND_5_GHZ_DFS_ONLY: DFS_5G_FREQUENCIES,
231 WIFI_BAND_5_GHZ_WITH_DFS: ALL_5G_FREQUENCIES,
232 WIFI_BAND_BOTH: ALL_2G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES,
233 WIFI_BAND_BOTH_WITH_DFS: ALL_5G_FREQUENCIES + ALL_2G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000234 }
235
236 # All Wifi frequencies to channels lookup.
237 freq_to_channel = {
238 2412: 1,
239 2417: 2,
240 2422: 3,
241 2427: 4,
242 2432: 5,
243 2437: 6,
244 2442: 7,
245 2447: 8,
246 2452: 9,
247 2457: 10,
248 2462: 11,
249 2467: 12,
250 2472: 13,
251 2484: 14,
252 4915: 183,
253 4920: 184,
254 4925: 185,
255 4935: 187,
256 4940: 188,
257 4945: 189,
258 4960: 192,
259 4980: 196,
260 5035: 7,
261 5040: 8,
262 5045: 9,
263 5055: 11,
264 5060: 12,
265 5080: 16,
266 5170: 34,
267 5180: 36,
268 5190: 38,
269 5200: 40,
270 5210: 42,
271 5220: 44,
272 5230: 46,
273 5240: 48,
274 5260: 52,
275 5280: 56,
276 5300: 60,
277 5320: 64,
278 5500: 100,
279 5520: 104,
280 5540: 108,
281 5560: 112,
282 5580: 116,
283 5600: 120,
284 5620: 124,
285 5640: 128,
286 5660: 132,
287 5680: 136,
288 5700: 140,
289 5745: 149,
290 5765: 153,
291 5785: 157,
292 5805: 161,
293 5825: 165,
294 }
295
296 # All Wifi channels to frequencies lookup.
297 channel_2G_to_freq = {
298 1: 2412,
299 2: 2417,
300 3: 2422,
301 4: 2427,
302 5: 2432,
303 6: 2437,
304 7: 2442,
305 8: 2447,
306 9: 2452,
307 10: 2457,
308 11: 2462,
309 12: 2467,
310 13: 2472,
311 14: 2484
312 }
313
314 channel_5G_to_freq = {
315 183: 4915,
316 184: 4920,
317 185: 4925,
318 187: 4935,
319 188: 4940,
320 189: 4945,
321 192: 4960,
322 196: 4980,
323 7: 5035,
324 8: 5040,
325 9: 5045,
326 11: 5055,
327 12: 5060,
328 16: 5080,
329 34: 5170,
330 36: 5180,
331 38: 5190,
332 40: 5200,
333 42: 5210,
334 44: 5220,
335 46: 5230,
336 48: 5240,
337 52: 5260,
338 56: 5280,
339 60: 5300,
340 64: 5320,
341 100: 5500,
342 104: 5520,
343 108: 5540,
344 112: 5560,
345 116: 5580,
346 120: 5600,
347 124: 5620,
348 128: 5640,
349 132: 5660,
350 136: 5680,
351 140: 5700,
352 149: 5745,
353 153: 5765,
354 157: 5785,
355 161: 5805,
356 165: 5825
357 }
358
Ang Li82522812016-06-02 13:57:21 -0700359
Ang Li73697b32015-12-03 00:41:53 +0000360class WifiEventNames:
361 WIFI_CONNECTED = "WifiNetworkConnected"
362 SUPPLICANT_CON_CHANGED = "SupplicantConnectionChanged"
363 WIFI_FORGET_NW_SUCCESS = "WifiManagerForgetNetworkOnSuccess"
364
Ang Li82522812016-06-02 13:57:21 -0700365
Ang Li73697b32015-12-03 00:41:53 +0000366class WifiTestUtilsError(Exception):
367 pass
368
Ang Li82522812016-06-02 13:57:21 -0700369
Ang Li73697b32015-12-03 00:41:53 +0000370class WifiChannelBase:
371 ALL_2G_FREQUENCIES = []
372 DFS_5G_FREQUENCIES = []
373 NONE_DFS_5G_FREQUENCIES = []
374 ALL_5G_FREQUENCIES = DFS_5G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES
375 MIX_CHANNEL_SCAN = []
376
377 def band_to_freq(self, band):
378 _band_to_frequencies = {
379 WifiEnums.WIFI_BAND_24_GHZ: self.ALL_2G_FREQUENCIES,
380 WifiEnums.WIFI_BAND_5_GHZ: self.NONE_DFS_5G_FREQUENCIES,
381 WifiEnums.WIFI_BAND_5_GHZ_DFS_ONLY: self.DFS_5G_FREQUENCIES,
382 WifiEnums.WIFI_BAND_5_GHZ_WITH_DFS: self.ALL_5G_FREQUENCIES,
Ang Li82522812016-06-02 13:57:21 -0700383 WifiEnums.WIFI_BAND_BOTH:
384 self.ALL_2G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES,
385 WifiEnums.WIFI_BAND_BOTH_WITH_DFS:
386 self.ALL_5G_FREQUENCIES + self.ALL_2G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000387 }
388 return _band_to_frequencies[band]
389
Ang Li82522812016-06-02 13:57:21 -0700390
Ang Li73697b32015-12-03 00:41:53 +0000391class WifiChannelUS(WifiChannelBase):
392 # US Wifi frequencies
393 ALL_2G_FREQUENCIES = [2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452,
394 2457, 2462]
395 NONE_DFS_5G_FREQUENCIES = [5180, 5200, 5220, 5240, 5745, 5765, 5785, 5805,
396 5825]
Ang Li82522812016-06-02 13:57:21 -0700397 MIX_CHANNEL_SCAN = [2412, 2437, 2462, 5180, 5200, 5280, 5260, 5300, 5500,
398 5320, 5520, 5560, 5700, 5745, 5805]
Ang Li73697b32015-12-03 00:41:53 +0000399
400 def __init__(self, model=None):
Ang Lifee28402016-07-13 13:43:29 -0700401 if model and utils.trim_model_name(model) in K_DEVICES:
Ang Li73697b32015-12-03 00:41:53 +0000402 self.DFS_5G_FREQUENCIES = []
403 self.ALL_5G_FREQUENCIES = self.NONE_DFS_5G_FREQUENCIES
Ang Li82522812016-06-02 13:57:21 -0700404 self.MIX_CHANNEL_SCAN = [2412, 2437, 2462, 5180, 5200, 5240, 5745,
405 5765]
Ang Lifee28402016-07-13 13:43:29 -0700406 elif model and utils.trim_model_name(model) in L_DEVICES:
Ang Li73697b32015-12-03 00:41:53 +0000407 self.DFS_5G_FREQUENCIES = [5260, 5280, 5300, 5320, 5500, 5520,
408 5540, 5560, 5580, 5660, 5680, 5700]
409 self.ALL_5G_FREQUENCIES = self.DFS_5G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES
Ang Lifee28402016-07-13 13:43:29 -0700410 elif model and utils.trim_model_name(model) in L_TAP_DEVICES:
Ang Li73697b32015-12-03 00:41:53 +0000411 self.DFS_5G_FREQUENCIES = [5260, 5280, 5300, 5320, 5500, 5520,
Ang Li82522812016-06-02 13:57:21 -0700412 5540, 5560, 5580, 5660, 5680, 5700,
413 5720]
Ang Li73697b32015-12-03 00:41:53 +0000414 self.ALL_5G_FREQUENCIES = self.DFS_5G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES
Ang Lifee28402016-07-13 13:43:29 -0700415 elif model and utils.trim_model_name(model) in M_DEVICES:
Ang Li82522812016-06-02 13:57:21 -0700416 self.DFS_5G_FREQUENCIES = [5260, 5280, 5300, 5320, 5500, 5520,
417 5540, 5560, 5580, 5600, 5620, 5640,
418 5660, 5680, 5700]
Ang Li73697b32015-12-03 00:41:53 +0000419 self.ALL_5G_FREQUENCIES = self.DFS_5G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES
420 else:
Ang Li82522812016-06-02 13:57:21 -0700421 self.DFS_5G_FREQUENCIES = [5260, 5280, 5300, 5320, 5500, 5520,
422 5540, 5560, 5580, 5600, 5620, 5640,
423 5660, 5680, 5700, 5720]
Ang Li73697b32015-12-03 00:41:53 +0000424 self.ALL_5G_FREQUENCIES = self.DFS_5G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES
425
Ang Li82522812016-06-02 13:57:21 -0700426
427def _assert_on_fail_handler(func, assert_on_fail, *args, **kwargs):
428 """Wrapper function that handles the bahevior of assert_on_fail.
429
430 When assert_on_fail is True, let all test signals through, which can
431 terminate test cases directly. When assert_on_fail is False, the wrapper
432 raises no test signals and reports operation status by returning True or
433 False.
434
435 Args:
436 func: The function to wrap. This function reports operation status by
437 raising test signals.
438 assert_on_fail: A boolean that specifies if the output of the wrapper
439 is test signal based or return value based.
440 args: Positional args for func.
441 kwargs: Name args for func.
442
443 Returns:
444 If assert_on_fail is True, returns True/False to signal operation
445 status, otherwise return nothing.
446 """
447 try:
448 func(*args, **kwargs)
449 if not assert_on_fail:
450 return True
451 except signals.TestSignal:
452 if assert_on_fail:
453 raise
454 return False
455
456
457def assert_network_in_list(target, network_list):
458 """Makes sure a specified target Wi-Fi network exists in a list of Wi-Fi
459 networks.
460
461 Args:
462 target: A dict representing a Wi-Fi network.
463 E.g. {WifiEnums.SSID_KEY: "SomeNetwork"}
464 network_list: A list of dicts, each representing a Wi-Fi network.
465 """
466 match_results = match_networks(target, network_list)
467 asserts.assert_true(
468 match_results, "Target network %s, does not exist in network list %s" %
469 (target, network_list))
470
471
Ang Li73697b32015-12-03 00:41:53 +0000472def match_networks(target_params, networks):
473 """Finds the WiFi networks that match a given set of parameters in a list
474 of WiFi networks.
475
476 To be considered a match, a network needs to have all the target parameters
477 and the values of those parameters need to equal to those of the target
478 parameters.
479
480 Args:
481 target_params: The target parameters to match networks against.
482 networks: A list of dict objects representing WiFi networks.
483
484 Returns:
485 The networks that match the target parameters.
486 """
487 results = []
488 for n in networks:
Ang Li9a66de72016-02-08 15:26:38 -0800489 for k, v in target_params.items():
490 if k not in n:
491 continue
492 if n[k] != v:
493 continue
Ang Li73697b32015-12-03 00:41:53 +0000494 results.append(n)
495 return results
496
Ang Li82522812016-06-02 13:57:21 -0700497
498def wifi_toggle_state(ad, new_state=None, assert_on_fail=True):
Ang Li6b557182015-11-11 17:19:17 -0800499 """Toggles the state of wifi.
Ang Li73697b32015-12-03 00:41:53 +0000500
Ang Li6b557182015-11-11 17:19:17 -0800501 Args:
502 ad: An AndroidDevice object.
503 new_state: Wifi state to set to. If None, opposite of the current state.
Ang Li82522812016-06-02 13:57:21 -0700504 assert_on_fail: If True, error checks in this function will raise test
505 failure signals.
Ang Li73697b32015-12-03 00:41:53 +0000506
Ang Li6b557182015-11-11 17:19:17 -0800507 Returns:
Ang Li82522812016-06-02 13:57:21 -0700508 If assert_on_fail is False, function returns True if the toggle was
509 successful, False otherwise. If assert_on_fail is True, no return value.
510 """
511 _assert_on_fail_handler(_wifi_toggle_state, assert_on_fail, ad, new_state)
512
513
514def _wifi_toggle_state(ad, new_state=None):
515 """Toggles the state of wifi.
516
517 TestFailure signals are raised when something goes wrong.
518
519 Args:
520 ad: An AndroidDevice object.
521 new_state: The state to set Wi-Fi to. If None, opposite of the current
522 state will be set.
Ang Li6b557182015-11-11 17:19:17 -0800523 """
Ang Li31b00782016-06-21 13:04:23 -0700524 if new_state is None:
525 new_state = not ad.droid.wifiCheckState()
Ang Lie5c85c92016-07-27 15:38:09 -0700526 elif new_state == ad.droid.wifiCheckState():
527 # Check if the new_state is already achieved, so we don't wait for the
528 # state change event by mistake.
529 return
530 ad.droid.wifiStartTrackingStateChange()
Ang Li31b00782016-06-21 13:04:23 -0700531 ad.log.info("Setting Wi-Fi state to %s.", new_state)
532 # Setting wifi state.
Ang Li6b557182015-11-11 17:19:17 -0800533 ad.droid.wifiToggleState(new_state)
Ang Lie2e93a22016-06-22 16:43:28 -0700534 fail_msg = "Failed to set Wi-Fi state to %s on %s." % (new_state,
535 ad.serial)
Ang Li73697b32015-12-03 00:41:53 +0000536 try:
Ang Li82522812016-06-02 13:57:21 -0700537 event = ad.ed.pop_event(WifiEventNames.SUPPLICANT_CON_CHANGED,
538 SHORT_TIMEOUT)
539 asserts.assert_equal(event['data']['Connected'], new_state, fail_msg)
Ang Li73697b32015-12-03 00:41:53 +0000540 except Empty:
Ang Li82522812016-06-02 13:57:21 -0700541 # Supplicant connection event is not always reliable. We double check
542 # here and call it a success as long as the new state equals the
543 # expected state.
Prashant Agrawale19e7ec2016-07-21 11:14:22 +0530544 time.sleep(5)
Ang Li82522812016-06-02 13:57:21 -0700545 asserts.assert_equal(new_state, ad.droid.wifiCheckState(), fail_msg)
Ang Li6b557182015-11-11 17:19:17 -0800546 finally:
547 ad.droid.wifiStopTrackingStateChange()
548
Ang Li82522812016-06-02 13:57:21 -0700549
Ang Li6b557182015-11-11 17:19:17 -0800550def reset_wifi(ad):
Ang Li1179fa72016-06-16 09:44:06 -0700551 """Clears all saved Wi-Fi networks on a device.
552
553 This will turn Wi-Fi on.
Ang Li6b557182015-11-11 17:19:17 -0800554
555 Args:
556 ad: An AndroidDevice object.
557
558 Raises:
Ang Li1179fa72016-06-16 09:44:06 -0700559 WifiTestUtilsError is raised if not all networks were removed.
Ang Li6b557182015-11-11 17:19:17 -0800560 """
Ang Li1179fa72016-06-16 09:44:06 -0700561 wifi_toggle_state(ad, True)
Ang Li6b557182015-11-11 17:19:17 -0800562 networks = ad.droid.wifiGetConfiguredNetworks()
563 if not networks:
564 return
565 for n in networks:
566 ad.droid.wifiForgetNetwork(n['networkId'])
567 try:
568 event = ad.ed.pop_event(WifiEventNames.WIFI_FORGET_NW_SUCCESS,
Ang Li82522812016-06-02 13:57:21 -0700569 SHORT_TIMEOUT)
Ang Li6b557182015-11-11 17:19:17 -0800570 except Empty:
Ang Li1179fa72016-06-16 09:44:06 -0700571 logging.warning("Could not confirm the removal of network %s.", n)
572 # Check again to see if there's any network left.
573 networks = ad.droid.wifiGetConfiguredNetworks()
574 if networks:
575 raise WifiTestUtilsError(
576 "Failed to remove these configured Wi-Fi networks: %s" % networks)
Ang Li82522812016-06-02 13:57:21 -0700577
Ang Li73697b32015-12-03 00:41:53 +0000578
579def wifi_forget_network(ad, net_ssid):
Ang Li8e767182015-12-09 17:29:24 -0800580 """Remove configured Wifi network on an android device.
Ang Li73697b32015-12-03 00:41:53 +0000581
Ang Li8e767182015-12-09 17:29:24 -0800582 Args:
583 ad: android_device object for forget network.
584 net_ssid: ssid of network to be forget
Ang Li73697b32015-12-03 00:41:53 +0000585
Ang Li8e767182015-12-09 17:29:24 -0800586 Raises:
587 WifiTestUtilsError is raised if forget network operation failed.
588 """
589 droid, ed = ad.droid, ad.ed
590 droid.wifiToggleState(True)
591 networks = droid.wifiGetConfiguredNetworks()
592 if not networks:
593 return
594 for n in networks:
595 if net_ssid in n[WifiEnums.SSID_KEY]:
596 droid.wifiForgetNetwork(n['networkId'])
597 try:
598 event = ed.pop_event(WifiEventNames.WIFI_FORGET_NW_SUCCESS,
Ang Li82522812016-06-02 13:57:21 -0700599 SHORT_TIMEOUT)
Ang Li8e767182015-12-09 17:29:24 -0800600 except Empty:
601 raise WifiTestUtilsError("Failed to remove network %s." % n)
Ang Li73697b32015-12-03 00:41:53 +0000602
Ang Li82522812016-06-02 13:57:21 -0700603
Ang Li73697b32015-12-03 00:41:53 +0000604def wifi_test_device_init(ad):
605 """Initializes an android device for wifi testing.
606
607 0. Make sure SL4A connection is established on the android device.
608 1. Disable location service's WiFi scan.
609 2. Turn WiFi on.
610 3. Clear all saved networks.
611 4. Set country code to US.
612 5. Enable WiFi verbose logging.
613 6. Sync device time with computer time.
614 7. Turn off cellular data.
Ang Lifee28402016-07-13 13:43:29 -0700615 8. Turn off ambient display.
Ang Li73697b32015-12-03 00:41:53 +0000616 """
Ang Lifee28402016-07-13 13:43:29 -0700617 utils.require_sl4a((ad, ))
Ang Li73697b32015-12-03 00:41:53 +0000618 ad.droid.wifiScannerToggleAlwaysAvailable(False)
619 msg = "Failed to turn off location service's scan."
Ang Li82522812016-06-02 13:57:21 -0700620 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
621 wifi_toggle_state(ad, True)
Ang Li6b557182015-11-11 17:19:17 -0800622 reset_wifi(ad)
Ang Li73697b32015-12-03 00:41:53 +0000623 msg = "Failed to clear configured networks."
Ang Li82522812016-06-02 13:57:21 -0700624 asserts.assert_true(not ad.droid.wifiGetConfiguredNetworks(), msg)
Ang Li73697b32015-12-03 00:41:53 +0000625 ad.droid.wifiEnableVerboseLogging(1)
Ang Li8e767182015-12-09 17:29:24 -0800626 msg = "Failed to enable WiFi verbose logging."
Ang Li82522812016-06-02 13:57:21 -0700627 asserts.assert_equal(ad.droid.wifiGetVerboseLoggingLevel(), 1, msg)
Ang Li73697b32015-12-03 00:41:53 +0000628 ad.droid.wifiScannerToggleAlwaysAvailable(False)
629 # We don't verify the following settings since they are not critical.
Ang Lie2e93a22016-06-22 16:43:28 -0700630 # Set wpa_supplicant log level to EXCESSIVE.
631 output = ad.adb.shell("wpa_cli -i wlan0 -p -g@android:wpa_wlan0 IFNAME="
632 "wlan0 log_level EXCESSIVE")
633 ad.log.info("wpa_supplicant log change status: %s", output)
Ang Lifee28402016-07-13 13:43:29 -0700634 utils.sync_device_time(ad)
Ang Li0bf8e022016-01-04 17:34:48 -0800635 ad.droid.telephonyToggleDataConnection(False)
Ang Li73697b32015-12-03 00:41:53 +0000636 # TODO(angli): need to verify the country code was actually set. No generic
637 # way to check right now.
638 ad.adb.shell("halutil -country %s" % WifiEnums.CountryCode.US)
Ang Lifee28402016-07-13 13:43:29 -0700639 utils.set_ambient_display(ad, False)
Ang Li73697b32015-12-03 00:41:53 +0000640
Ang Li82522812016-06-02 13:57:21 -0700641
Ang Li73697b32015-12-03 00:41:53 +0000642def sort_wifi_scan_results(results, key="level"):
Ang Li8e767182015-12-09 17:29:24 -0800643 """Sort wifi scan results by key.
Ang Li73697b32015-12-03 00:41:53 +0000644
Ang Li8e767182015-12-09 17:29:24 -0800645 Args:
646 results: A list of results to sort.
647 key: Name of the field to sort the results by.
Ang Li73697b32015-12-03 00:41:53 +0000648
Ang Li8e767182015-12-09 17:29:24 -0800649 Returns:
650 A list of results in sorted order.
651 """
652 return sorted(results, lambda d: (key not in d, d[key]))
Ang Li73697b32015-12-03 00:41:53 +0000653
Ang Li82522812016-06-02 13:57:21 -0700654
Ang Li6b557182015-11-11 17:19:17 -0800655def start_wifi_connection_scan(ad):
Ang Li73697b32015-12-03 00:41:53 +0000656 """Starts a wifi connection scan and wait for results to become available.
657
658 Args:
Ang Li6b557182015-11-11 17:19:17 -0800659 ad: An AndroidDevice object.
Ang Li73697b32015-12-03 00:41:53 +0000660 """
Ang Li6b557182015-11-11 17:19:17 -0800661 ad.droid.wifiStartScan()
Ang Li82522812016-06-02 13:57:21 -0700662 try:
663 ad.ed.pop_event("WifiManagerScanResultsAvailable", 60)
664 except Empty:
665 asserts.fail("Wi-Fi results did not become available within 60s.")
666
Ang Li73697b32015-12-03 00:41:53 +0000667
668def start_wifi_background_scan(ad, scan_setting):
669 """Starts wifi background scan.
670
671 Args:
672 ad: android_device object to initiate connection on.
673 scan_setting: A dict representing the settings of the scan.
674
675 Returns:
676 If scan was started successfully, event data of success event is returned.
677 """
678 droid, ed = ad.droids[0], ad.eds[0]
679 idx = droid.wifiScannerStartBackgroundScan(scan_setting)
680 event = ed.pop_event("WifiScannerScan{}onSuccess".format(idx),
681 SHORT_TIMEOUT)
682 return event['data']
683
Ang Li82522812016-06-02 13:57:21 -0700684
Ang Li73697b32015-12-03 00:41:53 +0000685def start_wifi_tethering(ad, ssid, password, band=None):
686 """Starts wifi tethering on an android_device.
687
688 Args:
689 ad: android_device to start wifi tethering on.
690 ssid: The SSID the soft AP should broadcast.
691 password: The password the soft AP should use.
692 band: The band the soft AP should be set on. It should be either
693 WifiEnums.WIFI_CONFIG_APBAND_2G or WifiEnums.WIFI_CONFIG_APBAND_5G.
694
695 Returns:
696 True if soft AP was started successfully, False otherwise.
697 """
698 droid, ed = ad.droid, ad.ed
Ang Li82522812016-06-02 13:57:21 -0700699 config = {WifiEnums.SSID_KEY: ssid}
Ang Li73697b32015-12-03 00:41:53 +0000700 if password:
701 config[WifiEnums.PWD_KEY] = password
702 if band:
703 config[WifiEnums.APBAND_KEY] = band
Ang Li76216d12016-09-20 14:51:57 -0700704 asserts.assert_true(droid.wifiSetWifiApConfiguration(config),
705 "Failed to update WifiAp Configuration")
Rebecca Silbersteina2889852016-08-11 00:48:53 -0700706 droid.wifiStartTrackingTetherStateChange()
707 droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
708 try:
709 ed.pop_event("ConnectivityManagerOnTetheringStarted")
710 ed.wait_for_event("TetherStateChanged",
711 lambda x : x["data"]["ACTIVE_TETHER"], 30)
Ang Li76216d12016-09-20 14:51:57 -0700712 ad.log.debug("Tethering started successfully.")
Rebecca Silbersteina2889852016-08-11 00:48:53 -0700713 except Empty:
714 msg = "Failed to receive confirmation of wifi tethering starting"
715 asserts.fail(msg)
716 finally:
717 droid.wifiStopTrackingTetherStateChange()
Ang Li73697b32015-12-03 00:41:53 +0000718
Ang Li82522812016-06-02 13:57:21 -0700719
Ang Li73697b32015-12-03 00:41:53 +0000720def stop_wifi_tethering(ad):
721 """Stops wifi tethering on an android_device.
722
723 Args:
724 ad: android_device to stop wifi tethering on.
725 """
726 droid, ed = ad.droid, ad.ed
Ang Li76216d12016-09-20 14:51:57 -0700727 droid.wifiStartTrackingTetherStateChange()
Rebecca Silbersteina2889852016-08-11 00:48:53 -0700728 droid.connectivityStopTethering(tel_defines.TETHERING_WIFI)
Ang Li73697b32015-12-03 00:41:53 +0000729 droid.wifiSetApEnabled(False, None)
Rebecca Silbersteina2889852016-08-11 00:48:53 -0700730 try:
731 ed.pop_event("WifiManagerApDisabled", 30)
732 ed.wait_for_event("TetherStateChanged",
733 lambda x : not x["data"]["ACTIVE_TETHER"], 30)
734 except Empty:
735 msg = "Failed to receive confirmation of wifi tethering stopping"
736 asserts.fail(msg)
737 finally:
738 droid.wifiStopTrackingTetherStateChange()
Ang Li82522812016-06-02 13:57:21 -0700739
Ang Li76216d12016-09-20 14:51:57 -0700740
Roshan Pius58916a32016-06-16 16:26:44 -0700741def toggle_wifi_and_wait_for_reconnection(ad,
742 network,
743 num_of_tries=1,
744 assert_on_fail=True):
745 """Toggle wifi state and then wait for Android device to reconnect to
746 the provided wifi network.
747
748 This expects the device to be already connected to the provided network.
749
750 Logic steps are
751 1. Ensure that we're connected to the network.
752 2. Turn wifi off.
753 3. Wait for 10 seconds.
754 4. Turn wifi on.
755 5. Wait for the "connected" event, then confirm the connected ssid is the
756 one requested.
757
758 Args:
759 ad: android_device object to initiate connection on.
760 network: A dictionary representing the network to await connection. The
761 dictionary must have the key "SSID".
762 num_of_tries: An integer that is the number of times to try before
763 delaring failure. Default is 1.
764 assert_on_fail: If True, error checks in this function will raise test
765 failure signals.
766
767 Returns:
768 If assert_on_fail is False, function returns True if the toggle was
769 successful, False otherwise. If assert_on_fail is True, no return value.
770 """
771 _assert_on_fail_handler(_toggle_wifi_and_wait_for_reconnection,
772 assert_on_fail, ad, network, num_of_tries)
773
774
775def _toggle_wifi_and_wait_for_reconnection(ad, network, num_of_tries=1):
776 """Toggle wifi state and then wait for Android device to reconnect to
777 the provided wifi network.
778
779 This expects the device to be already connected to the provided network.
780
781 Logic steps are
782 1. Ensure that we're connected to the network.
783 2. Turn wifi off.
784 3. Wait for 10 seconds.
785 4. Turn wifi on.
786 5. Wait for the "connected" event, then confirm the connected ssid is the
787 one requested.
788
789 This will directly fail a test if anything goes wrong.
790
791 Args:
792 ad: android_device object to initiate connection on.
793 network: A dictionary representing the network to await connection. The
794 dictionary must have the key "SSID".
795 num_of_tries: An integer that is the number of times to try before
796 delaring failure. Default is 1.
797 """
798 serial = ad.serial
799 expected_ssid = network[WifiEnums.SSID_KEY]
800 # First ensure that we're already connected to the provided network.
801 verify_con = {WifiEnums.SSID_KEY: expected_ssid}
802 verify_wifi_connection_info(ad, verify_con)
803 # Now toggle wifi state and wait for the connection event.
804 wifi_toggle_state(ad, False)
805 time.sleep(10)
806 wifi_toggle_state(ad, True)
807 ad.droid.wifiStartTrackingStateChange()
808 try:
809 connect_result = None
810 for i in range(num_of_tries):
811 try:
812 connect_result = ad.ed.pop_event(WifiEventNames.WIFI_CONNECTED,
813 30)
814 break
815 except Empty:
816 pass
817 asserts.assert_true(connect_result,
818 "Failed to connect to Wi-Fi network %s on %s" %
819 (network, serial))
820 log.debug("Connection result on %s: %s.", serial, connect_result)
821 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
822 asserts.assert_equal(actual_ssid, expected_ssid,
823 "Connected to the wrong network on %s."
824 "Expected %s, but got %s." %
825 (serial, expected_ssid, actual_ssid))
826 log.info("Connected to Wi-Fi network %s on %s", actual_ssid, serial)
827 finally:
828 ad.droid.wifiStopTrackingStateChange()
829
830
Ang Li82522812016-06-02 13:57:21 -0700831def wifi_connect(ad, network, num_of_tries=1, assert_on_fail=True):
Ang Li99d8c6d2015-12-09 15:56:13 -0800832 """Connect an Android device to a wifi network.
Ang Li73697b32015-12-03 00:41:53 +0000833
834 Initiate connection to a wifi network, wait for the "connected" event, then
Ang Li99d8c6d2015-12-09 15:56:13 -0800835 confirm the connected ssid is the one requested.
Ang Li73697b32015-12-03 00:41:53 +0000836
Ang Li82522812016-06-02 13:57:21 -0700837 This will directly fail a test if anything goes wrong.
838
Ang Li73697b32015-12-03 00:41:53 +0000839 Args:
840 ad: android_device object to initiate connection on.
Ang Li99d8c6d2015-12-09 15:56:13 -0800841 network: A dictionary representing the network to connect to. The
Ang Li82522812016-06-02 13:57:21 -0700842 dictionary must have the key "SSID".
843 num_of_tries: An integer that is the number of times to try before
844 delaring failure. Default is 1.
845 assert_on_fail: If True, error checks in this function will raise test
846 failure signals.
847
848 Returns:
849 If assert_on_fail is False, function returns True if the toggle was
850 successful, False otherwise. If assert_on_fail is True, no return value.
Ang Li73697b32015-12-03 00:41:53 +0000851 """
Ang Li82522812016-06-02 13:57:21 -0700852 _assert_on_fail_handler(_wifi_connect, assert_on_fail, ad, network,
853 num_of_tries)
854
855
856def _wifi_connect(ad, network, num_of_tries=1):
857 """Connect an Android device to a wifi network.
858
859 Initiate connection to a wifi network, wait for the "connected" event, then
860 confirm the connected ssid is the one requested.
861
862 This will directly fail a test if anything goes wrong.
863
864 Args:
865 ad: android_device object to initiate connection on.
866 network: A dictionary representing the network to connect to. The
867 dictionary must have the key "SSID".
868 num_of_tries: An integer that is the number of times to try before
869 delaring failure. Default is 1.
870 """
871 serial = ad.serial
872 asserts.assert_true(WifiEnums.SSID_KEY in network,
873 "Key '%s' must be present in network definition." %
874 WifiEnums.SSID_KEY)
Ang Li99d8c6d2015-12-09 15:56:13 -0800875 ad.droid.wifiStartTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +0000876 try:
Ang Li82522812016-06-02 13:57:21 -0700877 asserts.assert_true(
878 ad.droid.wifiConnect(network),
879 "Wi-Fi connect returned false on %s." % serial)
880 connect_result = None
881 for i in range(num_of_tries):
882 try:
883 connect_result = ad.ed.pop_event(WifiEventNames.WIFI_CONNECTED,
884 30)
885 break
886 except Empty:
887 pass
888 asserts.assert_true(connect_result,
889 "Failed to connect to Wi-Fi network %s on %s" %
890 (network, serial))
Ang Li31b00782016-06-21 13:04:23 -0700891 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
Ang Li99d8c6d2015-12-09 15:56:13 -0800892 expected_ssid = network[WifiEnums.SSID_KEY]
893 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Ang Li82522812016-06-02 13:57:21 -0700894 asserts.assert_equal(actual_ssid, expected_ssid,
895 "Connected to the wrong network on %s." % serial)
Ang Li31b00782016-06-21 13:04:23 -0700896 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
Ang Li73697b32015-12-03 00:41:53 +0000897 finally:
Ang Li99d8c6d2015-12-09 15:56:13 -0800898 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +0000899
Ang Li82522812016-06-02 13:57:21 -0700900
Ang Li73697b32015-12-03 00:41:53 +0000901def start_wifi_single_scan(ad, scan_setting):
902 """Starts wifi single shot scan.
903
904 Args:
905 ad: android_device object to initiate connection on.
906 scan_setting: A dict representing the settings of the scan.
907
908 Returns:
909 If scan was started successfully, event data of success event is returned.
910 """
Ang Li82522812016-06-02 13:57:21 -0700911 idx = ad.droid.wifiScannerStartScan(scan_setting)
912 event = ad.ed.pop_event("WifiScannerScan%sonSuccess" % idx, SHORT_TIMEOUT)
Ang Li31b00782016-06-21 13:04:23 -0700913 ad.log.debug("Got event %s", event)
Ang Li73697b32015-12-03 00:41:53 +0000914 return event['data']
915
Ang Li82522812016-06-02 13:57:21 -0700916
Ang Li73697b32015-12-03 00:41:53 +0000917def track_connection(ad, network_ssid, check_connection_count):
918 """Track wifi connection to network changes for given number of counts
919
920 Args:
921 ad: android_device object for forget network.
922 network_ssid: network ssid to which connection would be tracked
923 check_connection_count: Integer for maximum number network connection
Ang Li82522812016-06-02 13:57:21 -0700924 check.
Ang Li73697b32015-12-03 00:41:53 +0000925 Returns:
Ang Li73697b32015-12-03 00:41:53 +0000926 True if connection to given network happen, else return False.
927 """
928 droid, ed = ad.droid, ad.ed
929 droid.wifiStartTrackingStateChange()
930 while check_connection_count > 0:
Ang Li8e767182015-12-09 17:29:24 -0800931 connect_network = ed.pop_event("WifiNetworkConnected", 120)
Ang Li31b00782016-06-21 13:04:23 -0700932 ad.log.info("Connected to network %s", connect_network)
Ang Li82522812016-06-02 13:57:21 -0700933 if (WifiEnums.SSID_KEY in connect_network['data'] and
934 connect_network['data'][WifiEnums.SSID_KEY] == network_ssid):
935 return True
Ang Li8e767182015-12-09 17:29:24 -0800936 check_connection_count -= 1
Ang Li73697b32015-12-03 00:41:53 +0000937 droid.wifiStopTrackingStateChange()
938 return False
939
Ang Li82522812016-06-02 13:57:21 -0700940
Ang Li73697b32015-12-03 00:41:53 +0000941def get_scan_time_and_channels(wifi_chs, scan_setting, stime_channel):
942 """Calculate the scan time required based on the band or channels in scan
943 setting
944
945 Args:
946 wifi_chs: Object of channels supported
947 scan_setting: scan setting used for start scan
948 stime_channel: scan time per channel
949
950 Returns:
951 scan_time: time required for completing a scan
952 scan_channels: channel used for scanning
953 """
954 scan_time = 0
955 scan_channels = []
956 if "band" in scan_setting and "channels" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -0800957 scan_channels = wifi_chs.band_to_freq(scan_setting["band"])
Ang Li73697b32015-12-03 00:41:53 +0000958 elif "channels" in scan_setting and "band" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -0800959 scan_channels = scan_setting["channels"]
Ang Li73697b32015-12-03 00:41:53 +0000960 scan_time = len(scan_channels) * stime_channel
961 for channel in scan_channels:
Ang Li8e767182015-12-09 17:29:24 -0800962 if channel in WifiEnums.DFS_5G_FREQUENCIES:
Ang Li82522812016-06-02 13:57:21 -0700963 scan_time += 132 #passive scan time on DFS
Ang Li73697b32015-12-03 00:41:53 +0000964 return scan_time, scan_channels
965
Ang Li82522812016-06-02 13:57:21 -0700966
Ang Li73697b32015-12-03 00:41:53 +0000967def start_wifi_track_bssid(ad, track_setting):
968 """Start tracking Bssid for the given settings.
969
970 Args:
971 ad: android_device object.
972 track_setting: Setting for which the bssid tracking should be started
973
974 Returns:
975 If tracking started successfully, event data of success event is returned.
976 """
977 droid, ed = ad.droid, ad.ed
978 idx = droid.wifiScannerStartTrackingBssids(
Ang Li82522812016-06-02 13:57:21 -0700979 track_setting["bssidInfos"], track_setting["apLostThreshold"])
Ang Li73697b32015-12-03 00:41:53 +0000980 event = ed.pop_event("WifiScannerBssid{}onSuccess".format(idx),
981 SHORT_TIMEOUT)
982 return event['data']
983
Ang Li82522812016-06-02 13:57:21 -0700984
Ang Li73697b32015-12-03 00:41:53 +0000985def convert_pem_key_to_pkcs8(in_file, out_file):
986 """Converts the key file generated by us to the format required by
987 Android using openssl.
988
989 The input file must have the extension "pem". The output file must
990 have the extension "der".
991
992 Args:
993 in_file: The original key file.
994 out_file: The full path to the converted key file, including
995 filename.
996 """
Ang Li82522812016-06-02 13:57:21 -0700997 asserts.assert_true(in_file.endswith(".pem"), "Input file has to be .pem.")
998 asserts.assert_true(
999 out_file.endswith(".der"), "Output file has to be .der.")
Ang Li73697b32015-12-03 00:41:53 +00001000 cmd = ("openssl pkcs8 -inform PEM -in {} -outform DER -out {} -nocrypt"
1001 " -topk8").format(in_file, out_file)
Ang Lifee28402016-07-13 13:43:29 -07001002 utils.exe_cmd(cmd)
Ang Li73697b32015-12-03 00:41:53 +00001003
Ang Li82522812016-06-02 13:57:21 -07001004
Ang Li73697b32015-12-03 00:41:53 +00001005def check_internet_connection(ad, ping_addr):
1006 """Validate internet connection by pinging the address provided.
1007
1008 Args:
1009 ad: android_device object.
1010 ping_addr: address on internet for pinging.
1011
1012 Returns:
1013 True, if address ping successful
1014 """
1015 droid, ed = ad.droid, ad.ed
1016 ping = droid.httpPing(ping_addr)
Ang Li31b00782016-06-21 13:04:23 -07001017 ad.log.info("Http ping result: %s.", ping)
Ang Li73697b32015-12-03 00:41:53 +00001018 return ping
1019
Ang Li82522812016-06-02 13:57:21 -07001020
Ang Li73697b32015-12-03 00:41:53 +00001021#TODO(angli): This can only verify if an actual value is exactly the same.
1022# Would be nice to be able to verify an actual value is one of serveral.
1023def verify_wifi_connection_info(ad, expected_con):
1024 """Verifies that the information of the currently connected wifi network is
1025 as expected.
1026
1027 Args:
1028 expected_con: A dict representing expected key-value pairs for wifi
1029 connection. e.g. {"SSID": "test_wifi"}
1030 """
1031 current_con = ad.droid.wifiGetConnectionInfo()
Ang Li374d7602016-02-08 17:27:27 -08001032 case_insensitive = ["BSSID", "supplicant_state"]
Ang Li31b00782016-06-21 13:04:23 -07001033 ad.log.debug("Current connection: %s", current_con)
Ang Li73697b32015-12-03 00:41:53 +00001034 for k, expected_v in expected_con.items():
Ang Li9a66de72016-02-08 15:26:38 -08001035 # Do not verify authentication related fields.
1036 if k == "password":
1037 continue
Ang Li82522812016-06-02 13:57:21 -07001038 msg = "Field %s does not exist in wifi connection info %s." % (
1039 k, current_con)
Ang Li374d7602016-02-08 17:27:27 -08001040 if k not in current_con:
1041 raise signals.TestFailure(msg)
1042 actual_v = current_con[k]
1043 if k in case_insensitive:
1044 actual_v = actual_v.lower()
1045 expected_v = expected_v.lower()
Ang Li73697b32015-12-03 00:41:53 +00001046 msg = "Expected %s to be %s, actual %s is %s." % (k, expected_v, k,
Ang Li82522812016-06-02 13:57:21 -07001047 actual_v)
Ang Li374d7602016-02-08 17:27:27 -08001048 if actual_v != expected_v:
1049 raise signals.TestFailure(msg)
Ang Li73697b32015-12-03 00:41:53 +00001050
Ang Li82522812016-06-02 13:57:21 -07001051
1052def eap_connect(config,
1053 ad,
1054 validate_con=True,
1055 ping_addr=DEFAULT_PING_ADDR,
1056 assert_on_fail=True):
Ang Li73697b32015-12-03 00:41:53 +00001057 """Connects to an enterprise network and verify connection.
1058
1059 This logic expect the enterprise network to have Internet access.
1060
1061 Args:
1062 config: A dict representing a wifi enterprise configuration.
1063 ad: The android_device to operate with.
1064 validate_con: If True, validate Internet connection after connecting to
1065 the network.
1066
1067 Returns:
1068 True if the connection is successful and Internet access works.
1069 """
Ang Li82522812016-06-02 13:57:21 -07001070 _assert_on_fail_handler(_eap_connect, assert_on_fail, config, ad,
1071 validate_con, ping_addr)
1072
1073
1074def _eap_connect(config, ad, validate_con=True, ping_addr=DEFAULT_PING_ADDR):
1075 """Connects to an enterprise network and verify connection.
1076
1077 This logic expect the enterprise network to have Internet access.
1078
1079 Args:
1080 config: A dict representing a wifi enterprise configuration.
1081 ad: The android_device to operate with.
1082 validate_con: If True, validate Internet connection after connecting to
1083 the network.
1084 """
Ang Li73697b32015-12-03 00:41:53 +00001085 droid, ed = ad.droid, ad.ed
Ang Li82522812016-06-02 13:57:21 -07001086 serial = ad.serial
Ang Li6b557182015-11-11 17:19:17 -08001087 start_wifi_connection_scan(ad)
Ang Li73697b32015-12-03 00:41:53 +00001088 expect_ssid = None
1089 if WifiEnums.SSID_KEY in config:
1090 expect_ssid = config[WifiEnums.SSID_KEY]
Ang Li31b00782016-06-21 13:04:23 -07001091 ad.log.info("Connecting to %s.", expect_ssid)
Ang Li73697b32015-12-03 00:41:53 +00001092 else:
Ang Li31b00782016-06-21 13:04:23 -07001093 ad.log.info("Connecting.")
Ang Li6b557182015-11-11 17:19:17 -08001094 ad.droid.wifiEnterpriseConnect(config)
Ang Li73697b32015-12-03 00:41:53 +00001095 try:
1096 event = ed.pop_event("WifiManagerEnterpriseConnectOnSuccess", 30)
Ang Li31b00782016-06-21 13:04:23 -07001097 ad.log.info("Connection started.")
Ang Li82522812016-06-02 13:57:21 -07001098 except Empty:
1099 asserts.fail("Failed to start connection process to %s on %s" %
1100 (config, serial))
1101 try:
Ang Li73697b32015-12-03 00:41:53 +00001102 event = ed.pop_event(WifiEventNames.WIFI_CONNECTED, 60)
1103 except Empty:
Ang Li82522812016-06-02 13:57:21 -07001104 asserts.fail("Failed to connect to %s on %s." % (config, serial))
Ang Li73697b32015-12-03 00:41:53 +00001105 log.debug(event)
1106 if expect_ssid:
1107 actual_ssid = event["data"][WifiEnums.SSID_KEY]
Ang Li82522812016-06-02 13:57:21 -07001108 asserts.assert_equal(expect_ssid, actual_ssid)
Ang Li31b00782016-06-21 13:04:23 -07001109 ad.log.info("Connected to %s.", expect_ssid)
Ang Li73697b32015-12-03 00:41:53 +00001110 else:
Ang Li31b00782016-06-21 13:04:23 -07001111 ad.log.info("Connected successfully.")
Ang Li73697b32015-12-03 00:41:53 +00001112 if validate_con:
Ang Li31b00782016-06-21 13:04:23 -07001113 ad.log.info("Checking Internet access.")
Ang Li73697b32015-12-03 00:41:53 +00001114 # Wait for data connection to stabilize.
1115 time.sleep(4)
Ang Li6b557182015-11-11 17:19:17 -08001116 ping = ad.droid.httpPing(ping_addr)
Ang Li31b00782016-06-21 13:04:23 -07001117 ad.log.info("Http ping result: %s.", ping)
Ang Li82522812016-06-02 13:57:21 -07001118 asserts.assert_true(ping,
1119 "No Internet access on device %s on network %s." %
1120 (serial, config))
1121
Ang Li73697b32015-12-03 00:41:53 +00001122
1123def expand_enterprise_config_by_phase2(config):
1124 """Take an enterprise config and generate a list of configs, each with
1125 a different phase2 auth type.
1126
1127 Args:
1128 config: A dict representing enterprise config.
1129
1130 Returns
1131 A list of enterprise configs.
1132 """
1133 results = []
Ang Li0e7e58f2016-02-22 12:15:02 -08001134 phase2_types = WifiEnums.EapPhase2
1135 if config[WifiEnums.Enterprise.EAP] == WifiEnums.Eap.PEAP:
1136 # Skip unsupported phase2 types for PEAP.
1137 phase2_types = [WifiEnums.EapPhase2.GTC, WifiEnums.EapPhase2.MSCHAPV2]
1138 for phase2_type in phase2_types:
Ang Li73697b32015-12-03 00:41:53 +00001139 # Skip a special case for passpoint TTLS.
1140 if (WifiEnums.Enterprise.FQDN in config and
Ang Li82522812016-06-02 13:57:21 -07001141 phase2_type == WifiEnums.EapPhase2.GTC):
Ang Li73697b32015-12-03 00:41:53 +00001142 continue
1143 c = dict(config)
1144 c[WifiEnums.Enterprise.PHASE2] = phase2_type
1145 results.append(c)
1146 return results
Ang Li2d3fe982016-06-08 10:00:43 -07001147
1148
1149def group_attenuators(attenuators):
1150 """Groups a list of attenuators into attenuator groups for backward
1151 compatibility reasons.
1152
1153 Most legacy Wi-Fi setups have two attenuators each connected to a separate
1154 AP. The new Wi-Fi setup has four attenuators, each connected to one channel
1155 on an AP, so two of them are connected to one AP.
1156
1157 To make the existing scripts work in the new setup, when the script needs
1158 to attenuate one AP, it needs to set attenuation on both attenuators
1159 connected to the same AP.
1160
1161 This function groups attenuators properly so the scripts work in both
1162 legacy and new Wi-Fi setups.
1163
1164 Args:
1165 attenuators: A list of attenuator objects, either two or four in length.
1166
1167 Raises:
1168 signals.TestFailure is raised if the attenuator list does not have two
1169 or four objects.
1170 """
1171 attn0 = attenuator.AttenuatorGroup("AP0")
1172 attn1 = attenuator.AttenuatorGroup("AP1")
1173 # Legacy testbed setup has two attenuation channels.
1174 num_of_attns = len(attenuators)
1175 if num_of_attns == 2:
1176 attn0.add(attenuators[0])
1177 attn1.add(attenuators[1])
1178 elif num_of_attns == 4:
1179 attn0.add(attenuators[0])
1180 attn0.add(attenuators[1])
1181 attn1.add(attenuators[2])
1182 attn1.add(attenuators[3])
1183 else:
1184 asserts.fail(("Either two or four attenuators are required for this "
1185 "test, but found %s") % num_of_attns)
1186 return [attn0, attn1]