177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistpackage com.android.server.wifi.hotspot2; 277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 3947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhneimport static com.android.server.wifi.anqp.Constants.BYTES_IN_EUI48; 4947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhneimport static com.android.server.wifi.anqp.Constants.BYTE_MASK; 5947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne 677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport android.net.wifi.ScanResult; 773185809f4a44a8ee272afe3e5253496aeb966ceLorenzo Colittiimport android.util.Log; 877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport com.android.server.wifi.anqp.ANQPElement; 1077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport com.android.server.wifi.anqp.Constants; 112e814680f4dd27a5f825afab189843582235cedcJan Nordqvistimport com.android.server.wifi.anqp.RawByteElement; 1277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport com.android.server.wifi.anqp.VenueNameElement; 135d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Willsimport com.android.server.wifi.util.InformationElementUtil; 1477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 15a1edc185d46d85e04930a5e12b465de9fea64afeJan Nordqvistimport java.nio.BufferUnderflowException; 1677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.nio.ByteBuffer; 17fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvistimport java.nio.CharBuffer; 18fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvistimport java.nio.charset.CharacterCodingException; 19fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvistimport java.nio.charset.CharsetDecoder; 2077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.nio.charset.StandardCharsets; 21f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhneimport java.util.ArrayList; 2277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.util.List; 2377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.util.Map; 2473185809f4a44a8ee272afe3e5253496aeb966ceLorenzo Colitti 2577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistpublic class NetworkDetail { 2677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 27243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe //turn off when SHIP 28243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe private static final boolean DBG = true; 29d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande private static final boolean VDBG = false; 305d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills 31243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe private static final String TAG = "NetworkDetail:"; 3277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 3377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public enum Ant { 3477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Private, 3577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist PrivateWithGuest, 3677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist ChargeablePublic, 3777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist FreePublic, 3877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Personal, 3977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist EmergencyOnly, 4077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd6, 4177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd7, 4277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd8, 4377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd9, 4477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd10, 4577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd11, 4677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd12, 4777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd13, 4877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist TestOrExperimental, 4977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Wildcard 5077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 5177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 5277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public enum HSRelease { 5377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist R1, 5477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist R2, 5577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Unknown 5677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 5777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 5877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // General identifiers: 5977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final String mSSID; 6077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final long mHESSID; 6177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final long mBSSID; 627a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne // True if the SSID is potentially from a hidden network 637a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne private final boolean mIsHiddenSsid; 6477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 6577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // BSS Load element: 6677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final int mStationCount; 6777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final int mChannelUtilization; 6877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final int mCapacity; 6977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 70243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe //channel detailed information 71243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe /* 72243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe * 0 -- 20 MHz 73243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe * 1 -- 40 MHz 74243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe * 2 -- 80 MHz 75243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe * 3 -- 160 MHz 76243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe * 4 -- 80 + 80 MHz 77243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe */ 78243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe private final int mChannelWidth; 79243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe private final int mPrimaryFreq; 80243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe private final int mCenterfreq0; 81243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe private final int mCenterfreq1; 82f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne 83f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne /* 84f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne * 802.11 Standard (calculated from Capabilities and Supported Rates) 85f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne * 0 -- Unknown 86f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne * 1 -- 802.11a 87f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne * 2 -- 802.11b 88f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne * 3 -- 802.11g 89f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne * 4 -- 802.11n 90f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne * 7 -- 802.11ac 91f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne */ 92f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne private final int mWifiMode; 93f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne private final int mMaxRate; 94f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne 9577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist /* 9677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * From Interworking element: 9777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * mAnt non null indicates the presence of Interworking, i.e. 802.11u 9877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * mVenueGroup and mVenueType may be null if not present in the Interworking element. 9977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist */ 10077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final Ant mAnt; 10177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final boolean mInternet; 10277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final VenueNameElement.VenueGroup mVenueGroup; 10377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final VenueNameElement.VenueType mVenueType; 10477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 10577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist /* 10677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * From HS20 Indication element: 10777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * mHSRelease is null only if the HS20 Indication element was not present. 10877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * mAnqpDomainID is set to -1 if not present in the element. 10977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist */ 11077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final HSRelease mHSRelease; 11177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final int mAnqpDomainID; 11277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 11377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist /* 11477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * From beacon: 11577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * mAnqpOICount is how many additional OIs are available through ANQP. 11677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * mRoamingConsortiums is either null, if the element was not present, or is an array of 11777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * 1, 2 or 3 longs in which the roaming consortium values occupy the LSBs. 11877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist */ 11977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final int mAnqpOICount; 12077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final long[] mRoamingConsortiums; 121947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne private int mDtimInterval = -1; 12277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1235d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills private final InformationElementUtil.ExtendedCapabilities mExtendedCapabilities; 12477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 12577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final Map<Constants.ANQPElementType, ANQPElement> mANQPElements; 12677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1275d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills public NetworkDetail(String bssid, ScanResult.InformationElement[] infoElements, 1285d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills List<String> anqpLines, int freq) { 12977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (infoElements == null) { 1305d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills throw new IllegalArgumentException("Null information elements"); 13177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 13277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1335bee0e4616e2f8025d60cbfe3eec3e274a68a452Jan Nordqvist mBSSID = Utils.parseMac(bssid); 13477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 13577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist String ssid = null; 1367a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne boolean isHiddenSsid = false; 13777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist byte[] ssidOctets = null; 13877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1395d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills InformationElementUtil.BssLoad bssLoad = new InformationElementUtil.BssLoad(); 14077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1415d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills InformationElementUtil.Interworking interworking = 1425d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills new InformationElementUtil.Interworking(); 14377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1445d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills InformationElementUtil.RoamingConsortium roamingConsortium = 1455d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills new InformationElementUtil.RoamingConsortium(); 14677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1475d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa(); 14877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1495d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills InformationElementUtil.HtOperation htOperation = new InformationElementUtil.HtOperation(); 1505d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills InformationElementUtil.VhtOperation vhtOperation = 1515d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills new InformationElementUtil.VhtOperation(); 1525d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills 1535d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills InformationElementUtil.ExtendedCapabilities extendedCapabilities = 1545d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills new InformationElementUtil.ExtendedCapabilities(); 155243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe 156947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne InformationElementUtil.TrafficIndicationMap trafficIndicationMap = 157947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne new InformationElementUtil.TrafficIndicationMap(); 158f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne 159f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne InformationElementUtil.SupportedRates supportedRates = 160f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne new InformationElementUtil.SupportedRates(); 161f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne InformationElementUtil.SupportedRates extendedSupportedRates = 162f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne new InformationElementUtil.SupportedRates(); 163f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne 164c1072acda7dc8b9d7bc4a9bb0b1177b14ecaf276xinhe RuntimeException exception = null; 165f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne 166f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne ArrayList<Integer> iesFound = new ArrayList<Integer>(); 167fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist try { 1685d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills for (ScanResult.InformationElement ie : infoElements) { 169f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne iesFound.add(ie.id); 1705d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills switch (ie.id) { 1715d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills case ScanResult.InformationElement.EID_SSID: 1725d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills ssidOctets = ie.bytes; 173fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 1745d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills case ScanResult.InformationElement.EID_BSS_LOAD: 1755d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills bssLoad.from(ie); 176fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 1775d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills case ScanResult.InformationElement.EID_HT_OPERATION: 1785d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills htOperation.from(ie); 179fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 1805d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills case ScanResult.InformationElement.EID_VHT_OPERATION: 1815d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills vhtOperation.from(ie); 182fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 1835d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills case ScanResult.InformationElement.EID_INTERWORKING: 1845d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills interworking.from(ie); 185fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 1865d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills case ScanResult.InformationElement.EID_ROAMING_CONSORTIUM: 1875d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills roamingConsortium.from(ie); 188fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 1895d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills case ScanResult.InformationElement.EID_VSA: 1905d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills vsa.from(ie); 191fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 1925d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills case ScanResult.InformationElement.EID_EXTENDED_CAPS: 1935d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills extendedCapabilities.from(ie); 194fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 195947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne case ScanResult.InformationElement.EID_TIM: 196947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne trafficIndicationMap.from(ie); 197947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne break; 198f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne case ScanResult.InformationElement.EID_SUPPORTED_RATES: 199f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne supportedRates.from(ie); 200f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne break; 201f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne case ScanResult.InformationElement.EID_EXTENDED_SUPPORTED_RATES: 202f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne extendedSupportedRates.from(ie); 203f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne break; 204fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist default: 205243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe break; 206fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 207fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 208fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 209be24c9af85b8a6e02b24582418a4608e14396f2aJan Nordqvist catch (IllegalArgumentException | BufferUnderflowException | ArrayIndexOutOfBoundsException e) { 2101c03d75c73b9f5fa24a795a0d546f4f56b82ab9bJan Nordqvist Log.d(Utils.hs2LogTag(getClass()), "Caught " + e); 211fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist if (ssidOctets == null) { 212d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist throw new IllegalArgumentException("Malformed IE string (no SSID)", e); 21377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 214a1edc185d46d85e04930a5e12b465de9fea64afeJan Nordqvist exception = e; 21577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 21677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (ssidOctets != null) { 217d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist /* 218d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist * Strict use of the "UTF-8 SSID" bit by APs appears to be spotty at best even if the 219d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist * encoding truly is in UTF-8. An unconditional attempt to decode the SSID as UTF-8 is 220d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist * therefore always made with a fall back to 8859-1 under normal circumstances. 221d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist * If, however, a previous exception was detected and the UTF-8 bit is set, failure to 222d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist * decode the SSID will be used as an indication that the whole frame is malformed and 223d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist * an exception will be triggered. 224d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist */ 225d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder(); 226d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist try { 227d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist CharBuffer decoded = decoder.decode(ByteBuffer.wrap(ssidOctets)); 228d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist ssid = decoded.toString(); 22977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 230d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist catch (CharacterCodingException cce) { 231d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist ssid = null; 23277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 233fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist 234d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist if (ssid == null) { 2355d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills if (extendedCapabilities.isStrictUtf8() && exception != null) { 236d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist throw new IllegalArgumentException("Failed to decode SSID in dubious IE string"); 237fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 238d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist else { 239d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist ssid = new String(ssidOctets, StandardCharsets.ISO_8859_1); 240fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 241fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 2427a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne isHiddenSsid = true; 2437a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne for (byte byteVal : ssidOctets) { 2447a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne if (byteVal != 0) { 2457a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne isHiddenSsid = false; 2467a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne break; 2477a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne } 2487a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne } 24977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 25077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 25177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mSSID = ssid; 2525d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mHESSID = interworking.hessid; 2537a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne mIsHiddenSsid = isHiddenSsid; 2545d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mStationCount = bssLoad.stationCount; 2555d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mChannelUtilization = bssLoad.channelUtilization; 2565d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mCapacity = bssLoad.capacity; 2575d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mAnt = interworking.ant; 2585d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mInternet = interworking.internet; 2595d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mVenueGroup = interworking.venueGroup; 2605d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mVenueType = interworking.venueType; 2615d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mHSRelease = vsa.hsRelease; 2625d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mAnqpDomainID = vsa.anqpDomainID; 2635d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mAnqpOICount = roamingConsortium.anqpOICount; 2645d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mRoamingConsortiums = roamingConsortium.roamingConsortiums; 26577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mExtendedCapabilities = extendedCapabilities; 26677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mANQPElements = SupplicantBridge.parseANQPLines(anqpLines); 267243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe //set up channel info 268243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mPrimaryFreq = freq; 269243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe 2705d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills if (vhtOperation.isValid()) { 271243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe // 80 or 160 MHz 2725d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mChannelWidth = vhtOperation.getChannelWidth(); 2735d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mCenterfreq0 = vhtOperation.getCenterFreq0(); 2745d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mCenterfreq1 = vhtOperation.getCenterFreq1(); 275243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } else { 2765d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mChannelWidth = htOperation.getChannelWidth(); 2775d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mCenterfreq0 = htOperation.getCenterFreq0(mPrimaryFreq); 2785d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mCenterfreq1 = 0; 279243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } 280947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne 281947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne // If trafficIndicationMap is not valid, mDtimPeriod will be negative 2827a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne if (trafficIndicationMap.isValid()) { 2837a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne mDtimInterval = trafficIndicationMap.mDtimPeriod; 2847a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne } 285947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne 286f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne int maxRateA = 0; 287f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne int maxRateB = 0; 288f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne // If we got some Extended supported rates, consider them, if not default to 0 289f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne if (extendedSupportedRates.isValid()) { 290f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne // rates are sorted from smallest to largest in InformationElement 291f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne maxRateB = extendedSupportedRates.mRates.get(extendedSupportedRates.mRates.size() - 1); 292f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne } 293f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne // Only process the determination logic if we got a 'SupportedRates' 294f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne if (supportedRates.isValid()) { 295f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne maxRateA = supportedRates.mRates.get(supportedRates.mRates.size() - 1); 296f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne mMaxRate = maxRateA > maxRateB ? maxRateA : maxRateB; 297f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne mWifiMode = InformationElementUtil.WifiMode.determineMode(mPrimaryFreq, mMaxRate, 298f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne vhtOperation.isValid(), 299f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne iesFound.contains(ScanResult.InformationElement.EID_HT_OPERATION), 300f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne iesFound.contains(ScanResult.InformationElement.EID_ERP)); 301f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne } else { 302f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne mWifiMode = 0; 303f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne mMaxRate = 0; 304f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne Log.w("WifiMode", mSSID + ", Invalid SupportedRates!!!"); 305f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne } 306d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande if (VDBG) { 307f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne Log.d(TAG, mSSID + "ChannelWidth is: " + mChannelWidth + " PrimaryFreq: " + mPrimaryFreq 308f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne + " mCenterfreq0: " + mCenterfreq0 + " mCenterfreq1: " + mCenterfreq1 309f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne + (extendedCapabilities.is80211McRTTResponder ? "Support RTT reponder" 310f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne : "Do not support RTT responder")); 311f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne Log.v("WifiMode", mSSID 312f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne + ", WifiMode: " + InformationElementUtil.WifiMode.toString(mWifiMode) 313f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne + ", Freq: " + mPrimaryFreq 314f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne + ", mMaxRate: " + mMaxRate 315f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne + ", VHT: " + String.valueOf(vhtOperation.isValid()) 316f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne + ", HT: " + String.valueOf( 317f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne iesFound.contains(ScanResult.InformationElement.EID_HT_OPERATION)) 318f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne + ", ERP: " + String.valueOf( 319f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne iesFound.contains(ScanResult.InformationElement.EID_ERP)) 320f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne + ", SupportedRates: " + supportedRates.toString() 321f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne + " ExtendedSupportedRates: " + extendedSupportedRates.toString()); 322d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande } 32377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 32477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 325fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist private static ByteBuffer getAndAdvancePayload(ByteBuffer data, int plLength) { 326398823d45a240ff90ff2ffab3ff4a8b8646f24c9Jan Nordqvist ByteBuffer payload = data.duplicate().order(data.order()); 327fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist payload.limit(payload.position() + plLength); 328fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist data.position(data.position() + plLength); 329fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist return payload; 330fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 331fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist 33277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private NetworkDetail(NetworkDetail base, Map<Constants.ANQPElementType, ANQPElement> anqpElements) { 33377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mSSID = base.mSSID; 3347a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne mIsHiddenSsid = base.mIsHiddenSsid; 33577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mBSSID = base.mBSSID; 33677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mHESSID = base.mHESSID; 33777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mStationCount = base.mStationCount; 33877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mChannelUtilization = base.mChannelUtilization; 33977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mCapacity = base.mCapacity; 34077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mAnt = base.mAnt; 34177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mInternet = base.mInternet; 34277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mVenueGroup = base.mVenueGroup; 34377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mVenueType = base.mVenueType; 34477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mHSRelease = base.mHSRelease; 34577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mAnqpDomainID = base.mAnqpDomainID; 34677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mAnqpOICount = base.mAnqpOICount; 34777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mRoamingConsortiums = base.mRoamingConsortiums; 3485d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mExtendedCapabilities = 3495d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills new InformationElementUtil.ExtendedCapabilities(base.mExtendedCapabilities); 35077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mANQPElements = anqpElements; 351243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mChannelWidth = base.mChannelWidth; 352243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mPrimaryFreq = base.mPrimaryFreq; 353243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mCenterfreq0 = base.mCenterfreq0; 354243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mCenterfreq1 = base.mCenterfreq1; 355947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne mDtimInterval = base.mDtimInterval; 356f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne mWifiMode = base.mWifiMode; 357f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne mMaxRate = base.mMaxRate; 35877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 35977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 36077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public NetworkDetail complete(Map<Constants.ANQPElementType, ANQPElement> anqpElements) { 36177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return new NetworkDetail(this, anqpElements); 36277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 36377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 3641d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist public boolean queriable(List<Constants.ANQPElementType> queryElements) { 3651d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist return mAnt != null && 3661d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist (Constants.hasBaseANQPElements(queryElements) || 3671d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist Constants.hasR2Elements(queryElements) && mHSRelease == HSRelease.R2); 36877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 36977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 37077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public boolean has80211uInfo() { 37177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mAnt != null || mRoamingConsortiums != null || mHSRelease != null; 37277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 37377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 37477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public boolean hasInterworking() { 37577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mAnt != null; 37677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 37777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 37877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public String getSSID() { 37977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mSSID; 38077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 38177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 3829a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist public String getTrimmedSSID() { 3839a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist for (int n = 0; n < mSSID.length(); n++) { 3849a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist if (mSSID.charAt(n) != 0) { 3859a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist return mSSID; 3869a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist } 3879a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist } 3889a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist return ""; 3899a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist } 3909a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist 39177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public long getHESSID() { 39277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mHESSID; 39377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 39477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 39577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public long getBSSID() { 39677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mBSSID; 39777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 39877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 39977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public int getStationCount() { 40077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mStationCount; 40177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 40277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 40377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public int getChannelUtilization() { 40477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mChannelUtilization; 40577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 40677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 40777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public int getCapacity() { 40877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mCapacity; 40977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 41077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 41177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public boolean isInterworking() { 41277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mAnt != null; 41377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 41477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 41577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public Ant getAnt() { 41677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mAnt; 41777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 41877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 41977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public boolean isInternet() { 42077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mInternet; 42177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 42277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 42377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public VenueNameElement.VenueGroup getVenueGroup() { 42477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mVenueGroup; 42577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 42677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 42777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public VenueNameElement.VenueType getVenueType() { 42877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mVenueType; 42977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 43077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 43177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public HSRelease getHSRelease() { 43277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mHSRelease; 43377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 43477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 43577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public int getAnqpDomainID() { 43677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mAnqpDomainID; 43777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 43877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 4392e814680f4dd27a5f825afab189843582235cedcJan Nordqvist public byte[] getOsuProviders() { 4402e814680f4dd27a5f825afab189843582235cedcJan Nordqvist if (mANQPElements == null) { 4412e814680f4dd27a5f825afab189843582235cedcJan Nordqvist return null; 4422e814680f4dd27a5f825afab189843582235cedcJan Nordqvist } 4432e814680f4dd27a5f825afab189843582235cedcJan Nordqvist ANQPElement osuProviders = mANQPElements.get(Constants.ANQPElementType.HSOSUProviders); 4442e814680f4dd27a5f825afab189843582235cedcJan Nordqvist return osuProviders != null ? ((RawByteElement) osuProviders).getPayload() : null; 4452e814680f4dd27a5f825afab189843582235cedcJan Nordqvist } 4462e814680f4dd27a5f825afab189843582235cedcJan Nordqvist 44777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public int getAnqpOICount() { 44877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mAnqpOICount; 44977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 45077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 45177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public long[] getRoamingConsortiums() { 45277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mRoamingConsortiums; 45377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 45477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 45577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public Long getExtendedCapabilities() { 4565d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills return mExtendedCapabilities.extendedCapabilities; 45777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 45877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 45977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public Map<Constants.ANQPElementType, ANQPElement> getANQPElements() { 46077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mANQPElements; 46177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 46277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 463243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe public int getChannelWidth() { 464243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe return mChannelWidth; 465243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } 466243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe 467243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe public int getCenterfreq0() { 468243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe return mCenterfreq0; 469243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } 470243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe 471243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe public int getCenterfreq1() { 472243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe return mCenterfreq1; 473243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } 474243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe 475f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne public int getWifiMode() { 476f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne return mWifiMode; 477f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne } 478f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne 479947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne public int getDtimInterval() { 480947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne return mDtimInterval; 481947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne } 482947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne 483243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe public boolean is80211McResponderSupport() { 4845d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills return mExtendedCapabilities.is80211McRTTResponder; 485243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } 486243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe 48777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public boolean isSSID_UTF8() { 4885d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills return mExtendedCapabilities.isStrictUtf8(); 48977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 49077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 49177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist @Override 49277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public boolean equals(Object thatObject) { 49377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (this == thatObject) { 49477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return true; 49577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 49677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (thatObject == null || getClass() != thatObject.getClass()) { 49777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return false; 49877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 49977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 50077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist NetworkDetail that = (NetworkDetail)thatObject; 50177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 50277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return getSSID().equals(that.getSSID()) && getBSSID() == that.getBSSID(); 50377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 50477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 50577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist @Override 50677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public int hashCode() { 50777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return ((mSSID.hashCode() * 31) + (int)(mBSSID >>> 32)) * 31 + (int)mBSSID; 50877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 50977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 51077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist @Override 51177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public String toString() { 5121d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist return String.format("NetworkInfo{SSID='%s', HESSID=%x, BSSID=%x, StationCount=%d, " + 5131d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist "ChannelUtilization=%d, Capacity=%d, Ant=%s, Internet=%s, " + 5141d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist "VenueGroup=%s, VenueType=%s, HSRelease=%s, AnqpDomainID=%d, " + 5151d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist "AnqpOICount=%d, RoamingConsortiums=%s}", 51677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mSSID, mHESSID, mBSSID, mStationCount, 51777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mChannelUtilization, mCapacity, mAnt, mInternet, 51877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mVenueGroup, mVenueType, mHSRelease, mAnqpDomainID, 51977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mAnqpOICount, Utils.roamingConsortiumsToString(mRoamingConsortiums)); 52077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 52177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 52277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public String toKeyString() { 523a1edc185d46d85e04930a5e12b465de9fea64afeJan Nordqvist return mHESSID != 0 ? 524866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist String.format("'%s':%012x (%012x)", mSSID, mBSSID, mHESSID) : 525866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist String.format("'%s':%012x", mSSID, mBSSID); 52677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 52777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 52877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public String getBSSIDString() { 52977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return toMACString(mBSSID); 53077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 53177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 5327a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne /** 5337a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne * Evaluates the ScanResult this NetworkDetail is built from 5347a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne * returns true if built from a Beacon Frame 5357a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne * returns false if built from a Probe Response 5367a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne */ 5377a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne public boolean isBeaconFrame() { 5387a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne // Beacon frames have a 'Traffic Indication Map' Information element 5397a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne // Probe Responses do not. This is indicated by a DTIM period > 0 5407a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne return mDtimInterval > 0; 5417a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne } 5427a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne 5437a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne /** 5447a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne * Evaluates the ScanResult this NetworkDetail is built from 5457a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne * returns true if built from a hidden Beacon Frame 5467a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne * returns false if not hidden or not a Beacon 5477a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne */ 5487a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne public boolean isHiddenBeaconFrame() { 5497a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne // Hidden networks are not 80211 standard, but it is common for a hidden network beacon 5507a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne // frame to either send zero-value bytes as the SSID, or to send no bytes at all. 5517a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne return isBeaconFrame() && mIsHiddenSsid; 5527a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne } 5537a36be372edfa3f7fe0e37320b9b21a5fbadf277Glen Kuhne 554ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist public static String toMACString(long mac) { 55577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist StringBuilder sb = new StringBuilder(); 55677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist boolean first = true; 55777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist for (int n = BYTES_IN_EUI48 - 1; n >= 0; n--) { 55877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (first) { 55977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist first = false; 56077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } else { 56177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist sb.append(':'); 56277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 56377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist sb.append(String.format("%02x", (mac >>> (n * Byte.SIZE)) & BYTE_MASK)); 56477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 56577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return sb.toString(); 56677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 56777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist} 568