1e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu/* 2e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * Copyright (C) 2016 The Android Open Source Project 3e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * 4e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * Licensed under the Apache License, Version 2.0 (the "License"); 5e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * you may not use this file except in compliance with the License. 6e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * You may obtain a copy of the License at 7e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * 8e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * http://www.apache.org/licenses/LICENSE-2.0 9e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * 10e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * Unless required by applicable law or agreed to in writing, software 11e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * distributed under the License is distributed on an "AS IS" BASIS, 12e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * See the License for the specific language governing permissions and 14e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * limitations under the License. 15e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu */ 16e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu 17e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiupackage com.android.server.wifi.util; 18e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu 19e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport android.net.wifi.WifiConfiguration; 20e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport android.net.wifi.WifiScanner; 21e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport android.util.Log; 22e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu 23e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport com.android.server.wifi.WifiNative; 24e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu 25e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport java.util.ArrayList; 26e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiuimport java.util.Random; 27e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu 28e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu/** 29e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * Provide utility functions for updating soft AP related configuration. 30e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu */ 31e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiupublic class ApConfigUtil { 32e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu private static final String TAG = "ApConfigUtil"; 33e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu 34e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu public static final int DEFAULT_AP_BAND = WifiConfiguration.AP_BAND_2GHZ; 35e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu public static final int DEFAULT_AP_CHANNEL = 6; 36e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu 37e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu /* Return code for updateConfiguration. */ 38e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu public static final int SUCCESS = 0; 39e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu public static final int ERROR_NO_CHANNEL = 1; 40e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu public static final int ERROR_GENERIC = 2; 41e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu 42e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu /* Random number generator used for AP channel selection. */ 43e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu private static final Random sRandom = new Random(); 44e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu 45e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu /** 46e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * Convert frequency to channel. 47e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * @param frequency frequency to convert 48e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * @return channel number associated with given frequency, -1 if no match 49e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu */ 50e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu public static int convertFrequencyToChannel(int frequency) { 51e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu if (frequency >= 2412 && frequency <= 2472) { 52e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu return (frequency - 2412) / 5 + 1; 53e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu } else if (frequency == 2484) { 54e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu return 14; 55e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu } else if (frequency >= 5170 && frequency <= 5825) { 56e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu /* DFS is included. */ 57e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu return (frequency - 5170) / 5 + 34; 58e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu } 59e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu 60e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu return -1; 61e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu } 62e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu 63e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu /** 64e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * Return a channel number for AP setup based on the frequency band. 65e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * @param apBand 0 for 2GHz, 1 for 5GHz 66e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * @param allowed2GChannels list of allowed 2GHz channels 67e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * @param allowed5GFreqList list of allowed 5GHz frequencies 68e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * @return a valid channel number on success, -1 on failure. 69e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu */ 70e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu public static int chooseApChannel(int apBand, 71e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu ArrayList<Integer> allowed2GChannels, 72e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu int[] allowed5GFreqList) { 73e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu if (apBand != WifiConfiguration.AP_BAND_2GHZ 74e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu && apBand != WifiConfiguration.AP_BAND_5GHZ) { 75e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu Log.e(TAG, "Invalid band: " + apBand); 76e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu return -1; 77e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu } 78e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu 79e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu if (apBand == WifiConfiguration.AP_BAND_2GHZ) { 80e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu /* Select a channel from 2GHz band. */ 81e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu if (allowed2GChannels == null || allowed2GChannels.size() == 0) { 82e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu Log.d(TAG, "2GHz allowed channel list not specified"); 83e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu /* Use default channel. */ 84e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu return DEFAULT_AP_CHANNEL; 85e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu } 86e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu 87e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu /* Pick a random channel. */ 88e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu int index = sRandom.nextInt(allowed2GChannels.size()); 89e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu return allowed2GChannels.get(index).intValue(); 90e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu } 91e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu 92e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu /* 5G without DFS. */ 93e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu if (allowed5GFreqList != null && allowed5GFreqList.length > 0) { 94e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu /* Pick a random channel from the list of supported channels. */ 95e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu return convertFrequencyToChannel( 96e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu allowed5GFreqList[sRandom.nextInt(allowed5GFreqList.length)]); 97e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu } 98e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu 99e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu Log.e(TAG, "No available channels on 5GHz band"); 100e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu return -1; 101e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu } 102e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu 103e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu /** 104e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * Update AP band and channel based on the provided country code and band. 105e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * This will also set 106e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * @param wifiNative reference to WifiNative 107e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * @param countryCode country code 108e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * @param allowed2GChannels list of allowed 2GHz channels 109e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * @param config configuration to update 110e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu * @return an integer result code 111e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu */ 112e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu public static int updateApChannelConfig(WifiNative wifiNative, 113e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu String countryCode, 114e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu ArrayList<Integer> allowed2GChannels, 115e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu WifiConfiguration config) { 116e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu /* Use default band and channel for device without HAL. */ 117e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu if (!wifiNative.isHalStarted()) { 118e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu config.apBand = DEFAULT_AP_BAND; 119e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu config.apChannel = DEFAULT_AP_CHANNEL; 120e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu return SUCCESS; 121e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu } 122e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu 123e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu /* Country code is mandatory for 5GHz band. */ 124e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu if (config.apBand == WifiConfiguration.AP_BAND_5GHZ 125e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu && countryCode == null) { 126e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu Log.e(TAG, "5GHz band is not allowed without country code"); 127e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu return ERROR_GENERIC; 128e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu } 129e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu 130e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu /* Select a channel if it is not specified. */ 131e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu if (config.apChannel == 0) { 132e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu config.apChannel = chooseApChannel( 133e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu config.apBand, allowed2GChannels, 134e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu wifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ)); 135e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu if (config.apChannel == -1) { 136e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu if (wifiNative.isGetChannelsForBandSupported()) { 137e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu /* We're not able to get channel when it is supported by HAL. */ 138e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu Log.e(TAG, "Failed to get available channel."); 139e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu return ERROR_NO_CHANNEL; 140e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu } 141e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu 142e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu /* Use the default for HAL without get channel support. */ 143e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu config.apBand = DEFAULT_AP_BAND; 144e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu config.apChannel = DEFAULT_AP_CHANNEL; 145e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu } 146e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu } 147e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu 148e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu return SUCCESS; 149e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu } 150e5b93fbfe451bc57c07b3f72191b52b6bd237d5bPeter Qiu} 151