1 /* 2 * Copyright (C) 2020 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 17 package android.net.wifi.nl80211; 18 19 import android.annotation.NonNull; 20 import android.annotation.SystemApi; 21 import android.net.wifi.ScanResult; 22 import android.net.wifi.WifiAnnotations.ChannelWidth; 23 import android.net.wifi.WifiAnnotations.WifiStandard; 24 import android.os.Parcel; 25 import android.os.Parcelable; 26 import android.util.Log; 27 28 import java.util.Objects; 29 30 /** 31 * DeviceWiphyCapabilities for wificond 32 * 33 * Contains the WiFi physical layer attributes and capabilities of the device. 34 * It is used to collect these attributes from the device driver via wificond. 35 * 36 * @hide 37 */ 38 @SystemApi 39 public final class DeviceWiphyCapabilities implements Parcelable { 40 private static final String TAG = "DeviceWiphyCapabilities"; 41 42 private boolean m80211nSupported; 43 private boolean m80211acSupported; 44 private boolean m80211axSupported; 45 private boolean mChannelWidth160MhzSupported; 46 private boolean mChannelWidth80p80MhzSupported; 47 private int mMaxNumberTxSpatialStreams; 48 private int mMaxNumberRxSpatialStreams; 49 50 51 /** public constructor */ DeviceWiphyCapabilities()52 public DeviceWiphyCapabilities() { 53 m80211nSupported = false; 54 m80211acSupported = false; 55 m80211axSupported = false; 56 mChannelWidth160MhzSupported = false; 57 mChannelWidth80p80MhzSupported = false; 58 mMaxNumberTxSpatialStreams = 1; 59 mMaxNumberRxSpatialStreams = 1; 60 } 61 62 /** 63 * Get the IEEE 802.11 standard support 64 * 65 * @param standard the IEEE 802.11 standard to check on its support. 66 * valid values from {@link ScanResult}'s {@code WIFI_STANDARD_} 67 * @return {@code true} if supported, {@code false} otherwise. 68 */ isWifiStandardSupported(@ifiStandard int standard)69 public boolean isWifiStandardSupported(@WifiStandard int standard) { 70 switch (standard) { 71 case ScanResult.WIFI_STANDARD_LEGACY: 72 return true; 73 case ScanResult.WIFI_STANDARD_11N: 74 return m80211nSupported; 75 case ScanResult.WIFI_STANDARD_11AC: 76 return m80211acSupported; 77 case ScanResult.WIFI_STANDARD_11AX: 78 return m80211axSupported; 79 default: 80 Log.e(TAG, "isWifiStandardSupported called with invalid standard: " + standard); 81 return false; 82 } 83 } 84 85 /** 86 * Set the IEEE 802.11 standard support 87 * 88 * @param standard the IEEE 802.11 standard to set its support. 89 * valid values from {@link ScanResult}'s {@code WIFI_STANDARD_} 90 * @param support {@code true} if supported, {@code false} otherwise. 91 */ setWifiStandardSupport(@ifiStandard int standard, boolean support)92 public void setWifiStandardSupport(@WifiStandard int standard, boolean support) { 93 switch (standard) { 94 case ScanResult.WIFI_STANDARD_11N: 95 m80211nSupported = support; 96 break; 97 case ScanResult.WIFI_STANDARD_11AC: 98 m80211acSupported = support; 99 break; 100 case ScanResult.WIFI_STANDARD_11AX: 101 m80211axSupported = support; 102 break; 103 default: 104 Log.e(TAG, "setWifiStandardSupport called with invalid standard: " + standard); 105 } 106 } 107 108 /** 109 * Get the support for channel bandwidth 110 * 111 * @param chWidth valid values from {@link ScanResult}'s {@code CHANNEL_WIDTH_} 112 * 113 * @return {@code true} if supported, {@code false} otherwise. 114 */ isChannelWidthSupported(@hannelWidth int chWidth)115 public boolean isChannelWidthSupported(@ChannelWidth int chWidth) { 116 switch (chWidth) { 117 case ScanResult.CHANNEL_WIDTH_20MHZ: 118 return true; 119 case ScanResult.CHANNEL_WIDTH_40MHZ: 120 return (m80211nSupported || m80211acSupported || m80211axSupported); 121 case ScanResult.CHANNEL_WIDTH_80MHZ: 122 return (m80211acSupported || m80211axSupported); 123 case ScanResult.CHANNEL_WIDTH_160MHZ: 124 return mChannelWidth160MhzSupported; 125 case ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ: 126 return mChannelWidth80p80MhzSupported; 127 default: 128 Log.e(TAG, "isChannelWidthSupported called with invalid channel width: " + chWidth); 129 } 130 return false; 131 } 132 133 /** 134 * Set support for channel bandwidth 135 * 136 * @param chWidth valid values are {@link ScanResult#CHANNEL_WIDTH_160MHZ} and 137 * {@link ScanResult#CHANNEL_WIDTH_80MHZ_PLUS_MHZ} 138 * @param support {@code true} if supported, {@code false} otherwise. 139 * 140 * @hide 141 */ setChannelWidthSupported(@hannelWidth int chWidth, boolean support)142 public void setChannelWidthSupported(@ChannelWidth int chWidth, boolean support) { 143 switch (chWidth) { 144 case ScanResult.CHANNEL_WIDTH_160MHZ: 145 mChannelWidth160MhzSupported = support; 146 break; 147 case ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ: 148 mChannelWidth80p80MhzSupported = support; 149 break; 150 default: 151 Log.e(TAG, "setChannelWidthSupported called with Invalid channel width: " 152 + chWidth); 153 } 154 } 155 156 /** 157 * Get maximum number of transmit spatial streams 158 * 159 * @return number of spatial streams 160 */ getMaxNumberTxSpatialStreams()161 public int getMaxNumberTxSpatialStreams() { 162 return mMaxNumberTxSpatialStreams; 163 } 164 165 /** 166 * Set maximum number of transmit spatial streams 167 * 168 * @param streams number of spatial streams 169 * 170 * @hide 171 */ setMaxNumberTxSpatialStreams(int streams)172 public void setMaxNumberTxSpatialStreams(int streams) { 173 mMaxNumberTxSpatialStreams = streams; 174 } 175 176 /** 177 * Get maximum number of receive spatial streams 178 * 179 * @return number of streams 180 */ getMaxNumberRxSpatialStreams()181 public int getMaxNumberRxSpatialStreams() { 182 return mMaxNumberRxSpatialStreams; 183 } 184 185 /** 186 * Set maximum number of receive spatial streams 187 * 188 * @param streams number of streams 189 * 190 * @hide 191 */ setMaxNumberRxSpatialStreams(int streams)192 public void setMaxNumberRxSpatialStreams(int streams) { 193 mMaxNumberRxSpatialStreams = streams; 194 } 195 196 /** override comparator */ 197 @Override equals(Object rhs)198 public boolean equals(Object rhs) { 199 if (this == rhs) return true; 200 if (!(rhs instanceof DeviceWiphyCapabilities)) { 201 return false; 202 } 203 DeviceWiphyCapabilities capa = (DeviceWiphyCapabilities) rhs; 204 205 return m80211nSupported == capa.m80211nSupported 206 && m80211acSupported == capa.m80211acSupported 207 && m80211axSupported == capa.m80211axSupported 208 && mChannelWidth160MhzSupported == capa.mChannelWidth160MhzSupported 209 && mChannelWidth80p80MhzSupported == capa.mChannelWidth80p80MhzSupported 210 && mMaxNumberTxSpatialStreams == capa.mMaxNumberTxSpatialStreams 211 && mMaxNumberRxSpatialStreams == capa.mMaxNumberRxSpatialStreams; 212 } 213 214 /** override hash code */ 215 @Override hashCode()216 public int hashCode() { 217 return Objects.hash(m80211nSupported, m80211acSupported, m80211axSupported, 218 mChannelWidth160MhzSupported, mChannelWidth80p80MhzSupported, 219 mMaxNumberTxSpatialStreams, mMaxNumberRxSpatialStreams); 220 } 221 222 /** implement Parcelable interface */ 223 @Override describeContents()224 public int describeContents() { 225 return 0; 226 } 227 228 /** 229 * implement Parcelable interface 230 * |flags| is ignored. 231 */ 232 @Override writeToParcel(@onNull Parcel out, int flags)233 public void writeToParcel(@NonNull Parcel out, int flags) { 234 out.writeBoolean(m80211nSupported); 235 out.writeBoolean(m80211acSupported); 236 out.writeBoolean(m80211axSupported); 237 out.writeBoolean(mChannelWidth160MhzSupported); 238 out.writeBoolean(mChannelWidth80p80MhzSupported); 239 out.writeInt(mMaxNumberTxSpatialStreams); 240 out.writeInt(mMaxNumberRxSpatialStreams); 241 } 242 243 @Override toString()244 public String toString() { 245 StringBuilder sb = new StringBuilder(); 246 sb.append("m80211nSupported:").append(m80211nSupported ? "Yes" : "No"); 247 sb.append("m80211acSupported:").append(m80211acSupported ? "Yes" : "No"); 248 sb.append("m80211axSupported:").append(m80211axSupported ? "Yes" : "No"); 249 sb.append("mChannelWidth160MhzSupported: ") 250 .append(mChannelWidth160MhzSupported ? "Yes" : "No"); 251 sb.append("mChannelWidth80p80MhzSupported: ") 252 .append(mChannelWidth80p80MhzSupported ? "Yes" : "No"); 253 sb.append("mMaxNumberTxSpatialStreams: ").append(mMaxNumberTxSpatialStreams); 254 sb.append("mMaxNumberRxSpatialStreams: ").append(mMaxNumberRxSpatialStreams); 255 256 return sb.toString(); 257 } 258 259 /** implement Parcelable interface */ 260 public static final @NonNull Parcelable.Creator<DeviceWiphyCapabilities> CREATOR = 261 new Parcelable.Creator<DeviceWiphyCapabilities>() { 262 /** 263 * Caller is responsible for providing a valid parcel. 264 */ 265 @Override 266 public DeviceWiphyCapabilities createFromParcel(Parcel in) { 267 DeviceWiphyCapabilities capabilities = new DeviceWiphyCapabilities(); 268 capabilities.m80211nSupported = in.readBoolean(); 269 capabilities.m80211acSupported = in.readBoolean(); 270 capabilities.m80211axSupported = in.readBoolean(); 271 capabilities.mChannelWidth160MhzSupported = in.readBoolean(); 272 capabilities.mChannelWidth80p80MhzSupported = in.readBoolean(); 273 capabilities.mMaxNumberTxSpatialStreams = in.readInt(); 274 capabilities.mMaxNumberRxSpatialStreams = in.readInt(); 275 return capabilities; 276 } 277 278 @Override 279 public DeviceWiphyCapabilities[] newArray(int size) { 280 return new DeviceWiphyCapabilities[size]; 281 } 282 }; 283 } 284