1ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistpackage com.android.hotspot2.omadm;
2ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
3ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport com.android.hotspot2.osu.OSUError;
4ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport com.android.hotspot2.osu.OSUStatus;
5ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
6ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.io.EOFException;
7ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.io.IOException;
8ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.io.InputStream;
9ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.io.OutputStream;
10ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.nio.charset.StandardCharsets;
11ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.Arrays;
12ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.EnumMap;
13ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.HashMap;
14ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.Map;
15ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
16ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistpublic class OMAConstants {
17ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    private OMAConstants() {
18ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    }
19ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
20ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static final String MOVersion = "1.0";
21ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static final String PPS_URN = "urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0";
22ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static final String DevInfoURN = "urn:oma:mo:oma-dm-devinfo:1.0";
23ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static final String DevDetailURN = "urn:oma:mo:oma-dm-devdetail:1.0";
24ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static final String DevDetailXURN = "urn:wfa:mo-ext:hotspot2dot0-devdetail-ext:1.0";
25ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
26ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static final String[] SupportedMO_URNs = {
27ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            PPS_URN, DevInfoURN, DevDetailURN, DevDetailXURN
28ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    };
29ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
30ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static final String SppMOAttribute = "spp:moURN";
31ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static final String TAG_PostDevData = "spp:sppPostDevData";
32ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static final String TAG_SupportedVersions = "spp:supportedSPPVersions";
33ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static final String TAG_SupportedMOs = "spp:supportedMOList";
34ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static final String TAG_UpdateResponse = "spp:sppUpdateResponse";
35ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static final String TAG_MOContainer = "spp:moContainer";
36ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static final String TAG_Version = "spp:sppVersion";
37ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
38ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static final String TAG_SessionID = "spp:sessionID";
39ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static final String TAG_Status = "spp:sppStatus";
40ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static final String TAG_Error = "spp:sppError";
41ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
42ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static final String SyncMLVersionTag = "VerDTD";
43ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static final String OMAVersion = "1.2";
44ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static final String SyncML = "syncml:dmddf1.2";
45ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
46ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    private static final byte[] INDENT = new byte[1024];
47ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
48ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    private static final Map<OSUStatus, String> sStatusStrings = new EnumMap<>(OSUStatus.class);
49ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    private static final Map<String, OSUStatus> sStatusEnums = new HashMap<>();
50ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    private static final Map<OSUError, String> sErrorStrings = new EnumMap<>(OSUError.class);
51ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    private static final Map<String, OSUError> sErrorEnums = new HashMap<>();
52ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
53ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    static {
54ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sStatusStrings.put(OSUStatus.OK, "OK");
55ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sStatusStrings.put(OSUStatus.ProvComplete,
56ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                "Provisioning complete, request sppUpdateResponse");
57ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sStatusStrings.put(OSUStatus.RemediationComplete,
58ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                "Remediation complete, request sppUpdateResponse");
59ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sStatusStrings.put(OSUStatus.UpdateComplete, "Update complete, request sppUpdateResponse");
60ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sStatusStrings.put(OSUStatus.ExchangeComplete, "Exchange complete, release TLS connection");
61ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sStatusStrings.put(OSUStatus.Unknown, "No update available at this time");
62ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sStatusStrings.put(OSUStatus.Error, "Error occurred");
63ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
64ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        for (Map.Entry<OSUStatus, String> entry : sStatusStrings.entrySet()) {
65ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            sStatusEnums.put(entry.getValue().toLowerCase(), entry.getKey());
66ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        }
67ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
68ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sErrorStrings.put(OSUError.SPPversionNotSupported, "SPP version not supported");
69ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sErrorStrings.put(OSUError.MOsNotSupported, "One or more mandatory MOs not supported");
70ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sErrorStrings.put(OSUError.CredentialsFailure,
71ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                "Credentials cannot be provisioned at this time");
72ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sErrorStrings.put(OSUError.RemediationFailure,
73ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                "Remediation cannot be completed at this time");
74ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sErrorStrings.put(OSUError.ProvisioningFailed,
75ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                "Provisioning cannot be completed at this time");
76ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sErrorStrings.put(OSUError.ExistingCertificate, "Continue to use existing certificate");
77ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sErrorStrings.put(OSUError.CookieInvalid, "Cookie invalid");
78ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sErrorStrings.put(OSUError.WebSessionID,
79ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                "No corresponding web-browser-connection Session ID");
80ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sErrorStrings.put(OSUError.PermissionDenied, "Permission denied");
81ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sErrorStrings.put(OSUError.CommandFailed, "Command failed");
82ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sErrorStrings.put(OSUError.MOaddOrUpdateFailed, "MO addition or update failed");
83ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sErrorStrings.put(OSUError.DeviceFull, "Device full");
84ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sErrorStrings.put(OSUError.BadTreeURI, "Bad management tree URI");
85ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sErrorStrings.put(OSUError.TooLarge, "Requested entity too large");
86ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sErrorStrings.put(OSUError.CommandNotAllowed, "Command not allowed");
87ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sErrorStrings.put(OSUError.UserAborted, "Command not executed due to user");
88ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sErrorStrings.put(OSUError.NotFound, "Not found");
89ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        sErrorStrings.put(OSUError.Other, "Other");
90ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
91ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        for (Map.Entry<OSUError, String> entry : sErrorStrings.entrySet()) {
92ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            sErrorEnums.put(entry.getValue().toLowerCase(), entry.getKey());
93ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        }
94ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        Arrays.fill(INDENT, (byte) ' ');
95ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    }
96ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
97ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static String mapStatus(OSUStatus status) {
98ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        return sStatusStrings.get(status);
99ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    }
100ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
101ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static OSUStatus mapStatus(String status) {
102ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        return sStatusEnums.get(status.toLowerCase());
103ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    }
104ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
105ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static String mapError(OSUError error) {
106ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        return sErrorStrings.get(error);
107ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    }
108ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
109ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static OSUError mapError(String error) {
110ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        return sErrorEnums.get(error.toLowerCase());
111ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    }
112ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
113ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static void serializeString(String s, OutputStream out) throws IOException {
114ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        byte[] octets = s.getBytes(StandardCharsets.UTF_8);
115ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        byte[] prefix = String.format("%x:", octets.length).getBytes(StandardCharsets.UTF_8);
116ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        out.write(prefix);
117ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        out.write(octets);
118ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    }
119ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
120ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static void indent(int level, OutputStream out) throws IOException {
121ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        out.write(INDENT, 0, level);
122ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    }
123ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
124ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static String deserializeString(InputStream in) throws IOException {
125ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        StringBuilder prefix = new StringBuilder();
126ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        for (; ; ) {
127ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            byte b = (byte) in.read();
128ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            if (b == '.')
129ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                return null;
130ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            else if (b == ':')
131ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                break;
132ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            else if (b > ' ')
133ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                prefix.append((char) b);
134ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        }
135ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        int length = Integer.parseInt(prefix.toString(), 16);
136ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        byte[] octets = new byte[length];
137ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        int offset = 0;
138ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        while (offset < octets.length) {
139ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            int amount = in.read(octets, offset, octets.length - offset);
140ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            if (amount <= 0)
141ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                throw new EOFException();
142ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            offset += amount;
143ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        }
144ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        return new String(octets, StandardCharsets.UTF_8);
145ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    }
146ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
147ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public static String readURN(InputStream in) throws IOException {
148ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        StringBuilder urn = new StringBuilder();
149ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
150ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        for (; ; ) {
151ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            byte b = (byte) in.read();
152ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            if (b == ')')
153ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                break;
154ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            urn.append((char) b);
155ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        }
156ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        return urn.toString();
157ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    }
158ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist}
159