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