KnownBandsChannelHelper.java revision 39175cc807488dd849e2c530f8be30dd674fbd9f
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; 20import android.util.ArraySet; 21 22import com.android.server.wifi.WifiNative; 23 24import java.util.Set; 25 26/** 27 * ChannelHelper that offers channel manipulation utilities when the channels in a band are known. 28 * This allows more fine operations on channels than if band channels are not known. 29 */ 30public class KnownBandsChannelHelper extends ChannelHelper { 31 32 private static final WifiScanner.ChannelSpec[] NO_CHANNELS = new WifiScanner.ChannelSpec[0]; 33 34 private WifiScanner.ChannelSpec[][] mBandsToChannels; 35 36 public KnownBandsChannelHelper(int[] channels2G, int[] channels5G, int[] channelsDfs) { 37 mBandsToChannels = new WifiScanner.ChannelSpec[8][]; 38 39 mBandsToChannels[0] = NO_CHANNELS; 40 41 mBandsToChannels[1] = new WifiScanner.ChannelSpec[channels2G.length]; 42 copyChannels(mBandsToChannels[1], 0, channels2G); 43 44 mBandsToChannels[2] = new WifiScanner.ChannelSpec[channels5G.length]; 45 copyChannels(mBandsToChannels[2], 0, channels5G); 46 47 mBandsToChannels[3] = new WifiScanner.ChannelSpec[channels2G.length + channels5G.length]; 48 copyChannels(mBandsToChannels[3], 0, channels2G); 49 copyChannels(mBandsToChannels[3], channels2G.length, channels5G); 50 51 mBandsToChannels[4] = new WifiScanner.ChannelSpec[channelsDfs.length]; 52 copyChannels(mBandsToChannels[4], 0, channelsDfs); 53 54 mBandsToChannels[5] = new WifiScanner.ChannelSpec[channels2G.length + channelsDfs.length]; 55 copyChannels(mBandsToChannels[5], 0, channels2G); 56 copyChannels(mBandsToChannels[5], channels2G.length, channelsDfs); 57 58 mBandsToChannels[6] = new WifiScanner.ChannelSpec[channels5G.length + channelsDfs.length]; 59 copyChannels(mBandsToChannels[6], 0, channels5G); 60 copyChannels(mBandsToChannels[6], channels5G.length, channelsDfs); 61 62 mBandsToChannels[7] = new WifiScanner.ChannelSpec[ 63 channels2G.length + channels5G.length + channelsDfs.length]; 64 copyChannels(mBandsToChannels[7], 0, channels2G); 65 copyChannels(mBandsToChannels[7], channels2G.length, channels5G); 66 copyChannels(mBandsToChannels[7], channels2G.length + channels5G.length, channelsDfs); 67 } 68 69 private static void copyChannels( 70 WifiScanner.ChannelSpec[] channelSpec, int offset, int[] channels) { 71 for (int i = 0; i < channels.length; i++) { 72 channelSpec[offset + i] = new WifiScanner.ChannelSpec(channels[i]); 73 } 74 } 75 76 private WifiScanner.ChannelSpec[] getChannelsForBand(int band) { 77 if (band < WifiScanner.WIFI_BAND_24_GHZ || band > WifiScanner.WIFI_BAND_BOTH_WITH_DFS) { 78 // invalid value for band 79 return NO_CHANNELS; 80 } else { 81 return mBandsToChannels[band]; 82 } 83 } 84 85 private boolean isDfsChannel(int frequency) { 86 for (WifiScanner.ChannelSpec dfsChannel : 87 mBandsToChannels[WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY]) { 88 if (frequency == dfsChannel.frequency) { 89 return true; 90 } 91 } 92 return false; 93 } 94 95 // TODO this should be rewritten to be based on the input data instead of hardcoded ranges 96 private int getBandFromChannel(int frequency) { 97 if (2400 <= frequency && frequency < 2500) { 98 return WifiScanner.WIFI_BAND_24_GHZ; 99 } else if (isDfsChannel(frequency)) { 100 return WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY; 101 } else if (5100 <= frequency && frequency < 6000) { 102 return WifiScanner.WIFI_BAND_5_GHZ; 103 } else { 104 return WifiScanner.WIFI_BAND_UNSPECIFIED; 105 } 106 } 107 108 @Override 109 public boolean settingsContainChannel(WifiScanner.ScanSettings settings, int channel) { 110 WifiScanner.ChannelSpec[] settingsChannels; 111 if (settings.band == WifiScanner.WIFI_BAND_UNSPECIFIED) { 112 settingsChannels = settings.channels; 113 } else { 114 settingsChannels = getChannelsForBand(settings.band); 115 } 116 for (int i = 0; i < settingsChannels.length; ++i) { 117 if (settingsChannels[i].frequency == channel) { 118 return true; 119 } 120 } 121 return false; 122 } 123 124 /** 125 * ChannelCollection that merges channels so that the optimal schedule will be generated. 126 * When the max channels value is satisfied this implementation will always create a channel 127 * list that includes no more than the added channels. 128 */ 129 public class KnownBandsChannelCollection extends ChannelCollection { 130 /** 131 * Stores all channels, including those that belong to added bands. 132 */ 133 private final ArraySet<Integer> mChannels = new ArraySet<Integer>(); 134 /** 135 * Contains only the bands that were explicitly added as bands. 136 */ 137 private int mExactBands = 0; 138 /** 139 * Contains all bands, including those that were added because an added channel was in that 140 * band. 141 */ 142 private int mAllBands = 0; 143 144 @Override 145 public void addChannel(int frequency) { 146 mChannels.add(frequency); 147 mAllBands |= getBandFromChannel(frequency); 148 } 149 150 @Override 151 public void addBand(int band) { 152 mExactBands |= band; 153 mAllBands |= band; 154 WifiScanner.ChannelSpec[] bandChannels = getChannelsForBand(band); 155 for (int i = 0; i < bandChannels.length; ++i) { 156 mChannels.add(bandChannels[i].frequency); 157 } 158 } 159 160 @Override 161 public boolean containsChannel(int channel) { 162 return mChannels.contains(channel); 163 } 164 165 @Override 166 public boolean isEmpty() { 167 return mChannels.isEmpty(); 168 } 169 170 @Override 171 public void clear() { 172 mAllBands = 0; 173 mExactBands = 0; 174 mChannels.clear(); 175 } 176 177 @Override 178 public void fillBucketSettings(WifiNative.BucketSettings bucketSettings, int maxChannels) { 179 if ((mChannels.size() > maxChannels || mAllBands == mExactBands) 180 && mAllBands != 0) { 181 bucketSettings.band = mAllBands; 182 bucketSettings.num_channels = 0; 183 bucketSettings.channels = null; 184 } else { 185 bucketSettings.band = WifiScanner.WIFI_BAND_UNSPECIFIED; 186 bucketSettings.num_channels = mChannels.size(); 187 bucketSettings.channels = new WifiNative.ChannelSettings[mChannels.size()]; 188 for (int i = 0; i < mChannels.size(); ++i) { 189 WifiNative.ChannelSettings channelSettings = new WifiNative.ChannelSettings(); 190 channelSettings.frequency = mChannels.valueAt(i); 191 bucketSettings.channels[i] = channelSettings; 192 } 193 } 194 } 195 196 @Override 197 public Set<Integer> getSupplicantScanFreqs() { 198 if (mAllBands == mExactBands && mExactBands == WifiScanner.WIFI_BAND_BOTH_WITH_DFS) { 199 return null; 200 } else { 201 return new ArraySet<Integer>(mChannels); 202 } 203 } 204 } 205 206 @Override 207 public ChannelCollection createChannelCollection() { 208 return new KnownBandsChannelCollection(); 209 } 210} 211