177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistpackage com.android.server.wifi.hotspot2; 277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 38ca4ac971a9b862fbd69c57af3a3c0029a6b9f4dPeter Qiuimport static com.android.server.wifi.hotspot2.anqp.Constants.BYTES_IN_EUI48; 48ca4ac971a9b862fbd69c57af3a3c0029a6b9f4dPeter Qiuimport static com.android.server.wifi.hotspot2.anqp.Constants.BYTE_MASK; 5947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne 677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport android.net.wifi.ScanResult; 773185809f4a44a8ee272afe3e5253496aeb966ceLorenzo Colittiimport android.util.Log; 877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 98ca4ac971a9b862fbd69c57af3a3c0029a6b9f4dPeter Qiuimport com.android.server.wifi.hotspot2.anqp.ANQPElement; 108ca4ac971a9b862fbd69c57af3a3c0029a6b9f4dPeter Qiuimport com.android.server.wifi.hotspot2.anqp.Constants; 118ca4ac971a9b862fbd69c57af3a3c0029a6b9f4dPeter Qiuimport com.android.server.wifi.hotspot2.anqp.RawByteElement; 125d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Willsimport com.android.server.wifi.util.InformationElementUtil; 1377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 14a1edc185d46d85e04930a5e12b465de9fea64afeJan Nordqvistimport java.nio.BufferUnderflowException; 1577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.nio.ByteBuffer; 16fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvistimport java.nio.CharBuffer; 17fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvistimport java.nio.charset.CharacterCodingException; 18fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvistimport java.nio.charset.CharsetDecoder; 1977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.nio.charset.StandardCharsets; 20f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhneimport java.util.ArrayList; 2177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.util.List; 2277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.util.Map; 2373185809f4a44a8ee272afe3e5253496aeb966ceLorenzo Colitti 2477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistpublic class NetworkDetail { 2577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 268f14e9784bd8ca8e832fff86597a28755f7e668eSamuel Tan private static final boolean DBG = false; 275d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills 28243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe private static final String TAG = "NetworkDetail:"; 2977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 3077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public enum Ant { 3177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Private, 3277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist PrivateWithGuest, 3377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist ChargeablePublic, 3477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist FreePublic, 3577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Personal, 3677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist EmergencyOnly, 3777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd6, 3877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd7, 3977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd8, 4077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd9, 4177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd10, 4277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd11, 4377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd12, 4477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd13, 4577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist TestOrExperimental, 4677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Wildcard 4777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 4877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 4977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public enum HSRelease { 5077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist R1, 5177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist R2, 5277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Unknown 5377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 5477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 5577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // General identifiers: 5677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final String mSSID; 5777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final long mHESSID; 5877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final long mBSSID; 5959f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne // True if the SSID is potentially from a hidden network 6059f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne private final boolean mIsHiddenSsid; 6177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 6277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // BSS Load element: 6377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final int mStationCount; 6477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final int mChannelUtilization; 6577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final int mCapacity; 6677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 67243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe //channel detailed information 68243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe /* 69243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe * 0 -- 20 MHz 70243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe * 1 -- 40 MHz 71243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe * 2 -- 80 MHz 72243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe * 3 -- 160 MHz 73243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe * 4 -- 80 + 80 MHz 74243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe */ 75243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe private final int mChannelWidth; 76243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe private final int mPrimaryFreq; 77243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe private final int mCenterfreq0; 78243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe private final int mCenterfreq1; 79f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne 80f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne /* 81f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne * 802.11 Standard (calculated from Capabilities and Supported Rates) 82f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne * 0 -- Unknown 83f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne * 1 -- 802.11a 84f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne * 2 -- 802.11b 85f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne * 3 -- 802.11g 86f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne * 4 -- 802.11n 87f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne * 7 -- 802.11ac 88f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne */ 89f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne private final int mWifiMode; 90f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne private final int mMaxRate; 91f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne 9277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist /* 9377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * From Interworking element: 9477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * mAnt non null indicates the presence of Interworking, i.e. 802.11u 9577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist */ 9677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final Ant mAnt; 9777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final boolean mInternet; 9877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 9977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist /* 10077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * From HS20 Indication element: 10177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * mHSRelease is null only if the HS20 Indication element was not present. 10277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * mAnqpDomainID is set to -1 if not present in the element. 10377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist */ 10477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final HSRelease mHSRelease; 10577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final int mAnqpDomainID; 10677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 10777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist /* 10877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * From beacon: 10977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * mAnqpOICount is how many additional OIs are available through ANQP. 11077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * mRoamingConsortiums is either null, if the element was not present, or is an array of 11177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * 1, 2 or 3 longs in which the roaming consortium values occupy the LSBs. 11277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist */ 11377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final int mAnqpOICount; 11477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final long[] mRoamingConsortiums; 115947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne private int mDtimInterval = -1; 11677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1175d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills private final InformationElementUtil.ExtendedCapabilities mExtendedCapabilities; 11877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 11977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final Map<Constants.ANQPElementType, ANQPElement> mANQPElements; 12077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1215d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills public NetworkDetail(String bssid, ScanResult.InformationElement[] infoElements, 1225d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills List<String> anqpLines, int freq) { 12377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (infoElements == null) { 1245d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills throw new IllegalArgumentException("Null information elements"); 12577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 12677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1275bee0e4616e2f8025d60cbfe3eec3e274a68a452Jan Nordqvist mBSSID = Utils.parseMac(bssid); 12877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 12977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist String ssid = null; 13059f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne boolean isHiddenSsid = false; 13177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist byte[] ssidOctets = null; 13277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1335d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills InformationElementUtil.BssLoad bssLoad = new InformationElementUtil.BssLoad(); 13477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1355d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills InformationElementUtil.Interworking interworking = 1365d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills new InformationElementUtil.Interworking(); 13777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1385d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills InformationElementUtil.RoamingConsortium roamingConsortium = 1395d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills new InformationElementUtil.RoamingConsortium(); 14077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1415d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa(); 14277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1435d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills InformationElementUtil.HtOperation htOperation = new InformationElementUtil.HtOperation(); 1445d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills InformationElementUtil.VhtOperation vhtOperation = 1455d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills new InformationElementUtil.VhtOperation(); 1465d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills 1475d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills InformationElementUtil.ExtendedCapabilities extendedCapabilities = 1485d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills new InformationElementUtil.ExtendedCapabilities(); 149243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe 150947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne InformationElementUtil.TrafficIndicationMap trafficIndicationMap = 151947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne new InformationElementUtil.TrafficIndicationMap(); 152f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne 153f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne InformationElementUtil.SupportedRates supportedRates = 154f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne new InformationElementUtil.SupportedRates(); 155f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne InformationElementUtil.SupportedRates extendedSupportedRates = 156f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne new InformationElementUtil.SupportedRates(); 157f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne 158c1072acda7dc8b9d7bc4a9bb0b1177b14ecaf276xinhe RuntimeException exception = null; 159f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne 160f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne ArrayList<Integer> iesFound = new ArrayList<Integer>(); 161fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist try { 1625d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills for (ScanResult.InformationElement ie : infoElements) { 163f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne iesFound.add(ie.id); 1645d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills switch (ie.id) { 1655d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills case ScanResult.InformationElement.EID_SSID: 1665d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills ssidOctets = ie.bytes; 167fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 1685d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills case ScanResult.InformationElement.EID_BSS_LOAD: 1695d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills bssLoad.from(ie); 170fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 1715d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills case ScanResult.InformationElement.EID_HT_OPERATION: 1725d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills htOperation.from(ie); 173fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 1745d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills case ScanResult.InformationElement.EID_VHT_OPERATION: 1755d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills vhtOperation.from(ie); 176fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 1775d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills case ScanResult.InformationElement.EID_INTERWORKING: 1785d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills interworking.from(ie); 179fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 1805d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills case ScanResult.InformationElement.EID_ROAMING_CONSORTIUM: 1815d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills roamingConsortium.from(ie); 182fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 1835d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills case ScanResult.InformationElement.EID_VSA: 1845d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills vsa.from(ie); 185fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 1865d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills case ScanResult.InformationElement.EID_EXTENDED_CAPS: 1875d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills extendedCapabilities.from(ie); 188fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 189947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne case ScanResult.InformationElement.EID_TIM: 190947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne trafficIndicationMap.from(ie); 191947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne break; 192f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne case ScanResult.InformationElement.EID_SUPPORTED_RATES: 193f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne supportedRates.from(ie); 194f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne break; 195f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne case ScanResult.InformationElement.EID_EXTENDED_SUPPORTED_RATES: 196f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne extendedSupportedRates.from(ie); 197f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne break; 198fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist default: 199243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe break; 200fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 201fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 202fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 203be24c9af85b8a6e02b24582418a4608e14396f2aJan Nordqvist catch (IllegalArgumentException | BufferUnderflowException | ArrayIndexOutOfBoundsException e) { 2041c03d75c73b9f5fa24a795a0d546f4f56b82ab9bJan Nordqvist Log.d(Utils.hs2LogTag(getClass()), "Caught " + e); 205fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist if (ssidOctets == null) { 206d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist throw new IllegalArgumentException("Malformed IE string (no SSID)", e); 20777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 208a1edc185d46d85e04930a5e12b465de9fea64afeJan Nordqvist exception = e; 20977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 21077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (ssidOctets != null) { 211d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist /* 212d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist * Strict use of the "UTF-8 SSID" bit by APs appears to be spotty at best even if the 213d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist * encoding truly is in UTF-8. An unconditional attempt to decode the SSID as UTF-8 is 214d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist * therefore always made with a fall back to 8859-1 under normal circumstances. 215d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist * If, however, a previous exception was detected and the UTF-8 bit is set, failure to 216d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist * decode the SSID will be used as an indication that the whole frame is malformed and 217d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist * an exception will be triggered. 218d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist */ 219d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder(); 220d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist try { 221d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist CharBuffer decoded = decoder.decode(ByteBuffer.wrap(ssidOctets)); 222d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist ssid = decoded.toString(); 22377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 224d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist catch (CharacterCodingException cce) { 225d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist ssid = null; 22677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 227fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist 228d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist if (ssid == null) { 2295d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills if (extendedCapabilities.isStrictUtf8() && exception != null) { 230d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist throw new IllegalArgumentException("Failed to decode SSID in dubious IE string"); 231fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 232d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist else { 233d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist ssid = new String(ssidOctets, StandardCharsets.ISO_8859_1); 234fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 235fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 23659f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne isHiddenSsid = true; 23759f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne for (byte byteVal : ssidOctets) { 23859f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne if (byteVal != 0) { 23959f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne isHiddenSsid = false; 24059f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne break; 24159f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne } 24259f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne } 24377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 24477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 24577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mSSID = ssid; 2465d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mHESSID = interworking.hessid; 24759f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne mIsHiddenSsid = isHiddenSsid; 2485d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mStationCount = bssLoad.stationCount; 2495d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mChannelUtilization = bssLoad.channelUtilization; 2505d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mCapacity = bssLoad.capacity; 2515d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mAnt = interworking.ant; 2525d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mInternet = interworking.internet; 2535d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mHSRelease = vsa.hsRelease; 2545d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mAnqpDomainID = vsa.anqpDomainID; 2555d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mAnqpOICount = roamingConsortium.anqpOICount; 2562e889dc0b3f348f45cc5f5006d8784bed30583a9Masashi Honma mRoamingConsortiums = roamingConsortium.getRoamingConsortiums(); 25777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mExtendedCapabilities = extendedCapabilities; 25865d8ba5dd551cd132789e8feb270dfc7998dfbdcRoshan Pius mANQPElements = null; 259243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe //set up channel info 260243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mPrimaryFreq = freq; 261243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe 2625d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills if (vhtOperation.isValid()) { 263243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe // 80 or 160 MHz 2645d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mChannelWidth = vhtOperation.getChannelWidth(); 2655d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mCenterfreq0 = vhtOperation.getCenterFreq0(); 2665d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mCenterfreq1 = vhtOperation.getCenterFreq1(); 267243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } else { 2685d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mChannelWidth = htOperation.getChannelWidth(); 2695d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mCenterfreq0 = htOperation.getCenterFreq0(mPrimaryFreq); 2705d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mCenterfreq1 = 0; 271243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } 272947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne 273947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne // If trafficIndicationMap is not valid, mDtimPeriod will be negative 27459f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne if (trafficIndicationMap.isValid()) { 27559f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne mDtimInterval = trafficIndicationMap.mDtimPeriod; 27659f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne } 277947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne 278f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne int maxRateA = 0; 279f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne int maxRateB = 0; 280f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne // If we got some Extended supported rates, consider them, if not default to 0 281f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne if (extendedSupportedRates.isValid()) { 282f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne // rates are sorted from smallest to largest in InformationElement 283f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne maxRateB = extendedSupportedRates.mRates.get(extendedSupportedRates.mRates.size() - 1); 284f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne } 285f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne // Only process the determination logic if we got a 'SupportedRates' 286f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne if (supportedRates.isValid()) { 287f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne maxRateA = supportedRates.mRates.get(supportedRates.mRates.size() - 1); 288f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne mMaxRate = maxRateA > maxRateB ? maxRateA : maxRateB; 289f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne mWifiMode = InformationElementUtil.WifiMode.determineMode(mPrimaryFreq, mMaxRate, 290f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne vhtOperation.isValid(), 291f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne iesFound.contains(ScanResult.InformationElement.EID_HT_OPERATION), 292f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne iesFound.contains(ScanResult.InformationElement.EID_ERP)); 293f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne } else { 294f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne mWifiMode = 0; 295f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne mMaxRate = 0; 296f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne } 2978f14e9784bd8ca8e832fff86597a28755f7e668eSamuel Tan if (DBG) { 298f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne Log.d(TAG, mSSID + "ChannelWidth is: " + mChannelWidth + " PrimaryFreq: " + mPrimaryFreq 299f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne + " mCenterfreq0: " + mCenterfreq0 + " mCenterfreq1: " + mCenterfreq1 300b86089a48fae8878b5a27533a116c97b0be6d0e7Peter Qiu + (extendedCapabilities.is80211McRTTResponder() ? "Support RTT responder" 301f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne : "Do not support RTT responder")); 302f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne Log.v("WifiMode", mSSID 303f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne + ", WifiMode: " + InformationElementUtil.WifiMode.toString(mWifiMode) 304f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne + ", Freq: " + mPrimaryFreq 305f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne + ", mMaxRate: " + mMaxRate 306f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne + ", VHT: " + String.valueOf(vhtOperation.isValid()) 307f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne + ", HT: " + String.valueOf( 308f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne iesFound.contains(ScanResult.InformationElement.EID_HT_OPERATION)) 309f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne + ", ERP: " + String.valueOf( 310f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne iesFound.contains(ScanResult.InformationElement.EID_ERP)) 311f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne + ", SupportedRates: " + supportedRates.toString() 312f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne + " ExtendedSupportedRates: " + extendedSupportedRates.toString()); 313d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande } 31477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 31577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 316fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist private static ByteBuffer getAndAdvancePayload(ByteBuffer data, int plLength) { 317398823d45a240ff90ff2ffab3ff4a8b8646f24c9Jan Nordqvist ByteBuffer payload = data.duplicate().order(data.order()); 318fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist payload.limit(payload.position() + plLength); 319fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist data.position(data.position() + plLength); 320fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist return payload; 321fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 322fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist 32377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private NetworkDetail(NetworkDetail base, Map<Constants.ANQPElementType, ANQPElement> anqpElements) { 32477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mSSID = base.mSSID; 32559f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne mIsHiddenSsid = base.mIsHiddenSsid; 32677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mBSSID = base.mBSSID; 32777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mHESSID = base.mHESSID; 32877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mStationCount = base.mStationCount; 32977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mChannelUtilization = base.mChannelUtilization; 33077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mCapacity = base.mCapacity; 33177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mAnt = base.mAnt; 33277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mInternet = base.mInternet; 33377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mHSRelease = base.mHSRelease; 33477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mAnqpDomainID = base.mAnqpDomainID; 33577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mAnqpOICount = base.mAnqpOICount; 33677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mRoamingConsortiums = base.mRoamingConsortiums; 3375d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills mExtendedCapabilities = 3385d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills new InformationElementUtil.ExtendedCapabilities(base.mExtendedCapabilities); 33977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mANQPElements = anqpElements; 340243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mChannelWidth = base.mChannelWidth; 341243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mPrimaryFreq = base.mPrimaryFreq; 342243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mCenterfreq0 = base.mCenterfreq0; 343243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mCenterfreq1 = base.mCenterfreq1; 344947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne mDtimInterval = base.mDtimInterval; 345f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne mWifiMode = base.mWifiMode; 346f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne mMaxRate = base.mMaxRate; 34777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 34877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 34977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public NetworkDetail complete(Map<Constants.ANQPElementType, ANQPElement> anqpElements) { 35077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return new NetworkDetail(this, anqpElements); 35177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 35277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 3531d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist public boolean queriable(List<Constants.ANQPElementType> queryElements) { 3541d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist return mAnt != null && 3551d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist (Constants.hasBaseANQPElements(queryElements) || 3561d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist Constants.hasR2Elements(queryElements) && mHSRelease == HSRelease.R2); 35777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 35877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 35977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public boolean has80211uInfo() { 36077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mAnt != null || mRoamingConsortiums != null || mHSRelease != null; 36177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 36277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 36377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public boolean hasInterworking() { 36477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mAnt != null; 36577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 36677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 36777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public String getSSID() { 36877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mSSID; 36977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 37077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 3719a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist public String getTrimmedSSID() { 372c5d349d814e5eeb72beb62d722699a9624fb9932Julia Reynolds if (mSSID != null) { 373c5d349d814e5eeb72beb62d722699a9624fb9932Julia Reynolds for (int n = 0; n < mSSID.length(); n++) { 374c5d349d814e5eeb72beb62d722699a9624fb9932Julia Reynolds if (mSSID.charAt(n) != 0) { 375c5d349d814e5eeb72beb62d722699a9624fb9932Julia Reynolds return mSSID; 376c5d349d814e5eeb72beb62d722699a9624fb9932Julia Reynolds } 3779a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist } 3789a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist } 3799a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist return ""; 3809a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist } 3819a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist 38277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public long getHESSID() { 38377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mHESSID; 38477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 38577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 38677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public long getBSSID() { 38777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mBSSID; 38877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 38977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 39077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public int getStationCount() { 39177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mStationCount; 39277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 39377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 39477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public int getChannelUtilization() { 39577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mChannelUtilization; 39677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 39777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 39877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public int getCapacity() { 39977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mCapacity; 40077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 40177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 40277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public boolean isInterworking() { 40377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mAnt != null; 40477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 40577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 40677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public Ant getAnt() { 40777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mAnt; 40877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 40977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 41077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public boolean isInternet() { 41177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mInternet; 41277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 41377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 41477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public HSRelease getHSRelease() { 41577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mHSRelease; 41677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 41777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 41877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public int getAnqpDomainID() { 41977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mAnqpDomainID; 42077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 42177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 4222e814680f4dd27a5f825afab189843582235cedcJan Nordqvist public byte[] getOsuProviders() { 4232e814680f4dd27a5f825afab189843582235cedcJan Nordqvist if (mANQPElements == null) { 4242e814680f4dd27a5f825afab189843582235cedcJan Nordqvist return null; 4252e814680f4dd27a5f825afab189843582235cedcJan Nordqvist } 4262e814680f4dd27a5f825afab189843582235cedcJan Nordqvist ANQPElement osuProviders = mANQPElements.get(Constants.ANQPElementType.HSOSUProviders); 4272e814680f4dd27a5f825afab189843582235cedcJan Nordqvist return osuProviders != null ? ((RawByteElement) osuProviders).getPayload() : null; 4282e814680f4dd27a5f825afab189843582235cedcJan Nordqvist } 4292e814680f4dd27a5f825afab189843582235cedcJan Nordqvist 43077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public int getAnqpOICount() { 43177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mAnqpOICount; 43277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 43377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 43477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public long[] getRoamingConsortiums() { 43577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mRoamingConsortiums; 43677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 43777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 43877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public Map<Constants.ANQPElementType, ANQPElement> getANQPElements() { 43977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mANQPElements; 44077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 44177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 442243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe public int getChannelWidth() { 443243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe return mChannelWidth; 444243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } 445243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe 446243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe public int getCenterfreq0() { 447243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe return mCenterfreq0; 448243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } 449243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe 450243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe public int getCenterfreq1() { 451243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe return mCenterfreq1; 452243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } 453243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe 454f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne public int getWifiMode() { 455f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne return mWifiMode; 456f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne } 457f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne 458947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne public int getDtimInterval() { 459947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne return mDtimInterval; 460947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne } 461947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne 462243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe public boolean is80211McResponderSupport() { 463b86089a48fae8878b5a27533a116c97b0be6d0e7Peter Qiu return mExtendedCapabilities.is80211McRTTResponder(); 464243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } 465243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe 46677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public boolean isSSID_UTF8() { 4675d31cedf4024e0f038b4dfc2081016c8631ee8feMitchell Wills return mExtendedCapabilities.isStrictUtf8(); 46877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 46977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 47077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist @Override 47177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public boolean equals(Object thatObject) { 47277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (this == thatObject) { 47377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return true; 47477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 47577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (thatObject == null || getClass() != thatObject.getClass()) { 47677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return false; 47777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 47877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 47977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist NetworkDetail that = (NetworkDetail)thatObject; 48077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 48177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return getSSID().equals(that.getSSID()) && getBSSID() == that.getBSSID(); 48277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 48377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 48477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist @Override 48577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public int hashCode() { 48677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return ((mSSID.hashCode() * 31) + (int)(mBSSID >>> 32)) * 31 + (int)mBSSID; 48777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 48877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 48977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist @Override 49077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public String toString() { 4911d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist return String.format("NetworkInfo{SSID='%s', HESSID=%x, BSSID=%x, StationCount=%d, " + 4921d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist "ChannelUtilization=%d, Capacity=%d, Ant=%s, Internet=%s, " + 493e7399556522efdd3f137aba31c49cbb8d95c59d6Samuel Tan "HSRelease=%s, AnqpDomainID=%d, " + 4941d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist "AnqpOICount=%d, RoamingConsortiums=%s}", 49577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mSSID, mHESSID, mBSSID, mStationCount, 49677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mChannelUtilization, mCapacity, mAnt, mInternet, 497e7399556522efdd3f137aba31c49cbb8d95c59d6Samuel Tan mHSRelease, mAnqpDomainID, 49877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mAnqpOICount, Utils.roamingConsortiumsToString(mRoamingConsortiums)); 49977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 50077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 50177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public String toKeyString() { 502a1edc185d46d85e04930a5e12b465de9fea64afeJan Nordqvist return mHESSID != 0 ? 503866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist String.format("'%s':%012x (%012x)", mSSID, mBSSID, mHESSID) : 504866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist String.format("'%s':%012x", mSSID, mBSSID); 50577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 50677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 50777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public String getBSSIDString() { 50877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return toMACString(mBSSID); 50977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 51077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 51159f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne /** 51259f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne * Evaluates the ScanResult this NetworkDetail is built from 51359f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne * returns true if built from a Beacon Frame 51459f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne * returns false if built from a Probe Response 51559f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne */ 51659f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne public boolean isBeaconFrame() { 51759f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne // Beacon frames have a 'Traffic Indication Map' Information element 51859f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne // Probe Responses do not. This is indicated by a DTIM period > 0 51959f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne return mDtimInterval > 0; 52059f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne } 52159f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne 52259f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne /** 52359f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne * Evaluates the ScanResult this NetworkDetail is built from 52459f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne * returns true if built from a hidden Beacon Frame 52559f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne * returns false if not hidden or not a Beacon 52659f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne */ 52759f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne public boolean isHiddenBeaconFrame() { 52859f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne // Hidden networks are not 80211 standard, but it is common for a hidden network beacon 52959f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne // frame to either send zero-value bytes as the SSID, or to send no bytes at all. 53059f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne return isBeaconFrame() && mIsHiddenSsid; 53159f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne } 53259f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne 533ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist public static String toMACString(long mac) { 53477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist StringBuilder sb = new StringBuilder(); 53577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist boolean first = true; 53677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist for (int n = BYTES_IN_EUI48 - 1; n >= 0; n--) { 53777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (first) { 53877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist first = false; 53977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } else { 54077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist sb.append(':'); 54177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 54277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist sb.append(String.format("%02x", (mac >>> (n * Byte.SIZE)) & BYTE_MASK)); 54377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 54477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return sb.toString(); 54577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 54677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist} 547