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