blob: b6ce1edc622984d69df824a73d53d2167b8ff43b [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
Bindu Mahadev4e710362016-11-17 16:17:11 -080028from acts.test_utils.wifi import wifi_constants
Rebecca Silberstein8c422e62016-07-19 15:04:46 -070029from acts.test_utils.tel import tel_defines
Ang Li73697b32015-12-03 00:41:53 +000030
Bindu Mahadev1d3991e2017-03-20 18:06:54 -070031# Default timeout used for reboot, toggle WiFi and Airplane mode,
32# for the system to settle down after the operation.
33DEFAULT_TIMEOUT = 10
Ang Li73697b32015-12-03 00:41:53 +000034# Number of seconds to wait for events that are supposed to happen quickly.
35# Like onSuccess for start background scan and confirmation on wifi state
36# change.
37SHORT_TIMEOUT = 30
38
Ang Li73697b32015-12-03 00:41:53 +000039# Speed of light in m/s.
40SPEED_OF_LIGHT = 299792458
41
42DEFAULT_PING_ADDR = "http://www.google.com/robots.txt"
43
Ang Li82522812016-06-02 13:57:21 -070044
Ang Li73697b32015-12-03 00:41:53 +000045class WifiEnums():
46
47 SSID_KEY = "SSID"
Bindu Mahadev3c54c492017-02-15 16:00:08 -080048 NETID_KEY = "network_id"
Ang Li73697b32015-12-03 00:41:53 +000049 BSSID_KEY = "BSSID"
50 PWD_KEY = "password"
51 frequency_key = "frequency"
52 APBAND_KEY = "apBand"
Roshan Piusce821342018-01-10 11:03:04 -080053 HIDDEN_KEY = "hiddenSSID"
Ang Li73697b32015-12-03 00:41:53 +000054
55 WIFI_CONFIG_APBAND_2G = 0
56 WIFI_CONFIG_APBAND_5G = 1
57
Ang Li82522812016-06-02 13:57:21 -070058 WIFI_WPS_INFO_PBC = 0
59 WIFI_WPS_INFO_DISPLAY = 1
60 WIFI_WPS_INFO_KEYPAD = 2
61 WIFI_WPS_INFO_LABEL = 3
62 WIFI_WPS_INFO_INVALID = 4
Ang Li73697b32015-12-03 00:41:53 +000063
64 class CountryCode():
65 CHINA = "CN"
66 JAPAN = "JP"
67 UK = "GB"
68 US = "US"
69 UNKNOWN = "UNKNOWN"
70
71 # Start of Macros for EAP
72 # EAP types
73 class Eap(IntEnum):
74 NONE = -1
75 PEAP = 0
Ang Li82522812016-06-02 13:57:21 -070076 TLS = 1
Ang Li73697b32015-12-03 00:41:53 +000077 TTLS = 2
Ang Li82522812016-06-02 13:57:21 -070078 PWD = 3
79 SIM = 4
80 AKA = 5
81 AKA_PRIME = 6
82 UNAUTH_TLS = 7
Ang Li73697b32015-12-03 00:41:53 +000083
84 # EAP Phase2 types
85 class EapPhase2(IntEnum):
Ang Li82522812016-06-02 13:57:21 -070086 NONE = 0
87 PAP = 1
88 MSCHAP = 2
89 MSCHAPV2 = 3
90 GTC = 4
Ang Li73697b32015-12-03 00:41:53 +000091
92 class Enterprise:
Ang Li82522812016-06-02 13:57:21 -070093 # Enterprise Config Macros
94 EMPTY_VALUE = "NULL"
95 EAP = "eap"
96 PHASE2 = "phase2"
97 IDENTITY = "identity"
98 ANON_IDENTITY = "anonymous_identity"
99 PASSWORD = "password"
100 SUBJECT_MATCH = "subject_match"
Ang Li73697b32015-12-03 00:41:53 +0000101 ALTSUBJECT_MATCH = "altsubject_match"
102 DOM_SUFFIX_MATCH = "domain_suffix_match"
Ang Li82522812016-06-02 13:57:21 -0700103 CLIENT_CERT = "client_cert"
104 CA_CERT = "ca_cert"
105 ENGINE = "engine"
106 ENGINE_ID = "engine_id"
107 PRIVATE_KEY_ID = "key_id"
108 REALM = "realm"
109 PLMN = "plmn"
110 FQDN = "FQDN"
111 FRIENDLY_NAME = "providerFriendlyName"
112 ROAMING_IDS = "roamingConsortiumIds"
Ang Li73697b32015-12-03 00:41:53 +0000113 # End of Macros for EAP
114
115 # Macros for wifi p2p.
116 WIFI_P2P_SERVICE_TYPE_ALL = 0
117 WIFI_P2P_SERVICE_TYPE_BONJOUR = 1
118 WIFI_P2P_SERVICE_TYPE_UPNP = 2
119 WIFI_P2P_SERVICE_TYPE_VENDOR_SPECIFIC = 255
120
121 class ScanResult:
122 CHANNEL_WIDTH_20MHZ = 0
123 CHANNEL_WIDTH_40MHZ = 1
124 CHANNEL_WIDTH_80MHZ = 2
125 CHANNEL_WIDTH_160MHZ = 3
126 CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4
127
128 # Macros for wifi rtt.
129 class RttType(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700130 TYPE_ONE_SIDED = 1
131 TYPE_TWO_SIDED = 2
Ang Li73697b32015-12-03 00:41:53 +0000132
133 class RttPeerType(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700134 PEER_TYPE_AP = 1
135 PEER_TYPE_STA = 2 # Requires NAN.
136 PEER_P2P_GO = 3
137 PEER_P2P_CLIENT = 4
138 PEER_NAN = 5
Ang Li73697b32015-12-03 00:41:53 +0000139
140 class RttPreamble(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700141 PREAMBLE_LEGACY = 0x01
142 PREAMBLE_HT = 0x02
143 PREAMBLE_VHT = 0x04
Ang Li73697b32015-12-03 00:41:53 +0000144
145 class RttBW(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700146 BW_5_SUPPORT = 0x01
147 BW_10_SUPPORT = 0x02
148 BW_20_SUPPORT = 0x04
149 BW_40_SUPPORT = 0x08
150 BW_80_SUPPORT = 0x10
Ang Li73697b32015-12-03 00:41:53 +0000151 BW_160_SUPPORT = 0x20
152
153 class Rtt(IntEnum):
Ang Li82522812016-06-02 13:57:21 -0700154 STATUS_SUCCESS = 0
155 STATUS_FAILURE = 1
156 STATUS_FAIL_NO_RSP = 2
157 STATUS_FAIL_REJECTED = 3
158 STATUS_FAIL_NOT_SCHEDULED_YET = 4
159 STATUS_FAIL_TM_TIMEOUT = 5
160 STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6
161 STATUS_FAIL_NO_CAPABILITY = 7
162 STATUS_ABORTED = 8
163 STATUS_FAIL_INVALID_TS = 9
164 STATUS_FAIL_PROTOCOL = 10
165 STATUS_FAIL_SCHEDULE = 11
166 STATUS_FAIL_BUSY_TRY_LATER = 12
167 STATUS_INVALID_REQ = 13
168 STATUS_NO_WIFI = 14
169 STATUS_FAIL_FTM_PARAM_OVERRIDE = 15
Ang Li73697b32015-12-03 00:41:53 +0000170
Ang Li82522812016-06-02 13:57:21 -0700171 REASON_UNSPECIFIED = -1
172 REASON_NOT_AVAILABLE = -2
173 REASON_INVALID_LISTENER = -3
174 REASON_INVALID_REQUEST = -4
Ang Li73697b32015-12-03 00:41:53 +0000175
176 class RttParam:
177 device_type = "deviceType"
178 request_type = "requestType"
179 BSSID = "bssid"
180 channel_width = "channelWidth"
181 frequency = "frequency"
182 center_freq0 = "centerFreq0"
183 center_freq1 = "centerFreq1"
184 number_burst = "numberBurst"
185 interval = "interval"
186 num_samples_per_burst = "numSamplesPerBurst"
187 num_retries_per_measurement_frame = "numRetriesPerMeasurementFrame"
188 num_retries_per_FTMR = "numRetriesPerFTMR"
189 lci_request = "LCIRequest"
190 lcr_request = "LCRRequest"
191 burst_timeout = "burstTimeout"
192 preamble = "preamble"
193 bandwidth = "bandwidth"
194 margin = "margin"
195
196 RTT_MARGIN_OF_ERROR = {
197 RttBW.BW_80_SUPPORT: 2,
198 RttBW.BW_40_SUPPORT: 5,
199 RttBW.BW_20_SUPPORT: 5
200 }
201
202 # Macros as specified in the WifiScanner code.
Ang Li82522812016-06-02 13:57:21 -0700203 WIFI_BAND_UNSPECIFIED = 0 # not specified
204 WIFI_BAND_24_GHZ = 1 # 2.4 GHz band
205 WIFI_BAND_5_GHZ = 2 # 5 GHz band without DFS channels
206 WIFI_BAND_5_GHZ_DFS_ONLY = 4 # 5 GHz band with DFS channels
207 WIFI_BAND_5_GHZ_WITH_DFS = 6 # 5 GHz band with DFS channels
208 WIFI_BAND_BOTH = 3 # both bands without DFS channels
209 WIFI_BAND_BOTH_WITH_DFS = 7 # both bands with DFS channels
Ang Li73697b32015-12-03 00:41:53 +0000210
211 REPORT_EVENT_AFTER_BUFFER_FULL = 0
212 REPORT_EVENT_AFTER_EACH_SCAN = 1
213 REPORT_EVENT_FULL_SCAN_RESULT = 2
214
215 # US Wifi frequencies
216 ALL_2G_FREQUENCIES = [2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452,
217 2457, 2462]
218 DFS_5G_FREQUENCIES = [5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580,
219 5600, 5620, 5640, 5660, 5680, 5700, 5720]
220 NONE_DFS_5G_FREQUENCIES = [5180, 5200, 5220, 5240, 5745, 5765, 5785, 5805,
221 5825]
222 ALL_5G_FREQUENCIES = DFS_5G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES
223
224 band_to_frequencies = {
Ang Li82522812016-06-02 13:57:21 -0700225 WIFI_BAND_24_GHZ: ALL_2G_FREQUENCIES,
226 WIFI_BAND_5_GHZ: NONE_DFS_5G_FREQUENCIES,
227 WIFI_BAND_5_GHZ_DFS_ONLY: DFS_5G_FREQUENCIES,
228 WIFI_BAND_5_GHZ_WITH_DFS: ALL_5G_FREQUENCIES,
229 WIFI_BAND_BOTH: ALL_2G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES,
230 WIFI_BAND_BOTH_WITH_DFS: ALL_5G_FREQUENCIES + ALL_2G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000231 }
232
233 # All Wifi frequencies to channels lookup.
234 freq_to_channel = {
235 2412: 1,
236 2417: 2,
237 2422: 3,
238 2427: 4,
239 2432: 5,
240 2437: 6,
241 2442: 7,
242 2447: 8,
243 2452: 9,
244 2457: 10,
245 2462: 11,
246 2467: 12,
247 2472: 13,
248 2484: 14,
249 4915: 183,
250 4920: 184,
251 4925: 185,
252 4935: 187,
253 4940: 188,
254 4945: 189,
255 4960: 192,
256 4980: 196,
257 5035: 7,
258 5040: 8,
259 5045: 9,
260 5055: 11,
261 5060: 12,
262 5080: 16,
263 5170: 34,
264 5180: 36,
265 5190: 38,
266 5200: 40,
267 5210: 42,
268 5220: 44,
269 5230: 46,
270 5240: 48,
271 5260: 52,
272 5280: 56,
273 5300: 60,
274 5320: 64,
275 5500: 100,
276 5520: 104,
277 5540: 108,
278 5560: 112,
279 5580: 116,
280 5600: 120,
281 5620: 124,
282 5640: 128,
283 5660: 132,
284 5680: 136,
285 5700: 140,
286 5745: 149,
287 5765: 153,
288 5785: 157,
289 5805: 161,
290 5825: 165,
291 }
292
293 # All Wifi channels to frequencies lookup.
294 channel_2G_to_freq = {
295 1: 2412,
296 2: 2417,
297 3: 2422,
298 4: 2427,
299 5: 2432,
300 6: 2437,
301 7: 2442,
302 8: 2447,
303 9: 2452,
304 10: 2457,
305 11: 2462,
306 12: 2467,
307 13: 2472,
308 14: 2484
309 }
310
311 channel_5G_to_freq = {
312 183: 4915,
313 184: 4920,
314 185: 4925,
315 187: 4935,
316 188: 4940,
317 189: 4945,
318 192: 4960,
319 196: 4980,
320 7: 5035,
321 8: 5040,
322 9: 5045,
323 11: 5055,
324 12: 5060,
325 16: 5080,
326 34: 5170,
327 36: 5180,
328 38: 5190,
329 40: 5200,
330 42: 5210,
331 44: 5220,
332 46: 5230,
333 48: 5240,
334 52: 5260,
335 56: 5280,
336 60: 5300,
337 64: 5320,
338 100: 5500,
339 104: 5520,
340 108: 5540,
341 112: 5560,
342 116: 5580,
343 120: 5600,
344 124: 5620,
345 128: 5640,
346 132: 5660,
347 136: 5680,
348 140: 5700,
349 149: 5745,
350 153: 5765,
351 157: 5785,
352 161: 5805,
353 165: 5825
354 }
355
Ang Li82522812016-06-02 13:57:21 -0700356
Ang Li73697b32015-12-03 00:41:53 +0000357class WifiChannelBase:
358 ALL_2G_FREQUENCIES = []
359 DFS_5G_FREQUENCIES = []
360 NONE_DFS_5G_FREQUENCIES = []
361 ALL_5G_FREQUENCIES = DFS_5G_FREQUENCIES + NONE_DFS_5G_FREQUENCIES
362 MIX_CHANNEL_SCAN = []
363
364 def band_to_freq(self, band):
365 _band_to_frequencies = {
366 WifiEnums.WIFI_BAND_24_GHZ: self.ALL_2G_FREQUENCIES,
367 WifiEnums.WIFI_BAND_5_GHZ: self.NONE_DFS_5G_FREQUENCIES,
368 WifiEnums.WIFI_BAND_5_GHZ_DFS_ONLY: self.DFS_5G_FREQUENCIES,
369 WifiEnums.WIFI_BAND_5_GHZ_WITH_DFS: self.ALL_5G_FREQUENCIES,
Ang Li82522812016-06-02 13:57:21 -0700370 WifiEnums.WIFI_BAND_BOTH:
371 self.ALL_2G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES,
372 WifiEnums.WIFI_BAND_BOTH_WITH_DFS:
373 self.ALL_5G_FREQUENCIES + self.ALL_2G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000374 }
375 return _band_to_frequencies[band]
376
Ang Li82522812016-06-02 13:57:21 -0700377
Ang Li73697b32015-12-03 00:41:53 +0000378class WifiChannelUS(WifiChannelBase):
379 # US Wifi frequencies
380 ALL_2G_FREQUENCIES = [2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452,
381 2457, 2462]
382 NONE_DFS_5G_FREQUENCIES = [5180, 5200, 5220, 5240, 5745, 5765, 5785, 5805,
383 5825]
Ang Li82522812016-06-02 13:57:21 -0700384 MIX_CHANNEL_SCAN = [2412, 2437, 2462, 5180, 5200, 5280, 5260, 5300, 5500,
385 5320, 5520, 5560, 5700, 5745, 5805]
Ang Li73697b32015-12-03 00:41:53 +0000386
387 def __init__(self, model=None):
Girish Moturu0c567b02017-08-11 16:20:01 -0700388 self.DFS_5G_FREQUENCIES = [5260, 5280, 5300, 5320, 5500, 5520,
389 5540, 5560, 5580, 5600, 5620, 5640,
390 5660, 5680, 5700, 5720]
391 self.ALL_5G_FREQUENCIES = self.DFS_5G_FREQUENCIES + self.NONE_DFS_5G_FREQUENCIES
Ang Li73697b32015-12-03 00:41:53 +0000392
Girish Moturuf02fa1d2017-05-21 09:51:23 +0530393class WifiReferenceNetworks:
394 """ Class to parse and return networks of different band and
395 auth type from reference_networks
396 """
397 def __init__(self, obj):
398 self.reference_networks = obj
399 self.WIFI_2G = "2g"
400 self.WIFI_5G = "5g"
401
402 self.secure_networks_2g = []
403 self.secure_networks_5g = []
404 self.open_networks_2g = []
405 self.open_networks_5g = []
406 self._parse_networks()
407
408 def _parse_networks(self):
409 for network in self.reference_networks:
410 for key in network:
411 if key == self.WIFI_2G:
412 if "password" in network[key]:
413 self.secure_networks_2g.append(network[key])
414 else:
415 self.open_networks_2g.append(network[key])
416 else:
417 if "password" in network[key]:
418 self.secure_networks_5g.append(network[key])
419 else:
420 self.open_networks_5g.append(network[key])
421
422 def return_2g_secure_networks(self):
423 return self.secure_networks_2g
424
425 def return_5g_secure_networks(self):
426 return self.secure_networks_5g
427
428 def return_2g_open_networks(self):
429 return self.open_networks_2g
430
431 def return_5g_open_networks(self):
432 return self.open_networks_5g
433
434 def return_secure_networks(self):
435 return self.secure_networks_2g + self.secure_networks_5g
436
437 def return_open_networks(self):
438 return self.open_networks_2g + self.open_networks_5g
439
Ang Li82522812016-06-02 13:57:21 -0700440
441def _assert_on_fail_handler(func, assert_on_fail, *args, **kwargs):
442 """Wrapper function that handles the bahevior of assert_on_fail.
443
444 When assert_on_fail is True, let all test signals through, which can
445 terminate test cases directly. When assert_on_fail is False, the wrapper
446 raises no test signals and reports operation status by returning True or
447 False.
448
449 Args:
450 func: The function to wrap. This function reports operation status by
451 raising test signals.
452 assert_on_fail: A boolean that specifies if the output of the wrapper
453 is test signal based or return value based.
454 args: Positional args for func.
455 kwargs: Name args for func.
456
457 Returns:
458 If assert_on_fail is True, returns True/False to signal operation
459 status, otherwise return nothing.
460 """
461 try:
462 func(*args, **kwargs)
463 if not assert_on_fail:
464 return True
465 except signals.TestSignal:
466 if assert_on_fail:
467 raise
468 return False
469
470
471def assert_network_in_list(target, network_list):
472 """Makes sure a specified target Wi-Fi network exists in a list of Wi-Fi
473 networks.
474
475 Args:
476 target: A dict representing a Wi-Fi network.
477 E.g. {WifiEnums.SSID_KEY: "SomeNetwork"}
478 network_list: A list of dicts, each representing a Wi-Fi network.
479 """
480 match_results = match_networks(target, network_list)
481 asserts.assert_true(
482 match_results, "Target network %s, does not exist in network list %s" %
483 (target, network_list))
484
485
Ang Li73697b32015-12-03 00:41:53 +0000486def match_networks(target_params, networks):
487 """Finds the WiFi networks that match a given set of parameters in a list
488 of WiFi networks.
489
Girish Moturubc48d9f2016-11-01 13:24:14 -0700490 To be considered a match, the network should contain every key-value pair
491 of target_params
Ang Li73697b32015-12-03 00:41:53 +0000492
493 Args:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700494 target_params: A dict with 1 or more key-value pairs representing a Wi-Fi network.
495 E.g { 'SSID': 'wh_ap1_5g', 'BSSID': '30:b5:c2:33:e4:47' }
Ang Li73697b32015-12-03 00:41:53 +0000496 networks: A list of dict objects representing WiFi networks.
497
498 Returns:
499 The networks that match the target parameters.
500 """
501 results = []
Betty Zhou3caa0982017-02-22 19:26:20 -0800502 asserts.assert_true(target_params,
503 "Expected networks object 'target_params' is empty")
Ang Li73697b32015-12-03 00:41:53 +0000504 for n in networks:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700505 add_network = 1
Ang Li9a66de72016-02-08 15:26:38 -0800506 for k, v in target_params.items():
507 if k not in n:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700508 add_network = 0
509 break
Ang Li9a66de72016-02-08 15:26:38 -0800510 if n[k] != v:
Girish Moturubc48d9f2016-11-01 13:24:14 -0700511 add_network = 0
512 break
513 if add_network:
Ang Li73697b32015-12-03 00:41:53 +0000514 results.append(n)
515 return results
516
Ang Li82522812016-06-02 13:57:21 -0700517
518def wifi_toggle_state(ad, new_state=None, assert_on_fail=True):
Ang Li6b557182015-11-11 17:19:17 -0800519 """Toggles the state of wifi.
Ang Li73697b32015-12-03 00:41:53 +0000520
Ang Li6b557182015-11-11 17:19:17 -0800521 Args:
522 ad: An AndroidDevice object.
523 new_state: Wifi state to set to. If None, opposite of the current state.
Ang Li82522812016-06-02 13:57:21 -0700524 assert_on_fail: If True, error checks in this function will raise test
525 failure signals.
Ang Li73697b32015-12-03 00:41:53 +0000526
Ang Li6b557182015-11-11 17:19:17 -0800527 Returns:
Ang Li82522812016-06-02 13:57:21 -0700528 If assert_on_fail is False, function returns True if the toggle was
529 successful, False otherwise. If assert_on_fail is True, no return value.
530 """
Betty Zhou3caa0982017-02-22 19:26:20 -0800531 return _assert_on_fail_handler(
532 _wifi_toggle_state, assert_on_fail, ad, new_state=new_state)
Ang Li82522812016-06-02 13:57:21 -0700533
534
535def _wifi_toggle_state(ad, new_state=None):
536 """Toggles the state of wifi.
537
538 TestFailure signals are raised when something goes wrong.
539
540 Args:
541 ad: An AndroidDevice object.
542 new_state: The state to set Wi-Fi to. If None, opposite of the current
543 state will be set.
Ang Li6b557182015-11-11 17:19:17 -0800544 """
Ang Li31b00782016-06-21 13:04:23 -0700545 if new_state is None:
546 new_state = not ad.droid.wifiCheckState()
Ang Lie5c85c92016-07-27 15:38:09 -0700547 elif new_state == ad.droid.wifiCheckState():
548 # Check if the new_state is already achieved, so we don't wait for the
549 # state change event by mistake.
550 return
551 ad.droid.wifiStartTrackingStateChange()
Ang Li31b00782016-06-21 13:04:23 -0700552 ad.log.info("Setting Wi-Fi state to %s.", new_state)
553 # Setting wifi state.
Ang Li6b557182015-11-11 17:19:17 -0800554 ad.droid.wifiToggleState(new_state)
Ang Lie2e93a22016-06-22 16:43:28 -0700555 fail_msg = "Failed to set Wi-Fi state to %s on %s." % (new_state,
556 ad.serial)
Ang Li73697b32015-12-03 00:41:53 +0000557 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800558 event = ad.ed.pop_event(wifi_constants.SUPPLICANT_CON_CHANGED,
Ang Li82522812016-06-02 13:57:21 -0700559 SHORT_TIMEOUT)
560 asserts.assert_equal(event['data']['Connected'], new_state, fail_msg)
Ang Li73697b32015-12-03 00:41:53 +0000561 except Empty:
Ang Li82522812016-06-02 13:57:21 -0700562 # Supplicant connection event is not always reliable. We double check
563 # here and call it a success as long as the new state equals the
564 # expected state.
Prashant Agrawale19e7ec2016-07-21 11:14:22 +0530565 time.sleep(5)
Ang Li82522812016-06-02 13:57:21 -0700566 asserts.assert_equal(new_state, ad.droid.wifiCheckState(), fail_msg)
Ang Li6b557182015-11-11 17:19:17 -0800567 finally:
568 ad.droid.wifiStopTrackingStateChange()
569
Ang Li82522812016-06-02 13:57:21 -0700570
Ang Li6b557182015-11-11 17:19:17 -0800571def reset_wifi(ad):
Ang Li1179fa72016-06-16 09:44:06 -0700572 """Clears all saved Wi-Fi networks on a device.
573
574 This will turn Wi-Fi on.
Ang Li6b557182015-11-11 17:19:17 -0800575
576 Args:
577 ad: An AndroidDevice object.
578
Ang Li6b557182015-11-11 17:19:17 -0800579 """
Ang Li6b557182015-11-11 17:19:17 -0800580 networks = ad.droid.wifiGetConfiguredNetworks()
581 if not networks:
582 return
583 for n in networks:
584 ad.droid.wifiForgetNetwork(n['networkId'])
585 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800586 event = ad.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS,
Ang Li82522812016-06-02 13:57:21 -0700587 SHORT_TIMEOUT)
Ang Li6b557182015-11-11 17:19:17 -0800588 except Empty:
Ang Li1179fa72016-06-16 09:44:06 -0700589 logging.warning("Could not confirm the removal of network %s.", n)
590 # Check again to see if there's any network left.
Betty Zhou3caa0982017-02-22 19:26:20 -0800591 asserts.assert_true(
592 not ad.droid.wifiGetConfiguredNetworks(),
593 "Failed to remove these configured Wi-Fi networks: %s" % networks)
Ang Li82522812016-06-02 13:57:21 -0700594
Ang Li73697b32015-12-03 00:41:53 +0000595
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700596def toggle_airplane_mode_on_and_off(ad):
597 """Turn ON and OFF Airplane mode.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800598
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700599 ad: An AndroidDevice object.
600 Returns: Assert if turning on/off Airplane mode fails.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800601
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700602 """
603 ad.log.debug("Toggling Airplane mode ON.")
604 asserts.assert_true(
605 utils.force_airplane_mode(ad, True),
606 "Can not turn on airplane mode on: %s" % ad.serial)
607 time.sleep(DEFAULT_TIMEOUT)
608 ad.log.debug("Toggling Airplane mode OFF.")
609 asserts.assert_true(
610 utils.force_airplane_mode(ad, False),
611 "Can not turn on airplane mode on: %s" % ad.serial)
612 time.sleep(DEFAULT_TIMEOUT)
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800613
614
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700615def toggle_wifi_off_and_on(ad):
616 """Turn OFF and ON WiFi.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800617
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700618 ad: An AndroidDevice object.
619 Returns: Assert if turning off/on WiFi fails.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800620
Bindu Mahadev1d3991e2017-03-20 18:06:54 -0700621 """
622 ad.log.debug("Toggling wifi OFF.")
623 wifi_toggle_state(ad, False)
624 time.sleep(DEFAULT_TIMEOUT)
625 ad.log.debug("Toggling wifi ON.")
626 wifi_toggle_state(ad, True)
627 time.sleep(DEFAULT_TIMEOUT)
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800628
629
Ang Li73697b32015-12-03 00:41:53 +0000630def wifi_forget_network(ad, net_ssid):
Ang Li8e767182015-12-09 17:29:24 -0800631 """Remove configured Wifi network on an android device.
Ang Li73697b32015-12-03 00:41:53 +0000632
Ang Li8e767182015-12-09 17:29:24 -0800633 Args:
634 ad: android_device object for forget network.
635 net_ssid: ssid of network to be forget
Ang Li73697b32015-12-03 00:41:53 +0000636
Ang Li8e767182015-12-09 17:29:24 -0800637 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700638 networks = ad.droid.wifiGetConfiguredNetworks()
Ang Li8e767182015-12-09 17:29:24 -0800639 if not networks:
640 return
641 for n in networks:
642 if net_ssid in n[WifiEnums.SSID_KEY]:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700643 ad.droid.wifiForgetNetwork(n['networkId'])
Ang Li8e767182015-12-09 17:29:24 -0800644 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800645 event = ad.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS,
Betty Zhou3caa0982017-02-22 19:26:20 -0800646 SHORT_TIMEOUT)
Ang Li8e767182015-12-09 17:29:24 -0800647 except Empty:
Girish Moturu1bf82302016-11-01 13:27:00 -0700648 asserts.fail("Failed to remove network %s." % n)
Ang Li73697b32015-12-03 00:41:53 +0000649
Ang Li82522812016-06-02 13:57:21 -0700650
Ang Li73697b32015-12-03 00:41:53 +0000651def wifi_test_device_init(ad):
652 """Initializes an android device for wifi testing.
653
654 0. Make sure SL4A connection is established on the android device.
655 1. Disable location service's WiFi scan.
656 2. Turn WiFi on.
657 3. Clear all saved networks.
658 4. Set country code to US.
659 5. Enable WiFi verbose logging.
660 6. Sync device time with computer time.
661 7. Turn off cellular data.
Ang Lifee28402016-07-13 13:43:29 -0700662 8. Turn off ambient display.
Ang Li73697b32015-12-03 00:41:53 +0000663 """
Ang Lifee28402016-07-13 13:43:29 -0700664 utils.require_sl4a((ad, ))
Ang Li73697b32015-12-03 00:41:53 +0000665 ad.droid.wifiScannerToggleAlwaysAvailable(False)
666 msg = "Failed to turn off location service's scan."
Ang Li82522812016-06-02 13:57:21 -0700667 asserts.assert_true(not ad.droid.wifiScannerIsAlwaysAvailable(), msg)
668 wifi_toggle_state(ad, True)
Ang Li6b557182015-11-11 17:19:17 -0800669 reset_wifi(ad)
Ang Li73697b32015-12-03 00:41:53 +0000670 ad.droid.wifiEnableVerboseLogging(1)
Ang Li8e767182015-12-09 17:29:24 -0800671 msg = "Failed to enable WiFi verbose logging."
Ang Li82522812016-06-02 13:57:21 -0700672 asserts.assert_equal(ad.droid.wifiGetVerboseLoggingLevel(), 1, msg)
Ang Li73697b32015-12-03 00:41:53 +0000673 # We don't verify the following settings since they are not critical.
Ang Lie2e93a22016-06-22 16:43:28 -0700674 # Set wpa_supplicant log level to EXCESSIVE.
675 output = ad.adb.shell("wpa_cli -i wlan0 -p -g@android:wpa_wlan0 IFNAME="
676 "wlan0 log_level EXCESSIVE")
677 ad.log.info("wpa_supplicant log change status: %s", output)
Ang Lifee28402016-07-13 13:43:29 -0700678 utils.sync_device_time(ad)
Ang Li0bf8e022016-01-04 17:34:48 -0800679 ad.droid.telephonyToggleDataConnection(False)
Ang Li73697b32015-12-03 00:41:53 +0000680 # TODO(angli): need to verify the country code was actually set. No generic
681 # way to check right now.
682 ad.adb.shell("halutil -country %s" % WifiEnums.CountryCode.US)
Ang Lifee28402016-07-13 13:43:29 -0700683 utils.set_ambient_display(ad, False)
Ang Li73697b32015-12-03 00:41:53 +0000684
Ang Li82522812016-06-02 13:57:21 -0700685
Ang Li6b557182015-11-11 17:19:17 -0800686def start_wifi_connection_scan(ad):
Ang Li73697b32015-12-03 00:41:53 +0000687 """Starts a wifi connection scan and wait for results to become available.
688
689 Args:
Ang Li6b557182015-11-11 17:19:17 -0800690 ad: An AndroidDevice object.
Ang Li73697b32015-12-03 00:41:53 +0000691 """
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800692 ad.ed.clear_all_events()
Ang Li6b557182015-11-11 17:19:17 -0800693 ad.droid.wifiStartScan()
Ang Li82522812016-06-02 13:57:21 -0700694 try:
695 ad.ed.pop_event("WifiManagerScanResultsAvailable", 60)
696 except Empty:
697 asserts.fail("Wi-Fi results did not become available within 60s.")
698
Ang Li73697b32015-12-03 00:41:53 +0000699
Roshan Piuscb9bc482018-02-01 14:27:09 -0800700def start_wifi_connection_scan_and_return_status(ad):
701 """
702 Starts a wifi connection scan and wait for results to become available
703 or a scan failure to be reported.
704
705 Args:
706 ad: An AndroidDevice object.
707 Returns:
708 True: if scan succeeded & results are available
709 False: if scan failed
710 """
711 ad.ed.clear_all_events()
712 ad.droid.wifiStartScan()
713 try:
714 events = ad.ed.pop_events(
715 "WifiManagerScan(ResultsAvailable|Failure)", 60)
716 except Empty:
717 asserts.fail(
718 "Wi-Fi scan results/failure did not become available within 60s.")
719 # If there are multiple matches, we check for atleast one success.
720 for event in events:
721 if event["name"] == "WifiManagerScanResultsAvailable":
722 return True
723 elif event["name"] == "WifiManagerScanFailure":
724 ad.log.debug("Scan failure received")
725 return False
726
727
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800728def start_wifi_connection_scan_and_check_for_network(ad, network_ssid,
Roshan Piuscb9bc482018-02-01 14:27:09 -0800729 max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800730 """
731 Start connectivity scans & checks if the |network_ssid| is seen in
732 scan results. The method performs a max of |max_tries| connectivity scans
733 to find the network.
734
735 Args:
736 ad: An AndroidDevice object.
737 network_ssid: SSID of the network we are looking for.
738 max_tries: Number of scans to try.
739 Returns:
740 True: if network_ssid is found in scan results.
741 False: if network_ssid is not found in scan results.
742 """
743 for num_tries in range(max_tries):
Roshan Piuscb9bc482018-02-01 14:27:09 -0800744 if start_wifi_connection_scan_and_return_status(ad):
745 scan_results = ad.droid.wifiGetScanResults()
746 match_results = match_networks(
747 {WifiEnums.SSID_KEY: network_ssid}, scan_results)
748 if len(match_results) > 0:
749 return True
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800750 return False
751
752
753def start_wifi_connection_scan_and_ensure_network_found(ad, network_ssid,
Roshan Piuscb9bc482018-02-01 14:27:09 -0800754 max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800755 """
756 Start connectivity scans & ensure the |network_ssid| is seen in
757 scan results. The method performs a max of |max_tries| connectivity scans
758 to find the network.
759 This method asserts on failure!
760
761 Args:
762 ad: An AndroidDevice object.
763 network_ssid: SSID of the network we are looking for.
764 max_tries: Number of scans to try.
765 """
766 ad.log.info("Starting scans to ensure %s is present", network_ssid)
767 assert_msg = "Failed to find " + network_ssid + " in scan results" \
768 " after " + str(max_tries) + " tries"
769 asserts.assert_true(start_wifi_connection_scan_and_check_for_network(
770 ad, network_ssid, max_tries), assert_msg)
771
772
773def start_wifi_connection_scan_and_ensure_network_not_found(ad, network_ssid,
Roshan Piuscb9bc482018-02-01 14:27:09 -0800774 max_tries=3):
Roshan Pius7f61f1c2018-01-24 18:36:49 -0800775 """
776 Start connectivity scans & ensure the |network_ssid| is not seen in
777 scan results. The method performs a max of |max_tries| connectivity scans
778 to find the network.
779 This method asserts on failure!
780
781 Args:
782 ad: An AndroidDevice object.
783 network_ssid: SSID of the network we are looking for.
784 max_tries: Number of scans to try.
785 """
786 ad.log.info("Starting scans to ensure %s is not present", network_ssid)
787 assert_msg = "Found " + network_ssid + " in scan results" \
788 " after " + str(max_tries) + " tries"
789 asserts.assert_false(start_wifi_connection_scan_and_check_for_network(
790 ad, network_ssid, max_tries), assert_msg)
791
792
Ang Li73697b32015-12-03 00:41:53 +0000793def start_wifi_background_scan(ad, scan_setting):
794 """Starts wifi background scan.
795
796 Args:
797 ad: android_device object to initiate connection on.
798 scan_setting: A dict representing the settings of the scan.
799
800 Returns:
801 If scan was started successfully, event data of success event is returned.
802 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700803 idx = ad.droid.wifiScannerStartBackgroundScan(scan_setting)
804 event = ad.ed.pop_event("WifiScannerScan{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -0800805 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +0000806 return event['data']
807
Ang Li82522812016-06-02 13:57:21 -0700808
Roshan Piusce821342018-01-10 11:03:04 -0800809def start_wifi_tethering(ad, ssid, password, band=None, hidden=None):
Ang Li73697b32015-12-03 00:41:53 +0000810 """Starts wifi tethering on an android_device.
811
812 Args:
813 ad: android_device to start wifi tethering on.
814 ssid: The SSID the soft AP should broadcast.
815 password: The password the soft AP should use.
816 band: The band the soft AP should be set on. It should be either
817 WifiEnums.WIFI_CONFIG_APBAND_2G or WifiEnums.WIFI_CONFIG_APBAND_5G.
Roshan Piusce821342018-01-10 11:03:04 -0800818 hidden: boolean to indicate if the AP needs to be hidden or not.
Ang Li73697b32015-12-03 00:41:53 +0000819
820 Returns:
Girish Moturu3581d612016-11-02 15:08:51 -0700821 No return value. Error checks in this function will raise test failure signals
Ang Li73697b32015-12-03 00:41:53 +0000822 """
Ang Li82522812016-06-02 13:57:21 -0700823 config = {WifiEnums.SSID_KEY: ssid}
Ang Li73697b32015-12-03 00:41:53 +0000824 if password:
825 config[WifiEnums.PWD_KEY] = password
826 if band:
827 config[WifiEnums.APBAND_KEY] = band
Roshan Piusce821342018-01-10 11:03:04 -0800828 if hidden:
829 config[WifiEnums.HIDDEN_KEY] = hidden
Betty Zhou3caa0982017-02-22 19:26:20 -0800830 asserts.assert_true(
831 ad.droid.wifiSetWifiApConfiguration(config),
832 "Failed to update WifiAp Configuration")
Girish Moturu40d7dc22016-11-02 12:14:56 -0700833 ad.droid.wifiStartTrackingTetherStateChange()
834 ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False)
Rebecca Silbersteina2889852016-08-11 00:48:53 -0700835 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700836 ad.ed.pop_event("ConnectivityManagerOnTetheringStarted")
837 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -0800838 lambda x: x["data"]["ACTIVE_TETHER"], 30)
Ang Li76216d12016-09-20 14:51:57 -0700839 ad.log.debug("Tethering started successfully.")
Rebecca Silbersteina2889852016-08-11 00:48:53 -0700840 except Empty:
841 msg = "Failed to receive confirmation of wifi tethering starting"
842 asserts.fail(msg)
843 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700844 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li73697b32015-12-03 00:41:53 +0000845
Betty Zhou3caa0982017-02-22 19:26:20 -0800846
Ang Li73697b32015-12-03 00:41:53 +0000847def stop_wifi_tethering(ad):
848 """Stops wifi tethering on an android_device.
849
850 Args:
851 ad: android_device to stop wifi tethering on.
852 """
Girish Moturu40d7dc22016-11-02 12:14:56 -0700853 ad.droid.wifiStartTrackingTetherStateChange()
854 ad.droid.connectivityStopTethering(tel_defines.TETHERING_WIFI)
Rebecca Silbersteina2889852016-08-11 00:48:53 -0700855 try:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700856 ad.ed.pop_event("WifiManagerApDisabled", 30)
857 ad.ed.wait_for_event("TetherStateChanged",
Betty Zhou3caa0982017-02-22 19:26:20 -0800858 lambda x: not x["data"]["ACTIVE_TETHER"], 30)
Rebecca Silbersteina2889852016-08-11 00:48:53 -0700859 except Empty:
860 msg = "Failed to receive confirmation of wifi tethering stopping"
861 asserts.fail(msg)
862 finally:
Girish Moturu40d7dc22016-11-02 12:14:56 -0700863 ad.droid.wifiStopTrackingTetherStateChange()
Ang Li82522812016-06-02 13:57:21 -0700864
Ang Li76216d12016-09-20 14:51:57 -0700865
Roshan Pius58916a32016-06-16 16:26:44 -0700866def toggle_wifi_and_wait_for_reconnection(ad,
867 network,
868 num_of_tries=1,
869 assert_on_fail=True):
870 """Toggle wifi state and then wait for Android device to reconnect to
871 the provided wifi network.
872
873 This expects the device to be already connected to the provided network.
874
875 Logic steps are
876 1. Ensure that we're connected to the network.
877 2. Turn wifi off.
878 3. Wait for 10 seconds.
879 4. Turn wifi on.
880 5. Wait for the "connected" event, then confirm the connected ssid is the
881 one requested.
882
883 Args:
884 ad: android_device object to initiate connection on.
885 network: A dictionary representing the network to await connection. The
886 dictionary must have the key "SSID".
887 num_of_tries: An integer that is the number of times to try before
888 delaring failure. Default is 1.
889 assert_on_fail: If True, error checks in this function will raise test
890 failure signals.
891
892 Returns:
893 If assert_on_fail is False, function returns True if the toggle was
894 successful, False otherwise. If assert_on_fail is True, no return value.
895 """
Betty Zhou3caa0982017-02-22 19:26:20 -0800896 return _assert_on_fail_handler(
897 _toggle_wifi_and_wait_for_reconnection,
898 assert_on_fail,
899 ad,
900 network,
901 num_of_tries=num_of_tries)
Roshan Pius58916a32016-06-16 16:26:44 -0700902
903
904def _toggle_wifi_and_wait_for_reconnection(ad, network, num_of_tries=1):
905 """Toggle wifi state and then wait for Android device to reconnect to
906 the provided wifi network.
907
908 This expects the device to be already connected to the provided network.
909
910 Logic steps are
911 1. Ensure that we're connected to the network.
912 2. Turn wifi off.
913 3. Wait for 10 seconds.
914 4. Turn wifi on.
915 5. Wait for the "connected" event, then confirm the connected ssid is the
916 one requested.
917
918 This will directly fail a test if anything goes wrong.
919
920 Args:
921 ad: android_device object to initiate connection on.
922 network: A dictionary representing the network to await connection. The
923 dictionary must have the key "SSID".
924 num_of_tries: An integer that is the number of times to try before
925 delaring failure. Default is 1.
926 """
Roshan Pius58916a32016-06-16 16:26:44 -0700927 expected_ssid = network[WifiEnums.SSID_KEY]
928 # First ensure that we're already connected to the provided network.
929 verify_con = {WifiEnums.SSID_KEY: expected_ssid}
930 verify_wifi_connection_info(ad, verify_con)
931 # Now toggle wifi state and wait for the connection event.
932 wifi_toggle_state(ad, False)
933 time.sleep(10)
934 wifi_toggle_state(ad, True)
935 ad.droid.wifiStartTrackingStateChange()
936 try:
937 connect_result = None
938 for i in range(num_of_tries):
939 try:
Bindu Mahadev4e710362016-11-17 16:17:11 -0800940 connect_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
Roshan Pius58916a32016-06-16 16:26:44 -0700941 30)
942 break
943 except Empty:
944 pass
945 asserts.assert_true(connect_result,
946 "Failed to connect to Wi-Fi network %s on %s" %
Girish Moturu40d7dc22016-11-02 12:14:56 -0700947 (network, ad.serial))
Betty Zhou3caa0982017-02-22 19:26:20 -0800948 logging.debug("Connection result on %s: %s.", ad.serial,
949 connect_result)
Roshan Pius58916a32016-06-16 16:26:44 -0700950 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
951 asserts.assert_equal(actual_ssid, expected_ssid,
952 "Connected to the wrong network on %s."
953 "Expected %s, but got %s." %
Girish Moturu40d7dc22016-11-02 12:14:56 -0700954 (ad.serial, expected_ssid, actual_ssid))
Betty Zhou3caa0982017-02-22 19:26:20 -0800955 logging.info("Connected to Wi-Fi network %s on %s", actual_ssid,
956 ad.serial)
Roshan Pius58916a32016-06-16 16:26:44 -0700957 finally:
958 ad.droid.wifiStopTrackingStateChange()
959
960
Bindu Mahadevaf983c92017-03-27 12:00:37 -0700961def wait_for_connect(ad, ssid=None, id=None, tries=1):
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800962 """Wait for a connect event on queue and pop when available.
963
964 Args:
965 ad: An Android device object.
Bindu Mahadevaf983c92017-03-27 12:00:37 -0700966 ssid: SSID of the network to connect to.
967 id: Network Id of the network to connect to.
Bindu Mahadev3c54c492017-02-15 16:00:08 -0800968 tries: An integer that is the number of times to try before failing.
969
970 Returns:
971 A dict with details of the connection data, which looks like this:
972 {
973 'time': 1485460337798,
974 'name': 'WifiNetworkConnected',
975 'data': {
976 'rssi': -27,
977 'is_24ghz': True,
978 'mac_address': '02:00:00:00:00:00',
979 'network_id': 1,
980 'BSSID': '30:b5:c2:33:d3:fc',
981 'ip_address': 117483712,
982 'link_speed': 54,
983 'supplicant_state': 'completed',
984 'hidden_ssid': False,
985 'SSID': 'wh_ap1_2g',
986 'is_5ghz': False}
987 }
988
989 """
Bindu Mahadevd4542a82017-04-05 09:50:17 -0700990 conn_result = None
Bindu Mahadevaf983c92017-03-27 12:00:37 -0700991
Bindu Mahadevd4542a82017-04-05 09:50:17 -0700992 # If ssid and network id is None, just wait for any connect event.
Bindu Mahadevaf983c92017-03-27 12:00:37 -0700993 if id is None and ssid is None:
Bindu Mahadevd4542a82017-04-05 09:50:17 -0700994 for i in range(tries):
995 try:
996 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED, 30)
Bindu Mahadevaf983c92017-03-27 12:00:37 -0700997 break
Bindu Mahadevd4542a82017-04-05 09:50:17 -0700998 except Empty:
999 pass
1000 else:
1001 # If ssid or network id is specified, wait for specific connect event.
1002 for i in range(tries):
1003 try:
1004 conn_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED, 30)
1005 if id and conn_result['data'][WifiEnums.NETID_KEY] == id:
1006 break
1007 elif ssid and conn_result['data'][WifiEnums.SSID_KEY] == ssid:
1008 break
1009 except Empty:
1010 pass
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001011
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001012 return conn_result
1013
1014
1015def wait_for_disconnect(ad):
1016 """Wait for a Disconnect event from the supplicant.
1017
1018 Args:
1019 ad: Android device object.
1020
1021 """
1022 try:
1023 ad.droid.wifiStartTrackingStateChange()
1024 event = ad.ed.pop_event("WifiNetworkDisconnected", 10)
1025 ad.droid.wifiStopTrackingStateChange()
Roshan Piusbf7e3982018-02-15 12:37:41 -08001026 except Empty:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001027 raise signals.TestFailure("Device did not disconnect from the network")
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001028
1029
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001030def connect_to_wifi_network(ad, network):
1031 """Connection logic for open and psk wifi networks.
1032
1033 Args:
1034 params: A tuple of network info and AndroidDevice object.
1035 """
Roshan Piuse89ffd42018-01-25 07:17:48 -08001036 start_wifi_connection_scan_and_ensure_network_found(
1037 ad, network[WifiEnums.SSID_KEY])
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001038 wifi_connect(ad, network, num_of_tries=3)
1039
1040
1041def connect_to_wifi_network_with_id(ad, network_id, network_ssid):
1042 """Connect to the given network using network id and verify SSID.
1043
1044 Args:
1045 network_id: int Network Id of the network.
1046 network_ssid: string SSID of the network.
1047
1048 Returns: True if connect using network id was successful;
1049 False otherwise.
1050
1051 """
Roshan Piuse89ffd42018-01-25 07:17:48 -08001052 start_wifi_connection_scan_and_ensure_network_found(
1053 ad, network[WifiEnums.SSID_KEY])
Bindu Mahadev3876ae52017-12-19 14:22:19 -08001054 wifi_connect_by_id(ad, network_id)
1055 connect_data = ad.droid.wifiGetConnectionInfo()
1056 connect_ssid = connect_data[WifiEnums.SSID_KEY]
1057 ad.log.debug("Expected SSID = %s Connected SSID = %s" %
1058 (network_ssid, connect_ssid))
1059 if connect_ssid != network_ssid:
1060 return False
1061 return True
1062
1063
Ang Li82522812016-06-02 13:57:21 -07001064def wifi_connect(ad, network, num_of_tries=1, assert_on_fail=True):
Ang Li99d8c6d2015-12-09 15:56:13 -08001065 """Connect an Android device to a wifi network.
Ang Li73697b32015-12-03 00:41:53 +00001066
1067 Initiate connection to a wifi network, wait for the "connected" event, then
Ang Li99d8c6d2015-12-09 15:56:13 -08001068 confirm the connected ssid is the one requested.
Ang Li73697b32015-12-03 00:41:53 +00001069
Ang Li82522812016-06-02 13:57:21 -07001070 This will directly fail a test if anything goes wrong.
1071
Ang Li73697b32015-12-03 00:41:53 +00001072 Args:
1073 ad: android_device object to initiate connection on.
Ang Li99d8c6d2015-12-09 15:56:13 -08001074 network: A dictionary representing the network to connect to. The
Ang Li82522812016-06-02 13:57:21 -07001075 dictionary must have the key "SSID".
1076 num_of_tries: An integer that is the number of times to try before
1077 delaring failure. Default is 1.
1078 assert_on_fail: If True, error checks in this function will raise test
1079 failure signals.
1080
1081 Returns:
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001082 Returns a value only if assert_on_fail is false.
1083 Returns True if the connection was successful, False otherwise.
Ang Li73697b32015-12-03 00:41:53 +00001084 """
Betty Zhou3caa0982017-02-22 19:26:20 -08001085 return _assert_on_fail_handler(
1086 _wifi_connect, assert_on_fail, ad, network, num_of_tries=num_of_tries)
Ang Li82522812016-06-02 13:57:21 -07001087
1088
1089def _wifi_connect(ad, network, num_of_tries=1):
1090 """Connect an Android device to a wifi network.
1091
1092 Initiate connection to a wifi network, wait for the "connected" event, then
1093 confirm the connected ssid is the one requested.
1094
1095 This will directly fail a test if anything goes wrong.
1096
1097 Args:
1098 ad: android_device object to initiate connection on.
1099 network: A dictionary representing the network to connect to. The
1100 dictionary must have the key "SSID".
1101 num_of_tries: An integer that is the number of times to try before
1102 delaring failure. Default is 1.
1103 """
Ang Li82522812016-06-02 13:57:21 -07001104 asserts.assert_true(WifiEnums.SSID_KEY in network,
1105 "Key '%s' must be present in network definition." %
1106 WifiEnums.SSID_KEY)
Ang Li99d8c6d2015-12-09 15:56:13 -08001107 ad.droid.wifiStartTrackingStateChange()
Betty Zhoud35dab82016-12-06 15:24:23 -08001108 expected_ssid = network[WifiEnums.SSID_KEY]
Bindu Mahadev50374df2017-01-04 11:03:32 -08001109 ad.droid.wifiConnectByConfig(network)
1110 ad.log.info("Starting connection process to %s", expected_ssid)
Ang Li73697b32015-12-03 00:41:53 +00001111 try:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001112 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_CONFIG_SUCCESS, 30)
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001113 connect_result = wait_for_connect(ad, ssid=expected_ssid, tries=num_of_tries)
Ang Li82522812016-06-02 13:57:21 -07001114 asserts.assert_true(connect_result,
1115 "Failed to connect to Wi-Fi network %s on %s" %
Girish Moturubc48d9f2016-11-01 13:24:14 -07001116 (network, ad.serial))
Ang Li31b00782016-06-21 13:04:23 -07001117 ad.log.debug("Wi-Fi connection result: %s.", connect_result)
Ang Li99d8c6d2015-12-09 15:56:13 -08001118 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
Ang Li82522812016-06-02 13:57:21 -07001119 asserts.assert_equal(actual_ssid, expected_ssid,
Betty Zhou3caa0982017-02-22 19:26:20 -08001120 "Connected to the wrong network on %s." %
1121 ad.serial)
Ang Li31b00782016-06-21 13:04:23 -07001122 ad.log.info("Connected to Wi-Fi network %s.", actual_ssid)
Bindu Mahadev50374df2017-01-04 11:03:32 -08001123
1124 # Wait for data connection to stabilize.
1125 time.sleep(5)
1126
1127 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1128 if not internet:
1129 raise signals.TestFailure("Failed to connect to internet on %s" %
1130 expected_ssid)
1131 except Empty:
1132 asserts.fail("Failed to start connection process to %s on %s" %
1133 (network, ad.serial))
Bindu Mahadev4e710362016-11-17 16:17:11 -08001134 except Exception as error:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001135 ad.log.error("Failed to connect to %s with error %s", expected_ssid,
1136 error)
1137 raise signals.TestFailure("Failed to connect to %s network" % network)
1138
Ang Li73697b32015-12-03 00:41:53 +00001139 finally:
Ang Li99d8c6d2015-12-09 15:56:13 -08001140 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001141
Bindu Mahadev50374df2017-01-04 11:03:32 -08001142
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001143def wifi_connect_by_id(ad, network_id, num_of_tries=3, assert_on_fail=True):
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001144 """Connect an Android device to a wifi network using network Id.
1145
1146 Start connection to the wifi network, with the given network Id, wait for
1147 the "connected" event, then verify the connected network is the one requested.
1148
1149 This will directly fail a test if anything goes wrong.
1150
1151 Args:
1152 ad: android_device object to initiate connection on.
1153 network_id: Integer specifying the network id of the network.
1154 num_of_tries: An integer that is the number of times to try before
1155 delaring failure. Default is 1.
1156 assert_on_fail: If True, error checks in this function will raise test
1157 failure signals.
1158
1159 Returns:
1160 Returns a value only if assert_on_fail is false.
1161 Returns True if the connection was successful, False otherwise.
1162 """
1163 _assert_on_fail_handler(_wifi_connect_by_id, assert_on_fail, ad,
1164 network_id, num_of_tries)
1165
1166
1167def _wifi_connect_by_id(ad, network_id, num_of_tries=1):
1168 """Connect an Android device to a wifi network using it's network id.
1169
1170 Start connection to the wifi network, with the given network id, wait for
1171 the "connected" event, then verify the connected network is the one requested.
1172
1173 Args:
1174 ad: android_device object to initiate connection on.
1175 network_id: Integer specifying the network id of the network.
1176 num_of_tries: An integer that is the number of times to try before
1177 delaring failure. Default is 1.
1178 """
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001179 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001180 # Clear all previous events.
1181 ad.ed.clear_all_events()
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001182 ad.droid.wifiConnectByNetworkId(network_id)
1183 ad.log.info("Starting connection to network with id %d", network_id)
1184 try:
1185 event = ad.ed.pop_event(wifi_constants.CONNECT_BY_NETID_SUCCESS, 60)
Bindu Mahadevaf983c92017-03-27 12:00:37 -07001186 connect_result = wait_for_connect(ad, id=network_id, tries=num_of_tries)
Bindu Mahadev3c54c492017-02-15 16:00:08 -08001187 asserts.assert_true(connect_result,
1188 "Failed to connect to Wi-Fi network using network id")
1189 ad.log.debug("Wi-Fi connection result: %s", connect_result)
1190 actual_id = connect_result['data'][WifiEnums.NETID_KEY]
1191 asserts.assert_equal(actual_id, network_id,
1192 "Connected to the wrong network on %s."
1193 "Expected network id = %d, but got %d." %
1194 (ad.serial, network_id, actual_id))
1195 expected_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1196 ad.log.info("Connected to Wi-Fi network %s with %d network id.",
1197 expected_ssid, network_id)
1198
1199 # Wait for data connection to stabilize.
1200 time.sleep(5)
1201
1202 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1203 if not internet:
1204 raise signals.TestFailure("Failed to connect to internet on %s" %
1205 expected_ssid)
1206 except Empty:
1207 asserts.fail("Failed to connect to network with id %d on %s" %
1208 (network_id, ad.serial))
1209 except Exception as error:
1210 ad.log.error("Failed to connect to network with id %d with error %s",
1211 network_id, error)
1212 raise signals.TestFailure("Failed to connect to network with network"
1213 " id %d" % network_id)
1214 finally:
1215 ad.droid.wifiStopTrackingStateChange()
1216
1217
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001218def wifi_passpoint_connect(ad, passpoint_network, num_of_tries=1,
1219 assert_on_fail=True):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001220 """Connect an Android device to a wifi network.
1221
1222 Initiate connection to a wifi network, wait for the "connected" event, then
1223 confirm the connected ssid is the one requested.
1224
1225 This will directly fail a test if anything goes wrong.
1226
1227 Args:
1228 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001229 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001230 num_of_tries: An integer that is the number of times to try before
1231 delaring failure. Default is 1.
1232 assert_on_fail: If True, error checks in this function will raise test
1233 failure signals.
1234
1235 Returns:
1236 If assert_on_fail is False, function returns network id, if the connect was
1237 successful, False otherwise. If assert_on_fail is True, no return value.
1238 """
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001239 _assert_on_fail_handler(_wifi_passpoint_connect, assert_on_fail, ad,
1240 passpoint_network, num_of_tries = num_of_tries)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001241
1242
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001243def _wifi_passpoint_connect(ad, passpoint_network, num_of_tries=1):
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001244 """Connect an Android device to a wifi network.
1245
1246 Initiate connection to a wifi network, wait for the "connected" event, then
1247 confirm the connected ssid is the one requested.
1248
1249 This will directly fail a test if anything goes wrong.
1250
1251 Args:
1252 ad: android_device object to initiate connection on.
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001253 passpoint_network: SSID of the Passpoint network to connect to.
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001254 num_of_tries: An integer that is the number of times to try before
1255 delaring failure. Default is 1.
1256 """
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001257 ad.droid.wifiStartTrackingStateChange()
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001258 expected_ssid = passpoint_network
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001259 ad.log.info("Starting connection process to passpoint %s", expected_ssid)
1260
1261 try:
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001262 connect_result = wait_for_connect(ad, expected_ssid, num_of_tries)
Bindu Mahadev9dd48172017-03-06 17:04:34 -08001263 asserts.assert_true(connect_result,
1264 "Failed to connect to WiFi passpoint network %s on"
1265 " %s" % (expected_ssid, ad.serial))
1266 ad.log.info("Wi-Fi connection result: %s.", connect_result)
1267 actual_ssid = connect_result['data'][WifiEnums.SSID_KEY]
1268 asserts.assert_equal(actual_ssid, expected_ssid,
1269 "Connected to the wrong network on %s." % ad.serial)
1270 ad.log.info("Connected to Wi-Fi passpoint network %s.", actual_ssid)
1271
1272 # Wait for data connection to stabilize.
1273 time.sleep(5)
1274
1275 internet = validate_connection(ad, DEFAULT_PING_ADDR)
1276 if not internet:
1277 raise signals.TestFailure("Failed to connect to internet on %s" %
1278 expected_ssid)
1279 except Exception as error:
1280 ad.log.error("Failed to connect to passpoint network %s with error %s",
1281 expected_ssid, error)
1282 raise signals.TestFailure("Failed to connect to %s passpoint network" %
1283 expected_ssid)
1284
1285 finally:
1286 ad.droid.wifiStopTrackingStateChange()
1287
1288
Bindu Mahadevd4542a82017-04-05 09:50:17 -07001289def delete_passpoint(ad, fqdn):
1290 """Delete a required Passpoint configuration."""
1291 try:
1292 ad.droid.removePasspointConfig(fqdn)
1293 return True
1294 except Exception as error:
1295 ad.log.error("Failed to remove passpoint configuration with FQDN=%s "
1296 "and error=%s" , fqdn, error)
1297 return False
1298
1299
Ang Li73697b32015-12-03 00:41:53 +00001300def start_wifi_single_scan(ad, scan_setting):
1301 """Starts wifi single shot scan.
1302
1303 Args:
1304 ad: android_device object to initiate connection on.
1305 scan_setting: A dict representing the settings of the scan.
1306
1307 Returns:
1308 If scan was started successfully, event data of success event is returned.
1309 """
Ang Li82522812016-06-02 13:57:21 -07001310 idx = ad.droid.wifiScannerStartScan(scan_setting)
1311 event = ad.ed.pop_event("WifiScannerScan%sonSuccess" % idx, SHORT_TIMEOUT)
Ang Li31b00782016-06-21 13:04:23 -07001312 ad.log.debug("Got event %s", event)
Ang Li73697b32015-12-03 00:41:53 +00001313 return event['data']
1314
Ang Li82522812016-06-02 13:57:21 -07001315
Ang Li73697b32015-12-03 00:41:53 +00001316def track_connection(ad, network_ssid, check_connection_count):
1317 """Track wifi connection to network changes for given number of counts
1318
1319 Args:
1320 ad: android_device object for forget network.
1321 network_ssid: network ssid to which connection would be tracked
1322 check_connection_count: Integer for maximum number network connection
Ang Li82522812016-06-02 13:57:21 -07001323 check.
Ang Li73697b32015-12-03 00:41:53 +00001324 Returns:
Ang Li73697b32015-12-03 00:41:53 +00001325 True if connection to given network happen, else return False.
1326 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001327 ad.droid.wifiStartTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001328 while check_connection_count > 0:
Girish Moturu40d7dc22016-11-02 12:14:56 -07001329 connect_network = ad.ed.pop_event("WifiNetworkConnected", 120)
Ang Li31b00782016-06-21 13:04:23 -07001330 ad.log.info("Connected to network %s", connect_network)
Ang Li82522812016-06-02 13:57:21 -07001331 if (WifiEnums.SSID_KEY in connect_network['data'] and
1332 connect_network['data'][WifiEnums.SSID_KEY] == network_ssid):
1333 return True
Ang Li8e767182015-12-09 17:29:24 -08001334 check_connection_count -= 1
Girish Moturu40d7dc22016-11-02 12:14:56 -07001335 ad.droid.wifiStopTrackingStateChange()
Ang Li73697b32015-12-03 00:41:53 +00001336 return False
1337
Ang Li82522812016-06-02 13:57:21 -07001338
Ang Li73697b32015-12-03 00:41:53 +00001339def get_scan_time_and_channels(wifi_chs, scan_setting, stime_channel):
1340 """Calculate the scan time required based on the band or channels in scan
1341 setting
1342
1343 Args:
1344 wifi_chs: Object of channels supported
1345 scan_setting: scan setting used for start scan
1346 stime_channel: scan time per channel
1347
1348 Returns:
1349 scan_time: time required for completing a scan
1350 scan_channels: channel used for scanning
1351 """
1352 scan_time = 0
1353 scan_channels = []
1354 if "band" in scan_setting and "channels" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001355 scan_channels = wifi_chs.band_to_freq(scan_setting["band"])
Ang Li73697b32015-12-03 00:41:53 +00001356 elif "channels" in scan_setting and "band" not in scan_setting:
Ang Li8e767182015-12-09 17:29:24 -08001357 scan_channels = scan_setting["channels"]
Ang Li73697b32015-12-03 00:41:53 +00001358 scan_time = len(scan_channels) * stime_channel
1359 for channel in scan_channels:
Ang Li8e767182015-12-09 17:29:24 -08001360 if channel in WifiEnums.DFS_5G_FREQUENCIES:
Ang Li82522812016-06-02 13:57:21 -07001361 scan_time += 132 #passive scan time on DFS
Ang Li73697b32015-12-03 00:41:53 +00001362 return scan_time, scan_channels
1363
Ang Li82522812016-06-02 13:57:21 -07001364
Ang Li73697b32015-12-03 00:41:53 +00001365def start_wifi_track_bssid(ad, track_setting):
1366 """Start tracking Bssid for the given settings.
1367
1368 Args:
1369 ad: android_device object.
1370 track_setting: Setting for which the bssid tracking should be started
1371
1372 Returns:
1373 If tracking started successfully, event data of success event is returned.
1374 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001375 idx = ad.droid.wifiScannerStartTrackingBssids(
Ang Li82522812016-06-02 13:57:21 -07001376 track_setting["bssidInfos"], track_setting["apLostThreshold"])
Girish Moturu40d7dc22016-11-02 12:14:56 -07001377 event = ad.ed.pop_event("WifiScannerBssid{}onSuccess".format(idx),
Betty Zhou3caa0982017-02-22 19:26:20 -08001378 SHORT_TIMEOUT)
Ang Li73697b32015-12-03 00:41:53 +00001379 return event['data']
1380
Ang Li82522812016-06-02 13:57:21 -07001381
Ang Li73697b32015-12-03 00:41:53 +00001382def convert_pem_key_to_pkcs8(in_file, out_file):
1383 """Converts the key file generated by us to the format required by
1384 Android using openssl.
1385
1386 The input file must have the extension "pem". The output file must
1387 have the extension "der".
1388
1389 Args:
1390 in_file: The original key file.
1391 out_file: The full path to the converted key file, including
1392 filename.
1393 """
Ang Li82522812016-06-02 13:57:21 -07001394 asserts.assert_true(in_file.endswith(".pem"), "Input file has to be .pem.")
1395 asserts.assert_true(
1396 out_file.endswith(".der"), "Output file has to be .der.")
Ang Li73697b32015-12-03 00:41:53 +00001397 cmd = ("openssl pkcs8 -inform PEM -in {} -outform DER -out {} -nocrypt"
1398 " -topk8").format(in_file, out_file)
Ang Lifee28402016-07-13 13:43:29 -07001399 utils.exe_cmd(cmd)
Ang Li73697b32015-12-03 00:41:53 +00001400
Ang Li82522812016-06-02 13:57:21 -07001401
Girish Moturu7f287522017-09-25 13:33:06 -07001402def validate_connection(ad, ping_addr=DEFAULT_PING_ADDR):
Ang Li73697b32015-12-03 00:41:53 +00001403 """Validate internet connection by pinging the address provided.
1404
1405 Args:
1406 ad: android_device object.
1407 ping_addr: address on internet for pinging.
1408
1409 Returns:
Bindu Mahadev50374df2017-01-04 11:03:32 -08001410 ping output if successful, NULL otherwise.
Ang Li73697b32015-12-03 00:41:53 +00001411 """
Girish Moturu40d7dc22016-11-02 12:14:56 -07001412 ping = ad.droid.httpPing(ping_addr)
Ang Li31b00782016-06-21 13:04:23 -07001413 ad.log.info("Http ping result: %s.", ping)
Ang Li73697b32015-12-03 00:41:53 +00001414 return ping
1415
Ang Li82522812016-06-02 13:57:21 -07001416
Ang Li73697b32015-12-03 00:41:53 +00001417#TODO(angli): This can only verify if an actual value is exactly the same.
1418# Would be nice to be able to verify an actual value is one of serveral.
1419def verify_wifi_connection_info(ad, expected_con):
1420 """Verifies that the information of the currently connected wifi network is
1421 as expected.
1422
1423 Args:
1424 expected_con: A dict representing expected key-value pairs for wifi
1425 connection. e.g. {"SSID": "test_wifi"}
1426 """
1427 current_con = ad.droid.wifiGetConnectionInfo()
Ang Li374d7602016-02-08 17:27:27 -08001428 case_insensitive = ["BSSID", "supplicant_state"]
Ang Li31b00782016-06-21 13:04:23 -07001429 ad.log.debug("Current connection: %s", current_con)
Ang Li73697b32015-12-03 00:41:53 +00001430 for k, expected_v in expected_con.items():
Ang Li9a66de72016-02-08 15:26:38 -08001431 # Do not verify authentication related fields.
1432 if k == "password":
1433 continue
Ang Li82522812016-06-02 13:57:21 -07001434 msg = "Field %s does not exist in wifi connection info %s." % (
1435 k, current_con)
Ang Li374d7602016-02-08 17:27:27 -08001436 if k not in current_con:
1437 raise signals.TestFailure(msg)
1438 actual_v = current_con[k]
1439 if k in case_insensitive:
1440 actual_v = actual_v.lower()
1441 expected_v = expected_v.lower()
Ang Li73697b32015-12-03 00:41:53 +00001442 msg = "Expected %s to be %s, actual %s is %s." % (k, expected_v, k,
Ang Li82522812016-06-02 13:57:21 -07001443 actual_v)
Ang Li374d7602016-02-08 17:27:27 -08001444 if actual_v != expected_v:
1445 raise signals.TestFailure(msg)
Ang Li73697b32015-12-03 00:41:53 +00001446
Ang Li82522812016-06-02 13:57:21 -07001447
Ang Li73697b32015-12-03 00:41:53 +00001448def expand_enterprise_config_by_phase2(config):
1449 """Take an enterprise config and generate a list of configs, each with
1450 a different phase2 auth type.
1451
1452 Args:
1453 config: A dict representing enterprise config.
1454
1455 Returns
1456 A list of enterprise configs.
1457 """
1458 results = []
Ang Li0e7e58f2016-02-22 12:15:02 -08001459 phase2_types = WifiEnums.EapPhase2
1460 if config[WifiEnums.Enterprise.EAP] == WifiEnums.Eap.PEAP:
1461 # Skip unsupported phase2 types for PEAP.
1462 phase2_types = [WifiEnums.EapPhase2.GTC, WifiEnums.EapPhase2.MSCHAPV2]
1463 for phase2_type in phase2_types:
Ang Li73697b32015-12-03 00:41:53 +00001464 # Skip a special case for passpoint TTLS.
1465 if (WifiEnums.Enterprise.FQDN in config and
Ang Li82522812016-06-02 13:57:21 -07001466 phase2_type == WifiEnums.EapPhase2.GTC):
Ang Li73697b32015-12-03 00:41:53 +00001467 continue
1468 c = dict(config)
Girish Moturu150d32f2017-02-14 12:27:07 -08001469 c[WifiEnums.Enterprise.PHASE2] = phase2_type.value
Ang Li73697b32015-12-03 00:41:53 +00001470 results.append(c)
1471 return results
Ang Li2d3fe982016-06-08 10:00:43 -07001472
1473
Girish Moturub48a13c2017-02-27 11:36:42 -08001474def generate_eap_test_name(config, ad=None):
Girish Moturu150d32f2017-02-14 12:27:07 -08001475 """ Generates a test case name based on an EAP configuration.
1476
1477 Args:
1478 config: A dict representing an EAP credential.
Girish Moturub48a13c2017-02-27 11:36:42 -08001479 ad object: Redundant but required as the same param is passed
1480 to test_func in run_generated_tests
Girish Moturu150d32f2017-02-14 12:27:07 -08001481
1482 Returns:
1483 A string representing the name of a generated EAP test case.
1484 """
1485 eap = WifiEnums.Eap
1486 eap_phase2 = WifiEnums.EapPhase2
Girish Moturub48a13c2017-02-27 11:36:42 -08001487 Ent = WifiEnums.Enterprise
Girish Moturu150d32f2017-02-14 12:27:07 -08001488 name = "test_connect-"
1489 eap_name = ""
1490 for e in eap:
1491 if e.value == config[Ent.EAP]:
1492 eap_name = e.name
1493 break
1494 if "peap0" in config[WifiEnums.SSID_KEY].lower():
1495 eap_name = "PEAP0"
1496 if "peap1" in config[WifiEnums.SSID_KEY].lower():
1497 eap_name = "PEAP1"
1498 name += eap_name
1499 if Ent.PHASE2 in config:
1500 for e in eap_phase2:
1501 if e.value == config[Ent.PHASE2]:
1502 name += "-{}".format(e.name)
1503 break
1504 return name
1505
1506
Ang Li2d3fe982016-06-08 10:00:43 -07001507def group_attenuators(attenuators):
1508 """Groups a list of attenuators into attenuator groups for backward
1509 compatibility reasons.
1510
1511 Most legacy Wi-Fi setups have two attenuators each connected to a separate
1512 AP. The new Wi-Fi setup has four attenuators, each connected to one channel
1513 on an AP, so two of them are connected to one AP.
1514
1515 To make the existing scripts work in the new setup, when the script needs
1516 to attenuate one AP, it needs to set attenuation on both attenuators
1517 connected to the same AP.
1518
1519 This function groups attenuators properly so the scripts work in both
1520 legacy and new Wi-Fi setups.
1521
1522 Args:
1523 attenuators: A list of attenuator objects, either two or four in length.
1524
1525 Raises:
1526 signals.TestFailure is raised if the attenuator list does not have two
1527 or four objects.
1528 """
1529 attn0 = attenuator.AttenuatorGroup("AP0")
1530 attn1 = attenuator.AttenuatorGroup("AP1")
1531 # Legacy testbed setup has two attenuation channels.
1532 num_of_attns = len(attenuators)
1533 if num_of_attns == 2:
1534 attn0.add(attenuators[0])
1535 attn1.add(attenuators[1])
1536 elif num_of_attns == 4:
1537 attn0.add(attenuators[0])
1538 attn0.add(attenuators[1])
1539 attn1.add(attenuators[2])
1540 attn1.add(attenuators[3])
1541 else:
1542 asserts.fail(("Either two or four attenuators are required for this "
1543 "test, but found %s") % num_of_attns)
1544 return [attn0, attn1]