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