NetworkDetail.java revision 5bee0e4616e2f8025d60cbfe3eec3e274a68a452
177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistpackage com.android.server.wifi.hotspot2; 277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport android.net.wifi.ScanResult; 473185809f4a44a8ee272afe3e5253496aeb966ceLorenzo Colittiimport android.util.Log; 577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport com.android.server.wifi.anqp.ANQPElement; 777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport com.android.server.wifi.anqp.Constants; 877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport com.android.server.wifi.anqp.VenueNameElement; 977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.net.ProtocolException; 11a1edc185d46d85e04930a5e12b465de9fea64afeJan Nordqvistimport java.nio.BufferUnderflowException; 1277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.nio.ByteBuffer; 1377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.nio.ByteOrder; 14fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvistimport java.nio.CharBuffer; 15fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvistimport java.nio.charset.CharacterCodingException; 16fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvistimport java.nio.charset.CharsetDecoder; 1777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.nio.charset.StandardCharsets; 1877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.util.List; 1977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport java.util.Map; 2077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 2177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport static com.android.server.wifi.anqp.Constants.BYTES_IN_EUI48; 2277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport static com.android.server.wifi.anqp.Constants.BYTE_MASK; 2377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistimport static com.android.server.wifi.anqp.Constants.getInteger; 2473185809f4a44a8ee272afe3e5253496aeb966ceLorenzo Colitti 2577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvistpublic class NetworkDetail { 2677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 2777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private static final int EID_SSID = 0; 2877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private static final int EID_BSSLoad = 11; 29243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe private static final int EID_HT_OPERATION = 61; 30243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe private static final int EID_VHT_OPERATION = 192; 3177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private static final int EID_Interworking = 107; 3277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private static final int EID_RoamingConsortium = 111; 3377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private static final int EID_ExtendedCaps = 127; 3477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private static final int EID_VSA = 221; 35fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist 3677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private static final int ANQP_DOMID_BIT = 0x04; 37243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe private static final int RTT_RESP_ENABLE_BIT = 70; 3877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 3977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private static final long SSID_UTF8_BIT = 0x0001000000000000L; 40243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe //turn off when SHIP 41243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe private static final boolean DBG = true; 42d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande private static final boolean VDBG = false; 43d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande 44d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande private static final String TAG = "NetworkDetail:"; 4577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 4677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public enum Ant { 4777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Private, 4877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist PrivateWithGuest, 4977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist ChargeablePublic, 5077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist FreePublic, 5177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Personal, 5277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist EmergencyOnly, 5377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd6, 5477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd7, 5577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd8, 5677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd9, 5777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd10, 5877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd11, 5977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd12, 6077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Resvd13, 6177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist TestOrExperimental, 6277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Wildcard 6377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 6477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 6577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public enum HSRelease { 6677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist R1, 6777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist R2, 6877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Unknown 6977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 7077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 7177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // General identifiers: 7277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final String mSSID; 7377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final long mHESSID; 7477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final long mBSSID; 7577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 7677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist // BSS Load element: 7777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final int mStationCount; 7877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final int mChannelUtilization; 7977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final int mCapacity; 8077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 81243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe //channel detailed information 82243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe /* 83243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe * 0 -- 20 MHz 84243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe * 1 -- 40 MHz 85243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe * 2 -- 80 MHz 86243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe * 3 -- 160 MHz 87243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe * 4 -- 80 + 80 MHz 88243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe */ 89243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe private final int mChannelWidth; 90243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe private final int mPrimaryFreq; 91243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe private final int mCenterfreq0; 92243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe private final int mCenterfreq1; 93243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe private final boolean m80211McRTTResponder; 9477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist /* 9577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * From Interworking element: 9677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * mAnt non null indicates the presence of Interworking, i.e. 802.11u 9777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * mVenueGroup and mVenueType may be null if not present in the Interworking element. 9877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist */ 9977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final Ant mAnt; 10077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final boolean mInternet; 10177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final VenueNameElement.VenueGroup mVenueGroup; 10277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final VenueNameElement.VenueType mVenueType; 10377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 10477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist /* 10577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * From HS20 Indication element: 10677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * mHSRelease is null only if the HS20 Indication element was not present. 10777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * mAnqpDomainID is set to -1 if not present in the element. 10877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist */ 10977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final HSRelease mHSRelease; 11077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final int mAnqpDomainID; 11177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 11277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist /* 11377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * From beacon: 11477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * mAnqpOICount is how many additional OIs are available through ANQP. 11577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * mRoamingConsortiums is either null, if the element was not present, or is an array of 11677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist * 1, 2 or 3 longs in which the roaming consortium values occupy the LSBs. 11777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist */ 11877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final int mAnqpOICount; 11977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final long[] mRoamingConsortiums; 12077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 12177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final Long mExtendedCapabilities; 12277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 12377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private final Map<Constants.ANQPElementType, ANQPElement> mANQPElements; 12477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 125243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe public NetworkDetail(String bssid, String infoElements, List<String> anqpLines, int freq) { 12677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 12777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (infoElements == null) { 12877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist throw new IllegalArgumentException("Null information element string"); 12977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 13077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist int separator = infoElements.indexOf('='); 13177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (separator<0) { 13277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist throw new IllegalArgumentException("No element separator"); 13377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 13477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1355bee0e4616e2f8025d60cbfe3eec3e274a68a452Jan Nordqvist mBSSID = Utils.parseMac(bssid); 13677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 13777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist ByteBuffer data = ByteBuffer.wrap(Utils.hexToBytes(infoElements.substring(separator + 1))) 13877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist .order(ByteOrder.LITTLE_ENDIAN); 13977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 14077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist String ssid = null; 14177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist byte[] ssidOctets = null; 14277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist int stationCount = 0; 14377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist int channelUtilization = 0; 14477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist int capacity = 0; 14577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 14677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Ant ant = null; 14777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist boolean internet = false; 14877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist VenueNameElement.VenueGroup venueGroup = null; 14977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist VenueNameElement.VenueType venueType = null; 15077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist long hessid = 0L; 15177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 15277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist int anqpOICount = 0; 15377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist long[] roamingConsortiums = null; 15477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 15577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist HSRelease hsRelease = null; 156ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist int anqpDomainID = 0; // No domain ID treated the same as a 0; unique info per AP. 15777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 15877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Long extendedCapabilities = null; 15977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 160243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe int secondChanelOffset = 0; 161243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe int channelMode = 0; 162243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe int centerFreqIndex1 = 0; 163243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe int centerFreqIndex2 = 0; 164243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe boolean RTTResponder = false; 165243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe 166fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist RuntimeException exception = null; 167207af567531a0813a9c8651d28bc4bda0ea22088xinhe 168fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist try { 169fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist while (data.hasRemaining()) { 170fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist int eid = data.get() & Constants.BYTE_MASK; 171fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist int elementLength = data.get() & Constants.BYTE_MASK; 172fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist 173fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist if (elementLength > data.remaining()) { 174fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist throw new IllegalArgumentException("Element length " + elementLength + 175fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist " exceeds payload length " + data.remaining() + 176fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist " @ " + data.position()); 177fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 178fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist 179fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist ByteBuffer element; 18077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 181fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist switch (eid) { 182fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist case EID_SSID: 183fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist ssidOctets = new byte[elementLength]; 184fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist data.get(ssidOctets); 185fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 186fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist case EID_BSSLoad: 187fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist if (elementLength != 5) { 188fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist throw new IllegalArgumentException("BSS Load element length is not 5: " + 189fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist elementLength); 190fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 191fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist stationCount = data.getShort() & Constants.SHORT_MASK; 192fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist channelUtilization = data.get() & Constants.BYTE_MASK; 193fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist capacity = data.getShort() & Constants.SHORT_MASK; 194fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 195fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist case EID_HT_OPERATION: 196fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist element = getAndAdvancePayload(data, elementLength); 197fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist int primary_channel = element.get(); 198fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist secondChanelOffset = element.get() & 0x3; 199fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 200fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist case EID_VHT_OPERATION: 201fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist element = getAndAdvancePayload(data, elementLength); 202fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist channelMode = element.get() & Constants.BYTE_MASK; 203fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist centerFreqIndex1 = element.get() & Constants.BYTE_MASK; 204fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist centerFreqIndex2 = element.get() & Constants.BYTE_MASK; 205fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 206fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist case EID_Interworking: 207fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist int anOptions = data.get() & Constants.BYTE_MASK; 208fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist ant = Ant.values()[anOptions & 0x0f]; 209fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist internet = (anOptions & 0x10) != 0; 210fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist // Len 1 none, 3 venue-info, 7 HESSID, 9 venue-info & HESSID 211fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist if (elementLength == 3 || elementLength == 9) { 212fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist try { 213fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist ByteBuffer vinfo = data.duplicate(); 214fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist vinfo.limit(vinfo.position() + 2); 215fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist VenueNameElement vne = 216fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist new VenueNameElement(Constants.ANQPElementType.ANQPVenueName, 217fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist vinfo); 218fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist venueGroup = vne.getGroup(); 219fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist venueType = vne.getType(); 220fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist data.getShort(); 221fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } catch (ProtocolException pe) { 222fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist /*Cannot happen*/ 223fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 224fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } else if (elementLength != 1 && elementLength != 7) { 225fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist throw new IllegalArgumentException("Bad Interworking element length: " + 226fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist elementLength); 22777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 228fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist if (elementLength == 7 || elementLength == 9) { 229fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist hessid = getInteger(data, ByteOrder.BIG_ENDIAN, 6); 23077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 231fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 232fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist case EID_RoamingConsortium: 233fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist anqpOICount = data.get() & Constants.BYTE_MASK; 234fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist 235fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist int oi12Length = data.get() & Constants.BYTE_MASK; 236fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist int oi1Length = oi12Length & Constants.NIBBLE_MASK; 237fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist int oi2Length = (oi12Length >>> 4) & Constants.NIBBLE_MASK; 238fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist int oi3Length = elementLength - 2 - oi1Length - oi2Length; 239fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist int oiCount = 0; 240fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist if (oi1Length > 0) { 24177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist oiCount++; 242fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist if (oi2Length > 0) { 24377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist oiCount++; 244fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist if (oi3Length > 0) { 245fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist oiCount++; 246fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 24777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 24877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 249fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist roamingConsortiums = new long[oiCount]; 250fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist if (oi1Length > 0) { 251fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist roamingConsortiums[0] = 252fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist getInteger(data, ByteOrder.BIG_ENDIAN, oi1Length); 253fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 254fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist if (oi2Length > 0) { 255fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist roamingConsortiums[1] = 256fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist getInteger(data, ByteOrder.BIG_ENDIAN, oi2Length); 257fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 258fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist if (oi3Length > 0) { 259fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist roamingConsortiums[2] = 260fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist getInteger(data, ByteOrder.BIG_ENDIAN, oi3Length); 261fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 262fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 263fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist case EID_VSA: 264fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist element = getAndAdvancePayload(data, elementLength); 265fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist if (elementLength >= 5 && element.getInt() == Constants.HS20_FRAME_PREFIX) { 266fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist int hsConf = element.get() & Constants.BYTE_MASK; 267fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist switch ((hsConf >> 4) & Constants.NIBBLE_MASK) { 268fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist case 0: 269fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist hsRelease = HSRelease.R1; 270fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 271fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist case 1: 272fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist hsRelease = HSRelease.R2; 273fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 274fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist default: 275fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist hsRelease = HSRelease.Unknown; 276fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 277fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 278fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist if ((hsConf & ANQP_DOMID_BIT) != 0) { 279fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist if (elementLength < 7) { 280fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist throw new IllegalArgumentException( 281fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist "HS20 indication element too short: " + elementLength); 282fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 283fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist anqpDomainID = element.getShort() & Constants.SHORT_MASK; 284fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 28577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 286fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 287fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist case EID_ExtendedCaps: 288398823d45a240ff90ff2ffab3ff4a8b8646f24c9Jan Nordqvist element = data.duplicate(); 289fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist extendedCapabilities = 290fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist Constants.getInteger(data, ByteOrder.LITTLE_ENDIAN, elementLength); 291fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist 292fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist int index = RTT_RESP_ENABLE_BIT / 8; 293fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist byte offset = RTT_RESP_ENABLE_BIT % 8; 294fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist 295fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist if (elementLength < index + 1) { 296fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist RTTResponder = false; 297fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist element.position(element.position() + elementLength); 298fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 29977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 300fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist 301fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist element.position(element.position() + index); 302fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist 303fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist RTTResponder = (element.get() & (0x1 << offset)) != 0; 304fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist break; 305fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist default: 306243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe data.position(data.position() + elementLength); 307243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe break; 308fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 309fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 310fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 311a1edc185d46d85e04930a5e12b465de9fea64afeJan Nordqvist catch (IllegalArgumentException | BufferUnderflowException e) { 3121c03d75c73b9f5fa24a795a0d546f4f56b82ab9bJan Nordqvist Log.d(Utils.hs2LogTag(getClass()), "Caught " + e); 313fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist if (ssidOctets == null) { 314d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist throw new IllegalArgumentException("Malformed IE string (no SSID)", e); 31577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 316a1edc185d46d85e04930a5e12b465de9fea64afeJan Nordqvist exception = e; 31777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 31877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 31977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (ssidOctets != null) { 320d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist boolean strictUTF8 = extendedCapabilities != null && 321d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist ( extendedCapabilities & SSID_UTF8_BIT ) != 0; 322d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist 323d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist /* 324d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist * Strict use of the "UTF-8 SSID" bit by APs appears to be spotty at best even if the 325d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist * encoding truly is in UTF-8. An unconditional attempt to decode the SSID as UTF-8 is 326d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist * therefore always made with a fall back to 8859-1 under normal circumstances. 327d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist * If, however, a previous exception was detected and the UTF-8 bit is set, failure to 328d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist * decode the SSID will be used as an indication that the whole frame is malformed and 329d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist * an exception will be triggered. 330d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist */ 331d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder(); 332d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist try { 333d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist CharBuffer decoded = decoder.decode(ByteBuffer.wrap(ssidOctets)); 334d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist ssid = decoded.toString(); 33577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 336d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist catch (CharacterCodingException cce) { 337d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist ssid = null; 33877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 339fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist 340d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist if (ssid == null) { 341d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist if (strictUTF8 && exception != null) { 342d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist throw new IllegalArgumentException("Failed to decode SSID in dubious IE string"); 343fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 344d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist else { 345d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist ssid = new String(ssidOctets, StandardCharsets.ISO_8859_1); 346fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 347fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 34877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 34977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 35077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mSSID = ssid; 35177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mHESSID = hessid; 35277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mStationCount = stationCount; 35377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mChannelUtilization = channelUtilization; 35477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mCapacity = capacity; 35577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mAnt = ant; 35677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mInternet = internet; 35777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mVenueGroup = venueGroup; 35877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mVenueType = venueType; 35977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mHSRelease = hsRelease; 36077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mAnqpDomainID = anqpDomainID; 36177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mAnqpOICount = anqpOICount; 36277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mRoamingConsortiums = roamingConsortiums; 36377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mExtendedCapabilities = extendedCapabilities; 36477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mANQPElements = SupplicantBridge.parseANQPLines(anqpLines); 365243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe //set up channel info 366243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mPrimaryFreq = freq; 367243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe 368243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe if (channelMode != 0) { 369243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe // 80 or 160 MHz 370243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mChannelWidth = channelMode + 1; 371243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mCenterfreq0 = (centerFreqIndex1 - 36) * 5 + 5180; 372243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe if(channelMode > 1) { //160MHz 373243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mCenterfreq1 = (centerFreqIndex2 - 36) * 5 + 5180; 374243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } else { 375243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mCenterfreq1 = 0; 376243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } 377243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } else { 378243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe //20 or 40 MHz 379243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe if (secondChanelOffset != 0) {//40MHz 380243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mChannelWidth = 1; 381243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe if (secondChanelOffset == 1) { 382243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mCenterfreq0 = mPrimaryFreq + 20; 383243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } else if (secondChanelOffset == 3) { 384243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mCenterfreq0 = mPrimaryFreq - 20; 385243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } else { 386243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mCenterfreq0 = 0; 387243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe Log.e(TAG,"Error on secondChanelOffset"); 388243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } 389243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } else { 390243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mCenterfreq0 = 0; 391243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mChannelWidth = 0; 392243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } 393243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mCenterfreq1 = 0; 394243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } 395243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe m80211McRTTResponder = RTTResponder; 396d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande if (VDBG) { 397d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande Log.d(TAG, mSSID + "ChannelWidth is: " + mChannelWidth + " PrimaryFreq: " + mPrimaryFreq + 398d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande " mCenterfreq0: " + mCenterfreq0 + " mCenterfreq1: " + mCenterfreq1 + 399d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande (m80211McRTTResponder ? "Support RTT reponder" : "Do not support RTT responder")); 400d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande } 40177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 40277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 403fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist private static ByteBuffer getAndAdvancePayload(ByteBuffer data, int plLength) { 404398823d45a240ff90ff2ffab3ff4a8b8646f24c9Jan Nordqvist ByteBuffer payload = data.duplicate().order(data.order()); 405fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist payload.limit(payload.position() + plLength); 406fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist data.position(data.position() + plLength); 407fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist return payload; 408fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist } 409fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist 41077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private NetworkDetail(NetworkDetail base, Map<Constants.ANQPElementType, ANQPElement> anqpElements) { 41177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mSSID = base.mSSID; 41277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mBSSID = base.mBSSID; 41377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mHESSID = base.mHESSID; 41477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mStationCount = base.mStationCount; 41577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mChannelUtilization = base.mChannelUtilization; 41677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mCapacity = base.mCapacity; 41777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mAnt = base.mAnt; 41877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mInternet = base.mInternet; 41977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mVenueGroup = base.mVenueGroup; 42077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mVenueType = base.mVenueType; 42177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mHSRelease = base.mHSRelease; 42277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mAnqpDomainID = base.mAnqpDomainID; 42377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mAnqpOICount = base.mAnqpOICount; 42477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mRoamingConsortiums = base.mRoamingConsortiums; 42577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mExtendedCapabilities = base.mExtendedCapabilities; 42677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mANQPElements = anqpElements; 427243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mChannelWidth = base.mChannelWidth; 428243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mPrimaryFreq = base.mPrimaryFreq; 429243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mCenterfreq0 = base.mCenterfreq0; 430243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe mCenterfreq1 = base.mCenterfreq1; 431243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe m80211McRTTResponder = base.m80211McRTTResponder; 43277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 43377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 43477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public NetworkDetail complete(Map<Constants.ANQPElementType, ANQPElement> anqpElements) { 43577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return new NetworkDetail(this, anqpElements); 43677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 43777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 43877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public boolean hasInterworking() { 43977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mAnt != null; 44077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 44177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 44277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public String getSSID() { 44377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mSSID; 44477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 44577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 4469a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist public String getTrimmedSSID() { 4479a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist for (int n = 0; n < mSSID.length(); n++) { 4489a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist if (mSSID.charAt(n) != 0) { 4499a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist return mSSID; 4509a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist } 4519a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist } 4529a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist return ""; 4539a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist } 4549a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist 45577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public long getHESSID() { 45677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mHESSID; 45777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 45877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 45977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public long getBSSID() { 46077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mBSSID; 46177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 46277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 46377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public int getStationCount() { 46477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mStationCount; 46577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 46677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 46777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public int getChannelUtilization() { 46877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mChannelUtilization; 46977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 47077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 47177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public int getCapacity() { 47277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mCapacity; 47377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 47477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 47577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public boolean isInterworking() { 47677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mAnt != null; 47777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 47877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 47977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public Ant getAnt() { 48077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mAnt; 48177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 48277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 48377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public boolean isInternet() { 48477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mInternet; 48577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 48677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 48777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public VenueNameElement.VenueGroup getVenueGroup() { 48877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mVenueGroup; 48977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 49077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 49177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public VenueNameElement.VenueType getVenueType() { 49277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mVenueType; 49377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 49477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 49577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public HSRelease getHSRelease() { 49677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mHSRelease; 49777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 49877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 49977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public int getAnqpDomainID() { 50077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mAnqpDomainID; 50177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 50277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 50377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public int getAnqpOICount() { 50477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mAnqpOICount; 50577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 50677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 50777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public long[] getRoamingConsortiums() { 50877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mRoamingConsortiums; 50977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 51077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 51177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public Long getExtendedCapabilities() { 51277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mExtendedCapabilities; 51377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 51477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 51577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public Map<Constants.ANQPElementType, ANQPElement> getANQPElements() { 51677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mANQPElements; 51777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 51877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 519243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe public int getChannelWidth() { 520243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe return mChannelWidth; 521243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } 522243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe 523243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe public int getCenterfreq0() { 524243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe return mCenterfreq0; 525243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } 526243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe 527243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe public int getCenterfreq1() { 528243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe return mCenterfreq1; 529243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } 530243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe 531243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe public boolean is80211McResponderSupport() { 532243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe return m80211McRTTResponder; 533243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe } 534243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe 53577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public boolean isSSID_UTF8() { 53677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return mExtendedCapabilities != null && (mExtendedCapabilities & SSID_UTF8_BIT) != 0; 53777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 53877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 53977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist @Override 54077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public boolean equals(Object thatObject) { 54177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (this == thatObject) { 54277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return true; 54377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 54477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (thatObject == null || getClass() != thatObject.getClass()) { 54577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return false; 54677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 54777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 54877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist NetworkDetail that = (NetworkDetail)thatObject; 54977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 55077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return getSSID().equals(that.getSSID()) && getBSSID() == that.getBSSID(); 55177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 55277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 55377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist @Override 55477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public int hashCode() { 55577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return ((mSSID.hashCode() * 31) + (int)(mBSSID >>> 32)) * 31 + (int)mBSSID; 55677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 55777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 55877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist @Override 55977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public String toString() { 56077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return String.format("NetworkInfo{mSSID='%s', mHESSID=%x, mBSSID=%x, mStationCount=%d, " + 56177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist "mChannelUtilization=%d, mCapacity=%d, mAnt=%s, mInternet=%s, " + 56277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist "mVenueGroup=%s, mVenueType=%s, mHSRelease=%s, mAnqpDomainID=%d, " + 56377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist "mAnqpOICount=%d, mRoamingConsortiums=%s}", 56477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mSSID, mHESSID, mBSSID, mStationCount, 56577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mChannelUtilization, mCapacity, mAnt, mInternet, 56677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mVenueGroup, mVenueType, mHSRelease, mAnqpDomainID, 56777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist mAnqpOICount, Utils.roamingConsortiumsToString(mRoamingConsortiums)); 56877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 56977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 57077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public String toKeyString() { 571a1edc185d46d85e04930a5e12b465de9fea64afeJan Nordqvist return mHESSID != 0 ? 572a1edc185d46d85e04930a5e12b465de9fea64afeJan Nordqvist String.format("'%s':%s (%012x)", mSSID, getBSSIDString(), mHESSID) : 573a1edc185d46d85e04930a5e12b465de9fea64afeJan Nordqvist String.format("'%s':%s", mSSID, getBSSIDString()); 57477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 57577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 57677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public String getBSSIDString() { 57777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return toMACString(mBSSID); 57877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 57977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 580ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist public static String toMACString(long mac) { 58177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist StringBuilder sb = new StringBuilder(); 58277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist boolean first = true; 58377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist for (int n = BYTES_IN_EUI48 - 1; n >= 0; n--) { 58477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (first) { 58577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist first = false; 58677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } else { 58777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist sb.append(':'); 58877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 58977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist sb.append(String.format("%02x", (mac >>> (n * Byte.SIZE)) & BYTE_MASK)); 59077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 59177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return sb.toString(); 59277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 59377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 59477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private static final String IE = "ie=" + 59577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist "000477696e67" + // SSID wing 59677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist "0b052a00cf611e" + // BSS Load 42:207:7777 59777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist "6b091e0a01610408621205" + // internet:Experimental:Vehicular:Auto:hessid 59877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist "6f0a0e530111112222222229" + // 14:111111:2222222229 59977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist "dd07506f9a10143a01"; // r2:314 60077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 60177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist private static final String IE2 = "ie=000f4578616d706c65204e6574776f726b010882848b960c1218240301012a010432043048606c30140100000fac040100000fac040100000fac0100007f04000000806b091e07010203040506076c027f006f1001531122331020304050010203040506dd05506f9a1000"; 60277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 60377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public static void main(String[] args) { 60477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist ScanResult scanResult = new ScanResult(); 60577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist scanResult.SSID = "wing"; 60677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist scanResult.BSSID = "610408"; 607243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe NetworkDetail nwkDetail = new NetworkDetail(scanResult.BSSID, IE2, null, 0); 60877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist System.out.println(nwkDetail); 60977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 61077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist} 611