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
44243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe    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
166c1072acda7dc8b9d7bc4a9bb0b1177b14ecaf276xinhe        RuntimeException exception = null;
167f9f7c4ceed78d380a78c2d79a2af3d0cf473e065Prerepa Viswanadham
168fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist        try {
169be24c9af85b8a6e02b24582418a4608e14396f2aJan Nordqvist            while (data.remaining() > 1) {
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                }
178be24c9af85b8a6e02b24582418a4608e14396f2aJan Nordqvist                if (eid == 0 && elementLength == 0 && ssidOctets != null) {
179be24c9af85b8a6e02b24582418a4608e14396f2aJan Nordqvist                    // Don't overwrite SSID (eid 0) with trailing zero garbage
180be24c9af85b8a6e02b24582418a4608e14396f2aJan Nordqvist                    continue;
181be24c9af85b8a6e02b24582418a4608e14396f2aJan Nordqvist                }
182fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist
183fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                ByteBuffer element;
18477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
185fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                switch (eid) {
186fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                    case EID_SSID:
187fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        ssidOctets = new byte[elementLength];
188fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        data.get(ssidOctets);
189fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        break;
190fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                    case EID_BSSLoad:
191fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        if (elementLength != 5) {
192fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                            throw new IllegalArgumentException("BSS Load element length is not 5: " +
193fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                    elementLength);
194fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        }
195fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        stationCount = data.getShort() & Constants.SHORT_MASK;
196fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        channelUtilization = data.get() & Constants.BYTE_MASK;
197fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        capacity = data.getShort() & Constants.SHORT_MASK;
198fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        break;
199fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                    case EID_HT_OPERATION:
200fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        element = getAndAdvancePayload(data, elementLength);
201fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        int primary_channel = element.get();
202fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        secondChanelOffset = element.get() & 0x3;
203fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        break;
204fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                    case EID_VHT_OPERATION:
205fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        element = getAndAdvancePayload(data, elementLength);
206fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        channelMode = element.get() & Constants.BYTE_MASK;
207fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        centerFreqIndex1 = element.get() & Constants.BYTE_MASK;
208fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        centerFreqIndex2 = element.get() & Constants.BYTE_MASK;
209fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        break;
210fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                    case EID_Interworking:
211fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        int anOptions = data.get() & Constants.BYTE_MASK;
212fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        ant = Ant.values()[anOptions & 0x0f];
213fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        internet = (anOptions & 0x10) != 0;
214fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        // Len 1 none, 3 venue-info, 7 HESSID, 9 venue-info & HESSID
215fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        if (elementLength == 3 || elementLength == 9) {
216fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                            try {
217fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                ByteBuffer vinfo = data.duplicate();
218fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                vinfo.limit(vinfo.position() + 2);
219fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                VenueNameElement vne =
220fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                        new VenueNameElement(Constants.ANQPElementType.ANQPVenueName,
221fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                                vinfo);
222fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                venueGroup = vne.getGroup();
223fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                venueType = vne.getType();
224fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                data.getShort();
225fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                            } catch (ProtocolException pe) {
226fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                /*Cannot happen*/
227fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                            }
228fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        } else if (elementLength != 1 && elementLength != 7) {
229fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                            throw new IllegalArgumentException("Bad Interworking element length: " +
230fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                    elementLength);
23177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist                        }
232fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        if (elementLength == 7 || elementLength == 9) {
233fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                            hessid = getInteger(data, ByteOrder.BIG_ENDIAN, 6);
23477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist                        }
235fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        break;
236fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                    case EID_RoamingConsortium:
237fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        anqpOICount = data.get() & Constants.BYTE_MASK;
238fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist
239fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        int oi12Length = data.get() & Constants.BYTE_MASK;
240fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        int oi1Length = oi12Length & Constants.NIBBLE_MASK;
241fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        int oi2Length = (oi12Length >>> 4) & Constants.NIBBLE_MASK;
242fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        int oi3Length = elementLength - 2 - oi1Length - oi2Length;
243fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        int oiCount = 0;
244fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        if (oi1Length > 0) {
24577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist                            oiCount++;
246fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                            if (oi2Length > 0) {
24777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist                                oiCount++;
248fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                if (oi3Length > 0) {
249fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                    oiCount++;
250fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                }
25177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist                            }
25277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist                        }
253fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        roamingConsortiums = new long[oiCount];
254be24c9af85b8a6e02b24582418a4608e14396f2aJan Nordqvist                        if (oi1Length > 0 && roamingConsortiums.length > 0) {
255fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                            roamingConsortiums[0] =
256fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                    getInteger(data, ByteOrder.BIG_ENDIAN, oi1Length);
257fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        }
258be24c9af85b8a6e02b24582418a4608e14396f2aJan Nordqvist                        if (oi2Length > 0 && roamingConsortiums.length > 1) {
259fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                            roamingConsortiums[1] =
260fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                    getInteger(data, ByteOrder.BIG_ENDIAN, oi2Length);
261fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        }
262be24c9af85b8a6e02b24582418a4608e14396f2aJan Nordqvist                        if (oi3Length > 0 && roamingConsortiums.length > 2) {
263fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                            roamingConsortiums[2] =
264fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                    getInteger(data, ByteOrder.BIG_ENDIAN, oi3Length);
265fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        }
266fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        break;
267fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                    case EID_VSA:
268fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        element = getAndAdvancePayload(data, elementLength);
269fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        if (elementLength >= 5 && element.getInt() == Constants.HS20_FRAME_PREFIX) {
270fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                            int hsConf = element.get() & Constants.BYTE_MASK;
271fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                            switch ((hsConf >> 4) & Constants.NIBBLE_MASK) {
272fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                case 0:
273fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                    hsRelease = HSRelease.R1;
274fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                    break;
275fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                case 1:
276fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                    hsRelease = HSRelease.R2;
277fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                    break;
278fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                default:
279fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                    hsRelease = HSRelease.Unknown;
280fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                    break;
281fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                            }
282fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                            if ((hsConf & ANQP_DOMID_BIT) != 0) {
283fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                if (elementLength < 7) {
284fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                    throw new IllegalArgumentException(
285fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                            "HS20 indication element too short: " + elementLength);
286fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                }
287fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                anqpDomainID = element.getShort() & Constants.SHORT_MASK;
288fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                            }
28977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist                        }
290fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        break;
291fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                    case EID_ExtendedCaps:
292398823d45a240ff90ff2ffab3ff4a8b8646f24c9Jan Nordqvist                        element = data.duplicate();
293fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        extendedCapabilities =
294fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                                Constants.getInteger(data, ByteOrder.LITTLE_ENDIAN, elementLength);
295fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist
296fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        int index = RTT_RESP_ENABLE_BIT / 8;
297fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        byte offset = RTT_RESP_ENABLE_BIT % 8;
298fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist
299fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        if (elementLength < index + 1) {
300fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                            RTTResponder = false;
301fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                            element.position(element.position() + elementLength);
302fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                            break;
30377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist                        }
304fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist
305fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        element.position(element.position() + index);
306fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist
307fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        RTTResponder = (element.get() & (0x1 << offset)) != 0;
308fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                        break;
309fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                    default:
310243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe                        data.position(data.position() + elementLength);
311243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe                        break;
312fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                }
313fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist            }
314fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist        }
315be24c9af85b8a6e02b24582418a4608e14396f2aJan Nordqvist        catch (IllegalArgumentException | BufferUnderflowException | ArrayIndexOutOfBoundsException e) {
3161c03d75c73b9f5fa24a795a0d546f4f56b82ab9bJan Nordqvist            Log.d(Utils.hs2LogTag(getClass()), "Caught " + e);
317fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist            if (ssidOctets == null) {
318d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist                throw new IllegalArgumentException("Malformed IE string (no SSID)", e);
31977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist            }
320a1edc185d46d85e04930a5e12b465de9fea64afeJan Nordqvist            exception = e;
32177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        }
32277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
32377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        if (ssidOctets != null) {
324d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist            boolean strictUTF8 = extendedCapabilities != null &&
325d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist                    ( extendedCapabilities & SSID_UTF8_BIT ) != 0;
326d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist
327d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist            /*
328d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist             * Strict use of the "UTF-8 SSID" bit by APs appears to be spotty at best even if the
329d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist             * encoding truly is in UTF-8. An unconditional attempt to decode the SSID as UTF-8 is
330d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist             * therefore always made with a fall back to 8859-1 under normal circumstances.
331d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist             * If, however, a previous exception was detected and the UTF-8 bit is set, failure to
332d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist             * decode the SSID will be used as an indication that the whole frame is malformed and
333d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist             * an exception will be triggered.
334d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist             */
335d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist            CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
336d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist            try {
337d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist                CharBuffer decoded = decoder.decode(ByteBuffer.wrap(ssidOctets));
338d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist                ssid = decoded.toString();
33977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist            }
340d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist            catch (CharacterCodingException cce) {
341d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist                ssid = null;
34277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist            }
343fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist
344d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist            if (ssid == null) {
345d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist                if (strictUTF8 && exception != null) {
346d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist                    throw new IllegalArgumentException("Failed to decode SSID in dubious IE string");
347fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                }
348d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist                else {
349d33dc0d01f16ef7c338c3e3c82eaefa9e914ff83Jan Nordqvist                    ssid = new String(ssidOctets, StandardCharsets.ISO_8859_1);
350fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist                }
351fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist            }
35277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        }
35377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
35477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mSSID = ssid;
35577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mHESSID = hessid;
35677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mStationCount = stationCount;
35777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mChannelUtilization = channelUtilization;
35877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mCapacity = capacity;
35977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mAnt = ant;
36077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mInternet = internet;
36177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mVenueGroup = venueGroup;
36277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mVenueType = venueType;
36377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mHSRelease = hsRelease;
36477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mAnqpDomainID = anqpDomainID;
36577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mAnqpOICount = anqpOICount;
36677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mRoamingConsortiums = roamingConsortiums;
36777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mExtendedCapabilities = extendedCapabilities;
36877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mANQPElements = SupplicantBridge.parseANQPLines(anqpLines);
369243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        //set up channel info
370243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        mPrimaryFreq = freq;
371243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe
372243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        if (channelMode != 0) {
373243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe            // 80 or 160 MHz
374243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe            mChannelWidth = channelMode + 1;
375243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe            mCenterfreq0 = (centerFreqIndex1 - 36) * 5 + 5180;
376243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe            if(channelMode > 1) { //160MHz
377243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe                mCenterfreq1 = (centerFreqIndex2 - 36) * 5 + 5180;
378243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe            } else {
379243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe                mCenterfreq1 = 0;
380243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe            }
381243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        } else {
382243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe            //20 or 40 MHz
383243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe            if (secondChanelOffset != 0) {//40MHz
384243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe                mChannelWidth = 1;
385243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe                if (secondChanelOffset == 1) {
386243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe                    mCenterfreq0 = mPrimaryFreq + 20;
387243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe                } else if (secondChanelOffset == 3) {
388243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe                    mCenterfreq0 = mPrimaryFreq - 20;
389243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe                } else {
390243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe                    mCenterfreq0 = 0;
391243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe                    Log.e(TAG,"Error on secondChanelOffset");
392243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe                }
393243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe            } else {
394243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe                mCenterfreq0 = 0;
395243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe                mChannelWidth = 0;
396243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe            }
397243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe            mCenterfreq1 = 0;
398243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        }
399243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        m80211McRTTResponder = RTTResponder;
400d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande        if (VDBG) {
401d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande            Log.d(TAG, mSSID + "ChannelWidth is: " + mChannelWidth + " PrimaryFreq: " + mPrimaryFreq +
402d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande                    " mCenterfreq0: " + mCenterfreq0 + " mCenterfreq1: " + mCenterfreq1 +
403d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande                    (m80211McRTTResponder ? "Support RTT reponder" : "Do not support RTT responder"));
404d3fb9cbb12d013dd70e672ace5c41ab18a3679a0Vinit Deshpande        }
40577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
40677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
407fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist    private static ByteBuffer getAndAdvancePayload(ByteBuffer data, int plLength) {
408398823d45a240ff90ff2ffab3ff4a8b8646f24c9Jan Nordqvist        ByteBuffer payload = data.duplicate().order(data.order());
409fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist        payload.limit(payload.position() + plLength);
410fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist        data.position(data.position() + plLength);
411fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist        return payload;
412fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist    }
413fea443b1b8807443544dfdb29a9c237b3ccf964aJan Nordqvist
41477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    private NetworkDetail(NetworkDetail base, Map<Constants.ANQPElementType, ANQPElement> anqpElements) {
41577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mSSID = base.mSSID;
41677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mBSSID = base.mBSSID;
41777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mHESSID = base.mHESSID;
41877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mStationCount = base.mStationCount;
41977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mChannelUtilization = base.mChannelUtilization;
42077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mCapacity = base.mCapacity;
42177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mAnt = base.mAnt;
42277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mInternet = base.mInternet;
42377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mVenueGroup = base.mVenueGroup;
42477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mVenueType = base.mVenueType;
42577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mHSRelease = base.mHSRelease;
42677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mAnqpDomainID = base.mAnqpDomainID;
42777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mAnqpOICount = base.mAnqpOICount;
42877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mRoamingConsortiums = base.mRoamingConsortiums;
42977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mExtendedCapabilities = base.mExtendedCapabilities;
43077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        mANQPElements = anqpElements;
431243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        mChannelWidth = base.mChannelWidth;
432243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        mPrimaryFreq = base.mPrimaryFreq;
433243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        mCenterfreq0 = base.mCenterfreq0;
434243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        mCenterfreq1 = base.mCenterfreq1;
435243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        m80211McRTTResponder = base.m80211McRTTResponder;
43677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
43777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
43877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public NetworkDetail complete(Map<Constants.ANQPElementType, ANQPElement> anqpElements) {
43977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return new NetworkDetail(this, anqpElements);
44077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
44177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
44277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    private static long parseMac(String s) {
44377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
44477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        long mac = 0;
44577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        int count = 0;
44677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        for (int n = 0; n < s.length(); n++) {
44777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist            int nibble = Utils.fromHex(s.charAt(n), true);
44877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist            if (nibble >= 0) {
44977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist                mac = (mac << 4) | nibble;
45077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist                count++;
45177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist            }
45277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        }
45377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        if (count < 12 || (count&1) == 1) {
45477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist            throw new IllegalArgumentException("Bad MAC address: '" + s + "'");
45577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        }
45677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return mac;
45777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
45877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
45977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public boolean has80211uInfo() {
46077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return mAnt != null || mRoamingConsortiums != null || mHSRelease != null;
46177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
46277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
46377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public boolean hasInterworking() {
46477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return mAnt != null;
46577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
46677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
46777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public String getSSID() {
46877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return mSSID;
46977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
47077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
4719a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist    public String getTrimmedSSID() {
4729a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist        for (int n = 0; n < mSSID.length(); n++) {
4739a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist            if (mSSID.charAt(n) != 0) {
4749a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist                return mSSID;
4759a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist            }
4769a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist        }
4779a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist        return "";
4789a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist    }
4799a64375bfb3431ef8d4ec1f2e97349c106c9c5f0Jan Nordqvist
48077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public long getHESSID() {
48177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return mHESSID;
48277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
48377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
48477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public long getBSSID() {
48577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return mBSSID;
48677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
48777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
48877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public int getStationCount() {
48977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return mStationCount;
49077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
49177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
49277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public int getChannelUtilization() {
49377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return mChannelUtilization;
49477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
49577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
49677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public int getCapacity() {
49777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return mCapacity;
49877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
49977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
50077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public boolean isInterworking() {
50177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return mAnt != null;
50277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
50377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
50477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public Ant getAnt() {
50577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return mAnt;
50677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
50777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
50877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public boolean isInternet() {
50977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return mInternet;
51077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
51177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
51277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public VenueNameElement.VenueGroup getVenueGroup() {
51377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return mVenueGroup;
51477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
51577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
51677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public VenueNameElement.VenueType getVenueType() {
51777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return mVenueType;
51877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
51977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
52077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public HSRelease getHSRelease() {
52177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return mHSRelease;
52277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
52377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
52477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public int getAnqpDomainID() {
52577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return mAnqpDomainID;
52677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
52777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
52877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public int getAnqpOICount() {
52977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return mAnqpOICount;
53077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
53177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
53277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public long[] getRoamingConsortiums() {
53377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return mRoamingConsortiums;
53477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
53577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
53677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public Long getExtendedCapabilities() {
53777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return mExtendedCapabilities;
53877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
53977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
54077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public Map<Constants.ANQPElementType, ANQPElement> getANQPElements() {
54177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return mANQPElements;
54277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
54377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
544243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe    public int getChannelWidth() {
545243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        return mChannelWidth;
546243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe    }
547243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe
548243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe    public int getCenterfreq0() {
549243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        return mCenterfreq0;
550243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe    }
551243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe
552243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe    public int getCenterfreq1() {
553243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        return mCenterfreq1;
554243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe    }
555243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe
556243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe    public boolean is80211McResponderSupport() {
557243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        return m80211McRTTResponder;
558243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe    }
559243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe
56077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public boolean isSSID_UTF8() {
56177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return mExtendedCapabilities != null && (mExtendedCapabilities & SSID_UTF8_BIT) != 0;
56277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
56377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
56477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    @Override
56577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public boolean equals(Object thatObject) {
56677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        if (this == thatObject) {
56777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist            return true;
56877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        }
56977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        if (thatObject == null || getClass() != thatObject.getClass()) {
57077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist            return false;
57177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        }
57277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
57377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        NetworkDetail that = (NetworkDetail)thatObject;
57477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
57577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return getSSID().equals(that.getSSID()) && getBSSID() == that.getBSSID();
57677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
57777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
57877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    @Override
57977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public int hashCode() {
58077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return ((mSSID.hashCode() * 31) + (int)(mBSSID >>> 32)) * 31 + (int)mBSSID;
58177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
58277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
58377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    @Override
58477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public String toString() {
58577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return String.format("NetworkInfo{mSSID='%s', mHESSID=%x, mBSSID=%x, mStationCount=%d, " +
58677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist                "mChannelUtilization=%d, mCapacity=%d, mAnt=%s, mInternet=%s, " +
58777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist                "mVenueGroup=%s, mVenueType=%s, mHSRelease=%s, mAnqpDomainID=%d, " +
58877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist                "mAnqpOICount=%d, mRoamingConsortiums=%s}",
58977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist                mSSID, mHESSID, mBSSID, mStationCount,
59077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist                mChannelUtilization, mCapacity, mAnt, mInternet,
59177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist                mVenueGroup, mVenueType, mHSRelease, mAnqpDomainID,
59277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist                mAnqpOICount, Utils.roamingConsortiumsToString(mRoamingConsortiums));
59377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
59477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
59577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public String toKeyString() {
596a1edc185d46d85e04930a5e12b465de9fea64afeJan Nordqvist        return mHESSID != 0 ?
597866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist            String.format("'%s':%012x (%012x)", mSSID, mBSSID, mHESSID) :
598866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist            String.format("'%s':%012x", mSSID, mBSSID);
59977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
60077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
60177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public String getBSSIDString() {
60277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return toMACString(mBSSID);
60377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
60477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
605ef1567e413c9ed5f5c4fdb9e354861632f7b2f87Jan Nordqvist    public static String toMACString(long mac) {
60677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        StringBuilder sb = new StringBuilder();
60777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        boolean first = true;
60877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        for (int n = BYTES_IN_EUI48 - 1; n >= 0; n--) {
60977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist            if (first) {
61077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist                first = false;
61177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist            } else {
61277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist                sb.append(':');
61377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist            }
61477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist            sb.append(String.format("%02x", (mac >>> (n * Byte.SIZE)) & BYTE_MASK));
61577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        }
61677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        return sb.toString();
61777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
61877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
61977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    private static final String IE = "ie=" +
62077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist            "000477696e67" +                // SSID wing
62177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist            "0b052a00cf611e" +              // BSS Load 42:207:7777
62277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist            "6b091e0a01610408621205" +      // internet:Experimental:Vehicular:Auto:hessid
62377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist            "6f0a0e530111112222222229" +    // 14:111111:2222222229
62477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist            "dd07506f9a10143a01";           // r2:314
62577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
62677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    private static final String IE2 = "ie=000f4578616d706c65204e6574776f726b010882848b960c1218240301012a010432043048606c30140100000fac040100000fac040100000fac0100007f04000000806b091e07010203040506076c027f006f1001531122331020304050010203040506dd05506f9a1000";
62777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
62877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    public static void main(String[] args) {
62977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        ScanResult scanResult = new ScanResult();
63077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        scanResult.SSID = "wing";
63177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        scanResult.BSSID = "610408";
632243931f3474f6235cfcf5c1a55fa2f192ee264aexinhe        NetworkDetail nwkDetail = new NetworkDetail(scanResult.BSSID, IE2, null, 0);
63377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist        System.out.println(nwkDetail);
63477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
63577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist}
636