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