1#!/usr/bin/env python3 2# 3# Copyright 2019 - The Android Open Source Project 4# 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 17import csv 18import itertools 19import os 20import re 21import time 22 23from collections import OrderedDict 24from functools import partial 25 26import acts.base_test 27import acts.controllers.rohdeschwarz_lib.cmw500 as cmw500 28from acts_contrib.test_utils.coex.hotspot_utils import band_channel_map 29from acts_contrib.test_utils.coex.hotspot_utils import supported_lte_bands 30from acts_contrib.test_utils.coex.hotspot_utils import tdd_band_list 31from acts_contrib.test_utils.coex.hotspot_utils import wifi_channel_map 32from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode 33from acts_contrib.test_utils.wifi.wifi_test_utils import reset_wifi 34from acts_contrib.test_utils.wifi.wifi_test_utils import start_wifi_tethering 35from acts_contrib.test_utils.wifi.wifi_test_utils import stop_wifi_tethering 36from acts_contrib.test_utils.wifi.wifi_test_utils import wifi_connect 37from acts_contrib.test_utils.wifi.wifi_test_utils import WifiEnums 38 39BANDWIDTH_2G = 20 40CNSS_LOG_PATH = '/data/vendor/wifi/wlan_logs' 41CNSS_CMD = 'cnss_diag -f -s' 42 43 44class HotspotWiFiChannelTest(acts.base_test.BaseTestClass): 45 """Idea behind this test is to check which wifi channel gets picked with 46 different lte bands(low, mid and high frequencies) when connected via 47 hotspot from secondary device. As of now there is no failure condition 48 to check the channel picked for the particular lte band. 49 """ 50 def __init__(self, controllers): 51 super().__init__(controllers) 52 req_params = ['callbox_params', 'network', 'lte_bands', 'hotspot_mode'] 53 self.unpack_userparams(req_params) 54 self.tests = self.generate_test_cases() 55 56 def setup_class(self): 57 self.pri_ad = self.android_devices[0] 58 self.sec_ad = self.android_devices[1] 59 self.cmw = cmw500.Cmw500(self.callbox_params['host'], 60 self.callbox_params['port']) 61 # Get basestation object. 62 self.bts = self.cmw.get_base_station() 63 csv_header = ('Hotspot Mode', 'lte_band', 'LTE_dl_channel', 64 'LTE_ul_freq', 'LTE_dl_freq', 'wifi_channel', 65 'wifi_bandwidth') 66 self.write_data_to_csv(csv_header) 67 68 def setup_test(self): 69 self.pri_ad.adb.shell_nb(CNSS_CMD) 70 71 def teardown_test(self): 72 self.pri_ad.adb.shell('killall cnss_diag') 73 stop_wifi_tethering(self.pri_ad) 74 reset_wifi(self.sec_ad) 75 cnss_path = os.path.join(self.log_path, 'wlan_logs') 76 os.makedirs(cnss_path, exist_ok=True) 77 self.pri_ad.pull_files([CNSS_LOG_PATH], os.path.join( 78 cnss_path, self.current_test_name)) 79 self.pri_ad.adb.shell('rm -rf {}'.format(CNSS_LOG_PATH)) 80 81 def teardown_class(self): 82 self.cmw.disconnect() 83 84 def write_data_to_csv(self, data): 85 """Writes the data to csv file 86 87 Args: 88 data: data to be written into csv. 89 """ 90 with open('{}/test_data.csv'.format(self.log_path), 'a', 91 newline="") as cf: 92 csv_writer = csv.writer(cf, delimiter=',') 93 csv_writer.writerow(data) 94 cf.close() 95 96 def generate_test_cases(self): 97 # find and run only the supported bands. 98 lte_band = list(set(self.lte_bands).intersection(supported_lte_bands)) 99 100 if len(lte_band) == 0: 101 # if lte_band in config is empty run all bands. 102 lte_band = supported_lte_bands 103 104 test_cases = [] 105 for hmode, lband in itertools.product(self.hotspot_mode, lte_band): 106 for channel in band_channel_map.get(lband): 107 test_case_name = ('test_hotspot_lte_band_{}_channel_{}_wifi' 108 '_band_{}'.format(lband, channel, hmode)) 109 test_params = OrderedDict( 110 lte_band=lband, 111 LTE_dl_channel=channel, 112 hotspot_mode=hmode, 113 ) 114 setattr(self, test_case_name, partial(self.set_hotspot_params, 115 test_params)) 116 test_cases.append(test_case_name) 117 118 return test_cases 119 120 def set_hotspot_params(self, test_params): 121 """Set up hot spot parameters. 122 123 Args: 124 test_params: Contains band and frequency of current test. 125 """ 126 self.setup_lte_and_attach(test_params['lte_band'], 127 test_params['LTE_dl_channel']) 128 band = test_params['hotspot_mode'].lower() 129 self.initiate_wifi_tethering_and_connect(band) 130 test_params['LTE_ul_freq'] = self.bts.ul_frequency 131 test_params['LTE_dl_freq'] = self.bts.dl_frequency 132 test_params['wifi_channel'] = self.get_wifi_channel(self.sec_ad) 133 test_params['wifi_bandwidth'] = self.get_wifi_bandwidth(self.sec_ad) 134 data = (test_params['hotspot_mode'], test_params['lte_band'], 135 test_params['LTE_dl_channel'], test_params['LTE_ul_freq'], 136 test_params['LTE_dl_freq'], test_params['wifi_channel'], 137 test_params['wifi_bandwidth']) 138 139 self.write_data_to_csv(data) 140 141 def setup_lte_and_attach(self, band, channel): 142 """Setup callbox and attaches the device. 143 144 Args: 145 band: lte band to configure. 146 channel: channel to set for band. 147 """ 148 toggle_airplane_mode(self.log, self.pri_ad, True) 149 150 # Reset system 151 self.cmw.reset() 152 153 if band in tdd_band_list: 154 self.bts.duplex_mode = cmw500.DuplexMode.TDD 155 156 # Turn ON LTE signalling 157 self.cmw.switch_lte_signalling(cmw500.LteState.LTE_ON) 158 159 # Set Signalling params 160 self.cmw.enable_packet_switching() 161 self.bts.downlink_power_level = '-59.8' 162 163 self.bts.band = band 164 self.bts.bandwidth = cmw500.LteBandwidth.BANDWIDTH_5MHz 165 self.bts.dl_channel = channel 166 time.sleep(1) 167 self.log.info('Callbox settings: band: {}, bandwidth: {}, ' 168 'dl_channel: {}, '.format(self.bts.band, 169 self.bts.bandwidth, 170 self.bts.dl_channel 171 )) 172 173 toggle_airplane_mode(self.log, self.pri_ad, False) 174 self.log.info('Waiting for device to attach.') 175 self.cmw.wait_for_attached_state() 176 self.log.info('Device attached with callbox.') 177 self.log.debug('Waiting for connected state.') 178 self.cmw.wait_for_rrc_state(cmw500.LTE_CONN_RESP) 179 self.log.info('Device connected with callbox') 180 181 def initiate_wifi_tethering_and_connect(self, wifi_band=None): 182 """Initiates wifi tethering and connects wifi. 183 184 Args: 185 wifi_band: Hotspot mode to set. 186 """ 187 if wifi_band == '2g': 188 wband = WifiEnums.WIFI_CONFIG_APBAND_2G 189 elif wifi_band == '5g': 190 wutils.set_wifi_country_code(self.pri_ad, WifiEnums.CountryCode.US) 191 wutils.set_wifi_country_code(self.sec_ad, WifiEnums.CountryCode.US) 192 wband = WifiEnums.WIFI_CONFIG_APBAND_5G 193 elif wifi_band == 'auto': 194 wband = WifiEnums.WIFI_CONFIG_APBAND_AUTO 195 else: 196 raise ValueError('Invalid hotspot mode.') 197 198 start_wifi_tethering(self.pri_ad, self.network['SSID'], 199 self.network['password'], band=wband) 200 201 wifi_connect(self.sec_ad, self.network, check_connectivity=False) 202 203 def get_wifi_channel(self, ad): 204 """Get the Wifi Channel for the SSID connected. 205 206 Args: 207 ad: Android device to get channel. 208 209 Returns: 210 wifi_channel: WiFi channel of connected device, 211 212 Raises: 213 Value Error on Failure. 214 """ 215 out = ad.adb.shell('wpa_cli status') 216 match = re.search('freq=.*', out) 217 if match: 218 freq = match.group(0).split('=')[1] 219 wifi_channel = wifi_channel_map[int(freq)] 220 self.log.info('Channel Chosen: {}'.format(wifi_channel)) 221 return wifi_channel 222 else: 223 raise ValueError('Wifi connection inactive.') 224 225 def get_wifi_bandwidth(self, ad): 226 """Gets the Wifi Bandwidth for the SSID connected. 227 228 Args: 229 ad: Android device to get bandwidth. 230 231 Returns: 232 bandwidth: if connected wifi is 5GHz. 233 2G_BANDWIDTH: if connected wifi is 2GHz, 234 """ 235 out = ad.adb.shell('iw wlan0 link') 236 match = re.search(r'[0-9.]+MHz', out) 237 if match: 238 bandwidth = match.group(0).strip('MHz') 239 return bandwidth 240 else: 241 return BANDWIDTH_2G 242