Utils.java revision 820d73615f338d6c71f2d75aba0ad8410e9eed3e
1package com.android.server.wifi.hotspot2; 2 3import java.nio.ByteBuffer; 4import java.util.ArrayList; 5import java.util.Calendar; 6import java.util.Collection; 7import java.util.LinkedList; 8import java.util.List; 9import java.util.TimeZone; 10 11import static com.android.server.wifi.anqp.Constants.BYTE_MASK; 12import static com.android.server.wifi.anqp.Constants.NIBBLE_MASK; 13 14public abstract class Utils { 15 16 public static final String HS20_TAG = "HS20"; 17 18 private static final String[] PLMNText = { "wlan", "mnc*", "mcc*", "3gppnetwork", "org" }; 19 20 public static List<String> splitDomain(String domain) { 21 22 if (domain.endsWith(".")) 23 domain = domain.substring(0, domain.length() - 1); 24 int at = domain.indexOf('@'); 25 if (at >= 0) 26 domain = domain.substring(at + 1); 27 28 String[] labels = domain.toLowerCase().split("\\."); 29 LinkedList<String> labelList = new LinkedList<String>(); 30 for (String label : labels) { 31 labelList.addFirst(label); 32 } 33 34 return labelList; 35 } 36 37 public static long parseMac(String s) { 38 39 long mac = 0; 40 int count = 0; 41 for (int n = 0; n < s.length(); n++) { 42 int nibble = Utils.fromHex(s.charAt(n), true); 43 if (nibble >= 0) { 44 mac = (mac << 4) | nibble; 45 count++; 46 } 47 } 48 if (count < 12 || (count&1) == 1) { 49 throw new IllegalArgumentException("Bad MAC address: '" + s + "'"); 50 } 51 return mac; 52 } 53 54 public static String getMccMnc(List<String> domain) { 55 if (domain.size() != 5) { 56 return null; 57 } 58 59 for (int n = 4; n >= 0; n-- ) { 60 String expect = PLMNText[n]; 61 int len = expect.endsWith("*") ? expect.length() - 1 : expect.length(); 62 if (!domain.get(n).regionMatches(0, expect, 0, len)) { 63 return null; 64 } 65 } 66 67 String prefix = domain.get(1).substring(3) + domain.get(2).substring(3); 68 for (int n = 0; n < prefix.length(); n++) { 69 char ch = prefix.charAt(n); 70 if (ch < '0' || ch > '9') { 71 return null; 72 } 73 } 74 return prefix; 75 } 76 77 public static String roamingConsortiumsToString(long[] ois) { 78 if (ois == null) { 79 return "null"; 80 } 81 List<Long> list = new ArrayList<Long>(ois.length); 82 for (long oi : ois) { 83 list.add(oi); 84 } 85 return roamingConsortiumsToString(list); 86 } 87 88 public static String roamingConsortiumsToString(Collection<Long> ois) { 89 StringBuilder sb = new StringBuilder(); 90 boolean first = true; 91 for (long oi : ois) { 92 if (first) { 93 first = false; 94 } else { 95 sb.append(", "); 96 } 97 if (Long.numberOfLeadingZeros(oi) > 40) { 98 sb.append(String.format("%06x", oi)); 99 } else { 100 sb.append(String.format("%010x", oi)); 101 } 102 } 103 return sb.toString(); 104 } 105 106 public static String toUnicodeEscapedString(String s) { 107 StringBuilder sb = new StringBuilder(s.length()); 108 for (int n = 0; n < s.length(); n++) { 109 char ch = s.charAt(n); 110 if (ch>= ' ' && ch < 127) { 111 sb.append(ch); 112 } 113 else { 114 sb.append("\\u").append(String.format("%04x", (int)ch)); 115 } 116 } 117 return sb.toString(); 118 } 119 120 public static String toHexString(byte[] data) { 121 if (data == null) { 122 return "null"; 123 } 124 StringBuilder sb = new StringBuilder(data.length * 3); 125 126 boolean first = true; 127 for (byte b : data) { 128 if (first) { 129 first = false; 130 } else { 131 sb.append(' '); 132 } 133 sb.append(String.format("%02x", b & BYTE_MASK)); 134 } 135 return sb.toString(); 136 } 137 138 public static String toHex(byte[] octets) { 139 StringBuilder sb = new StringBuilder(octets.length * 2); 140 for (byte o : octets) { 141 sb.append(String.format("%02x", o & BYTE_MASK)); 142 } 143 return sb.toString(); 144 } 145 146 public static byte[] hexToBytes(String text) { 147 if ((text.length() & 1) == 1) { 148 throw new NumberFormatException("Odd length hex string: " + text.length()); 149 } 150 byte[] data = new byte[text.length() >> 1]; 151 int position = 0; 152 for (int n = 0; n < text.length(); n += 2) { 153 data[position] = 154 (byte) (((fromHex(text.charAt(n), false) & NIBBLE_MASK) << 4) | 155 (fromHex(text.charAt(n + 1), false) & NIBBLE_MASK)); 156 position++; 157 } 158 return data; 159 } 160 161 public static int fromHex(char ch, boolean lenient) throws NumberFormatException { 162 if (ch <= '9' && ch >= '0') { 163 return ch - '0'; 164 } else if (ch >= 'a' && ch <= 'f') { 165 return ch + 10 - 'a'; 166 } else if (ch <= 'F' && ch >= 'A') { 167 return ch + 10 - 'A'; 168 } else if (lenient) { 169 return -1; 170 } else { 171 throw new NumberFormatException("Bad hex-character: " + ch); 172 } 173 } 174 175 private static char toAscii(int b) { 176 return b >= ' ' && b < 0x7f ? (char) b : '.'; 177 } 178 179 static boolean isDecimal(String s) { 180 for (int n = 0; n < s.length(); n++) { 181 char ch = s.charAt(n); 182 if (ch < '0' || ch > '9') { 183 return false; 184 } 185 } 186 return true; 187 } 188 189 public static <T extends Comparable> int compare(Comparable<T> c1, T c2) { 190 if (c1 == null) { 191 return c2 == null ? 0 : -1; 192 } 193 else if (c2 == null) { 194 return 1; 195 } 196 else { 197 return c1.compareTo(c2); 198 } 199 } 200 201 public static String bytesToBingoCard(ByteBuffer data, int len) { 202 ByteBuffer dup = data.duplicate(); 203 dup.limit(dup.position() + len); 204 return bytesToBingoCard(dup); 205 } 206 207 public static String bytesToBingoCard(ByteBuffer data) { 208 ByteBuffer dup = data.duplicate(); 209 StringBuilder sbx = new StringBuilder(); 210 while (dup.hasRemaining()) { 211 sbx.append(String.format("%02x ", dup.get() & BYTE_MASK)); 212 } 213 dup = data.duplicate(); 214 sbx.append(' '); 215 while (dup.hasRemaining()) { 216 sbx.append(String.format("%c", toAscii(dup.get() & BYTE_MASK))); 217 } 218 return sbx.toString(); 219 } 220 221 public static String toHMS(long millis) { 222 long time = millis >= 0 ? millis : -millis; 223 long tmp = time / 1000L; 224 long ms = time - tmp * 1000L; 225 226 time = tmp; 227 tmp /= 60L; 228 long s = time - tmp * 60L; 229 230 time = tmp; 231 tmp /= 60L; 232 long m = time - tmp * 60L; 233 234 return String.format("%s%d:%02d:%02d.%03d", millis < 0 ? "-" : "", tmp, m, s, ms); 235 } 236 237 public static String toUTCString(long ms) { 238 if (ms < 0) { 239 return "unset"; 240 } 241 Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC")); 242 c.setTimeInMillis(ms); 243 return String.format("%4d/%02d/%02d %2d:%02d:%02dZ", 244 c.get(Calendar.YEAR), 245 c.get(Calendar.MONTH) + 1, 246 c.get(Calendar.DAY_OF_MONTH), 247 c.get(Calendar.HOUR_OF_DAY), 248 c.get(Calendar.MINUTE), 249 c.get(Calendar.SECOND)); 250 } 251 252 public static String unquote(String s) { 253 if (s == null) { 254 return null; 255 } 256 else if (s.startsWith("\"") && s.endsWith("\"")) { 257 return s.substring(1, s.length()-1); 258 } 259 else { 260 return s; 261 } 262 } 263} 264