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