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