1package com.android.server.wifi.anqp;
2
3import java.net.ProtocolException;
4import java.nio.ByteBuffer;
5import java.nio.ByteOrder;
6import java.nio.charset.Charset;
7import java.util.HashMap;
8import java.util.Map;
9
10/**
11 * ANQP related constants (802.11-2012)
12 */
13public class Constants {
14
15    public static final int NIBBLE_MASK = 0x0f;
16    public static final int BYTE_MASK = 0xff;
17    public static final int SHORT_MASK = 0xffff;
18    public static final long INT_MASK = 0xffffffffL;
19    public static final int BYTES_IN_SHORT = 2;
20    public static final int BYTES_IN_INT = 4;
21    public static final int BYTES_IN_EUI48 = 6;
22
23    public static final int HS20_PREFIX = 0x119a6f50;   // Note that this is represented as a LE int
24    public static final int HS20_FRAME_PREFIX = 0x109a6f50;
25    public static final int UTF8_INDICATOR = 1;
26
27    public static final int ANQP_QUERY_LIST = 256;
28    public static final int ANQP_CAPABILITY_LIST = 257;
29    public static final int ANQP_VENUE_NAME = 258;
30    public static final int ANQP_EMERGENCY_NUMBER = 259;
31    public static final int ANQP_NWK_AUTH_TYPE = 260;
32    public static final int ANQP_ROAMING_CONSORTIUM = 261;
33    public static final int ANQP_IP_ADDR_AVAILABILITY = 262;
34    public static final int ANQP_NAI_REALM = 263;
35    public static final int ANQP_3GPP_NETWORK = 264;
36    public static final int ANQP_GEO_LOC = 265;
37    public static final int ANQP_CIVIC_LOC = 266;
38    public static final int ANQP_LOC_URI = 267;
39    public static final int ANQP_DOM_NAME = 268;
40    public static final int ANQP_EMERGENCY_ALERT = 269;
41    public static final int ANQP_TDLS_CAP = 270;
42    public static final int ANQP_EMERGENCY_NAI = 271;
43    public static final int ANQP_NEIGHBOR_REPORT = 272;
44    public static final int ANQP_VENDOR_SPEC = 56797;
45
46    public static final int HS_QUERY_LIST = 1;
47    public static final int HS_CAPABILITY_LIST = 2;
48    public static final int HS_FRIENDLY_NAME = 3;
49    public static final int HS_WAN_METRICS = 4;
50    public static final int HS_CONN_CAPABILITY = 5;
51    public static final int HS_NAI_HOME_REALM_QUERY = 6;
52    public static final int HS_OPERATING_CLASS = 7;
53    public static final int HS_OSU_PROVIDERS = 8;
54    public static final int HS_ICON_REQUEST = 10;
55    public static final int HS_ICON_FILE = 11;
56
57    public enum ANQPElementType {
58        ANQPQueryList,
59        ANQPCapabilityList,
60        ANQPVenueName,
61        ANQPEmergencyNumber,
62        ANQPNwkAuthType,
63        ANQPRoamingConsortium,
64        ANQPIPAddrAvailability,
65        ANQPNAIRealm,
66        ANQP3GPPNetwork,
67        ANQPGeoLoc,
68        ANQPCivicLoc,
69        ANQPLocURI,
70        ANQPDomName,
71        ANQPEmergencyAlert,
72        ANQPTDLSCap,
73        ANQPEmergencyNAI,
74        ANQPNeighborReport,
75        ANQPVendorSpec,
76        HSQueryList,
77        HSCapabilityList,
78        HSFriendlyName,
79        HSWANMetrics,
80        HSConnCapability,
81        HSNAIHomeRealmQuery,
82        HSOperatingclass,
83        HSOSUProviders,
84        HSIconRequest,
85        HSIconFile
86    }
87
88    private static final Map<Integer, ANQPElementType> sAnqpMap = new HashMap<Integer, ANQPElementType>();
89    private static final Map<Integer, ANQPElementType> sHs20Map = new HashMap<Integer, ANQPElementType>();
90    private static final Map<ANQPElementType, Integer> sRevAnqpmap = new HashMap<ANQPElementType, Integer>();
91    private static final Map<ANQPElementType, Integer> sRevHs20map = new HashMap<ANQPElementType, Integer>();
92
93    static {
94        sAnqpMap.put(ANQP_QUERY_LIST, ANQPElementType.ANQPQueryList);
95        sAnqpMap.put(ANQP_CAPABILITY_LIST, ANQPElementType.ANQPCapabilityList);
96        sAnqpMap.put(ANQP_VENUE_NAME, ANQPElementType.ANQPVenueName);
97        sAnqpMap.put(ANQP_EMERGENCY_NUMBER, ANQPElementType.ANQPEmergencyNumber);
98        sAnqpMap.put(ANQP_NWK_AUTH_TYPE, ANQPElementType.ANQPNwkAuthType);
99        sAnqpMap.put(ANQP_ROAMING_CONSORTIUM, ANQPElementType.ANQPRoamingConsortium);
100        sAnqpMap.put(ANQP_IP_ADDR_AVAILABILITY, ANQPElementType.ANQPIPAddrAvailability);
101        sAnqpMap.put(ANQP_NAI_REALM, ANQPElementType.ANQPNAIRealm);
102        sAnqpMap.put(ANQP_3GPP_NETWORK, ANQPElementType.ANQP3GPPNetwork);
103        sAnqpMap.put(ANQP_GEO_LOC, ANQPElementType.ANQPGeoLoc);
104        sAnqpMap.put(ANQP_CIVIC_LOC, ANQPElementType.ANQPCivicLoc);
105        sAnqpMap.put(ANQP_LOC_URI, ANQPElementType.ANQPLocURI);
106        sAnqpMap.put(ANQP_DOM_NAME, ANQPElementType.ANQPDomName);
107        sAnqpMap.put(ANQP_EMERGENCY_ALERT, ANQPElementType.ANQPEmergencyAlert);
108        sAnqpMap.put(ANQP_TDLS_CAP, ANQPElementType.ANQPTDLSCap);
109        sAnqpMap.put(ANQP_EMERGENCY_NAI, ANQPElementType.ANQPEmergencyNAI);
110        sAnqpMap.put(ANQP_NEIGHBOR_REPORT, ANQPElementType.ANQPNeighborReport);
111        sAnqpMap.put(ANQP_VENDOR_SPEC, ANQPElementType.ANQPVendorSpec);
112
113        sHs20Map.put(HS_QUERY_LIST, ANQPElementType.HSQueryList);
114        sHs20Map.put(HS_CAPABILITY_LIST, ANQPElementType.HSCapabilityList);
115        sHs20Map.put(HS_FRIENDLY_NAME, ANQPElementType.HSFriendlyName);
116        sHs20Map.put(HS_WAN_METRICS, ANQPElementType.HSWANMetrics);
117        sHs20Map.put(HS_CONN_CAPABILITY, ANQPElementType.HSConnCapability);
118        sHs20Map.put(HS_NAI_HOME_REALM_QUERY, ANQPElementType.HSNAIHomeRealmQuery);
119        sHs20Map.put(HS_OPERATING_CLASS, ANQPElementType.HSOperatingclass);
120        sHs20Map.put(HS_OSU_PROVIDERS, ANQPElementType.HSOSUProviders);
121        sHs20Map.put(HS_ICON_REQUEST, ANQPElementType.HSIconRequest);
122        sHs20Map.put(HS_ICON_FILE, ANQPElementType.HSIconFile);
123
124        for (Map.Entry<Integer, ANQPElementType> entry : sAnqpMap.entrySet()) {
125            sRevAnqpmap.put(entry.getValue(), entry.getKey());
126        }
127        for (Map.Entry<Integer, ANQPElementType> entry : sHs20Map.entrySet()) {
128            sRevHs20map.put(entry.getValue(), entry.getKey());
129        }
130    }
131
132    public static ANQPElementType mapANQPElement(int id) {
133        return sAnqpMap.get(id);
134    }
135
136    public static ANQPElementType mapHS20Element(int id) {
137        return sHs20Map.get(id);
138    }
139
140    public static Integer getANQPElementID(ANQPElementType elementType) {
141        return sRevAnqpmap.get(elementType);
142    }
143
144    public static Integer getHS20ElementID(ANQPElementType elementType) {
145        return sRevHs20map.get(elementType);
146    }
147
148    public static long getInteger(ByteBuffer payload, ByteOrder bo, int size) {
149        byte[] octets = new byte[size];
150        payload.get(octets);
151        long value = 0;
152        if (bo == ByteOrder.LITTLE_ENDIAN) {
153            for (int n = octets.length - 1; n >= 0; n--) {
154                value = (value << Byte.SIZE) | (octets[n] & BYTE_MASK);
155            }
156        }
157        else {
158            for (byte octet : octets) {
159                value = (value << Byte.SIZE) | (octet & BYTE_MASK);
160            }
161        }
162        return value;
163    }
164
165    public static String getPrefixedString(ByteBuffer payload, int lengthLength, Charset charset)
166            throws ProtocolException {
167        return getPrefixedString(payload, lengthLength, charset, false);
168    }
169
170    public static String getPrefixedString(ByteBuffer payload, int lengthLength, Charset charset,
171                                           boolean useNull) throws ProtocolException {
172        if (payload.remaining() < lengthLength) {
173            throw new ProtocolException("Runt string: " + payload.remaining());
174        }
175        return getString(payload, (int) getInteger(payload, ByteOrder.LITTLE_ENDIAN,
176                lengthLength), charset, useNull);
177    }
178
179    public static String getString(ByteBuffer payload, int length, Charset charset)
180            throws ProtocolException {
181        return getString(payload, length, charset, false);
182    }
183
184    public static String getString(ByteBuffer payload, int length, Charset charset, boolean useNull)
185            throws ProtocolException {
186        if (length > payload.remaining()) {
187            throw new ProtocolException("Bad string length: " + length);
188        }
189        if (useNull && length == 0) {
190            return null;
191        }
192        byte[] octets = new byte[length];
193        payload.get(octets);
194        return new String(octets, charset);
195    }
196}
197