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