ChannelHelper.java revision e6d8fa5fb50afdfc04922f7f87c2cac08db5bbec
1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.wifi.scanner; 18 19import android.net.wifi.WifiScanner; 20 21import com.android.server.wifi.WifiNative; 22 23import java.util.Set; 24 25/** 26 * ChannelHelper offers an abstraction for channel manipulation utilities allowing operation to be 27 * adjusted based on the amount of information known about the available channels. 28 */ 29public abstract class ChannelHelper { 30 31 // TODO: Currently this is simply an estimate and is used for both active and passive channels 32 // scans. Eventually it should be split between passive and active and perhaps retrieved 33 // from the driver. 34 /** 35 * The estimated period spent scanning each channel. This is used for estimating scan duration. 36 */ 37 public static final int SCAN_PERIOD_PER_CHANNEL_MS = 200; 38 39 protected static final WifiScanner.ChannelSpec[] NO_CHANNELS = new WifiScanner.ChannelSpec[0]; 40 41 /** 42 * Create a new collection that can be used to store channels 43 */ 44 public abstract ChannelCollection createChannelCollection(); 45 46 /** 47 * Return true if the specified channel is expected for a scan with the given settings 48 */ 49 public abstract boolean settingsContainChannel(WifiScanner.ScanSettings settings, int channel); 50 51 /** 52 * Get the channels that are available for scanning on the supplied band. 53 * This method may return empty if the information is not available. 54 */ 55 public abstract WifiScanner.ChannelSpec[] getAvailableScanChannels(int band); 56 57 /** 58 * Estimates the duration that the chip will spend scanning with the given settings 59 */ 60 public abstract int estimateScanDuration(WifiScanner.ScanSettings settings); 61 62 /** 63 * Update the channel information that this object has. The source of the update is 64 * implementation dependent and may result in no change. Warning the behavior of a 65 * ChannelCollection created using {@link #createChannelCollection createChannelCollection} is 66 * undefined after calling this method until the {@link ChannelColleciton#clear() clear} method 67 * is called on it. 68 */ 69 public void updateChannels() { 70 // default implementation does nothing 71 } 72 73 /** 74 * Object that supports accumulation of channels and bands 75 */ 76 public abstract class ChannelCollection { 77 /** 78 * Add a channel to the collection 79 */ 80 public abstract void addChannel(int channel); 81 /** 82 * Add all channels in the band to the collection 83 */ 84 public abstract void addBand(int band); 85 /** 86 * @return true if the collection contains the supplied channel 87 */ 88 public abstract boolean containsChannel(int channel); 89 /** 90 * @return true if the collection contains no channels 91 */ 92 public abstract boolean isEmpty(); 93 /** 94 * Remove all channels from the collection 95 */ 96 public abstract void clear(); 97 98 /** 99 * Add all channels in the ScanSetting to the collection 100 */ 101 public void addChannels(WifiScanner.ScanSettings scanSettings) { 102 if (scanSettings.band == WifiScanner.WIFI_BAND_UNSPECIFIED) { 103 for (int j = 0; j < scanSettings.channels.length; ++j) { 104 addChannel(scanSettings.channels[j].frequency); 105 } 106 } else { 107 addBand(scanSettings.band); 108 } 109 } 110 111 /** 112 * Add all channels in the BucketSettings to the collection 113 */ 114 public void addChannels(WifiNative.BucketSettings bucketSettings) { 115 if (bucketSettings.band == WifiScanner.WIFI_BAND_UNSPECIFIED) { 116 for (int j = 0; j < bucketSettings.channels.length; ++j) { 117 addChannel(bucketSettings.channels[j].frequency); 118 } 119 } else { 120 addBand(bucketSettings.band); 121 } 122 } 123 124 /** 125 * Store the channels in this collection in the supplied BucketSettings. If maxChannels is 126 * exceeded or a band better describes the channels then a band is specified instead of a 127 * channel list. 128 */ 129 public abstract void fillBucketSettings(WifiNative.BucketSettings bucket, int maxChannels); 130 131 /** 132 * Gets the list of channels that should be supplied to supplicant for a scan. Will either 133 * be a collection of all channels or null if all channels should be scanned. 134 */ 135 public abstract Set<Integer> getSupplicantScanFreqs(); 136 } 137 138 139 /* 140 * Utility methods for converting band/channels to strings 141 */ 142 143 /** 144 * Create a string representation of the channels in the ScanSettings. 145 * If it contains a list of channels then the channels are returned, otherwise a string name of 146 * the band is returned. 147 */ 148 public static String toString(WifiScanner.ScanSettings scanSettings) { 149 if (scanSettings.band == WifiScanner.WIFI_BAND_UNSPECIFIED) { 150 return toString(scanSettings.channels); 151 } else { 152 return toString(scanSettings.band); 153 } 154 } 155 156 /** 157 * Create a string representation of the channels in the BucketSettings. 158 * If it contains a list of channels then the channels are returned, otherwise a string name of 159 * the band is returned. 160 */ 161 public static String toString(WifiNative.BucketSettings bucketSettings) { 162 if (bucketSettings.band == WifiScanner.WIFI_BAND_UNSPECIFIED) { 163 return toString(bucketSettings.channels, bucketSettings.num_channels); 164 } else { 165 return toString(bucketSettings.band); 166 } 167 } 168 169 private static String toString(WifiScanner.ChannelSpec[] channels) { 170 if (channels == null) { 171 return "null"; 172 } 173 174 StringBuilder sb = new StringBuilder(); 175 sb.append("["); 176 for (int c = 0; c < channels.length; c++) { 177 sb.append(channels[c].frequency); 178 if (c != channels.length - 1) { 179 sb.append(","); 180 } 181 } 182 sb.append("]"); 183 return sb.toString(); 184 } 185 186 private static String toString(WifiNative.ChannelSettings[] channels, int numChannels) { 187 if (channels == null) { 188 return "null"; 189 } 190 191 StringBuilder sb = new StringBuilder(); 192 sb.append("["); 193 for (int c = 0; c < numChannels; c++) { 194 sb.append(channels[c].frequency); 195 if (c != numChannels - 1) { 196 sb.append(","); 197 } 198 } 199 sb.append("]"); 200 return sb.toString(); 201 } 202 203 private static String toString(int band) { 204 switch (band) { 205 case WifiScanner.WIFI_BAND_UNSPECIFIED: 206 return "unspecified"; 207 case WifiScanner.WIFI_BAND_24_GHZ: 208 return "24Ghz"; 209 case WifiScanner.WIFI_BAND_5_GHZ: 210 return "5Ghz (no DFS)"; 211 case WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY: 212 return "5Ghz (DFS only)"; 213 case WifiScanner.WIFI_BAND_5_GHZ_WITH_DFS: 214 return "5Ghz (DFS incl)"; 215 case WifiScanner.WIFI_BAND_BOTH: 216 return "24Ghz & 5Ghz (no DFS)"; 217 case WifiScanner.WIFI_BAND_BOTH_WITH_DFS: 218 return "24Ghz & 5Ghz (DFS incl)"; 219 } 220 221 return "invalid band"; 222 } 223} 224