Bug 853715 - 0003. Add PDU helper for decoding SI messages. r=vicamo
authorChuck Lee <chulee@mozilla.com>
Thu, 30 May 2013 14:22:44 +0800
changeset 134476 26372a81084650eaeeae13308d8d4cb3e1b1f7e6
parent 134475 a457d19b001de05642f27f12672dcdf3909f2e8d
child 134477 aba5a6ca7427d3207d30d4c4eba3460463beb262
push id29232
push useremorley@mozilla.com
push dateMon, 10 Jun 2013 09:07:08 +0000
treeherdermozilla-inbound@deb589f7e2dc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvicamo
bugs853715
milestone24.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 853715 - 0003. Add PDU helper for decoding SI messages. r=vicamo
dom/wappush/src/Makefile.in
dom/wappush/src/gonk/SiPduHelper.jsm
--- a/dom/wappush/src/Makefile.in
+++ b/dom/wappush/src/Makefile.in
@@ -12,13 +12,14 @@ VPATH            = \
 include $(DEPTH)/config/autoconf.mk
 
 ifdef MOZ_B2G_RIL
 EXTRA_COMPONENTS = \
   $(NULL)
 
 EXTRA_JS_MODULES = \
   gonk/WbxmlPduHelper.jsm \
+  gonk/SiPduHelper.jsm \
   $(NULL)
 endif
 
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/dom/wappush/src/gonk/SiPduHelper.jsm
@@ -0,0 +1,197 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+let WSP = {};
+Cu.import("resource://gre/modules/WspPduHelper.jsm", WSP);
+let WBXML = {};
+Cu.import("resource://gre/modules/WbxmlPduHelper.jsm", WBXML);
+
+// set to true to see debug messages
+let DEBUG = WBXML.DEBUG_ALL | false;
+
+/**
+ * Public identifier for SI
+ *
+ * @see http://technical.openmobilealliance.org/tech/omna/omna-wbxml-public-docid.aspx
+ */
+const PUBLIC_IDENTIFIER_SI    = "-//WAPFORUM//DTD SI 1.0//EN";
+
+/**
+ * Parse inline date encoded in OPAQUE format.
+ *
+ * @param data
+ *        A wrapped object containing raw PDU data.
+ * @param msg
+ *        Target object for decoding.
+ *
+ * @see WAP-167-SERVICEIND-20010731-A, clause 8.2.2
+ *
+ */
+this.OpaqueAsDate = {
+  decode: function decode_opaque_as_date(data) {
+    let size = WSP.UintVar.decode(data);
+    let dateBuf = [0, 0, 0, 0, 0, 0, 0];
+
+    // Maximum length for date is 7 bytes.
+    if (size > dateBuf.length)
+      size = dateBuf.length
+
+    // Read date date, non-specified parts remain 0.
+    for (let i = 0; i < size; i++) {
+      dateBuf[i] = WSP.Octet.decode(data);
+    }
+
+    // Decode and return result in "YYYY-MM-DDThh:mm:ssZ" form
+    let year = ((dateBuf[0] >> 4) & 0x0F) * 1000 + (dateBuf[0] & 0x0F) * 100 +
+               ((dateBuf[1] >> 4) & 0x0F) * 10 + (dateBuf[1] & 0x0F);
+    let month = ((dateBuf[2] >> 4) & 0x0F) * 10 + (dateBuf[2] & 0x0F);
+    let date = ((dateBuf[3] >> 4) & 0x0F) * 10 + (dateBuf[3] & 0x0F);
+    let hour = ((dateBuf[4] >> 4) & 0x0F) * 10 + (dateBuf[4] & 0x0F);
+    let minute = ((dateBuf[5] >> 4) & 0x0F) * 10 + (dateBuf[5] & 0x0F);
+    let second = ((dateBuf[6] >> 4) & 0x0F) * 10 + (dateBuf[6] & 0x0F);
+    let dateValue = new Date(Date.UTC(year, month - 1, date, hour, minute, second));
+
+    return dateValue.toISOString().replace(".000", "");
+  },
+};
+
+this.PduHelper = {
+
+  /**
+   * @param data
+   *        A wrapped object containing raw PDU data.
+   * @param contentType [optional]
+   *        Content type of incoming SI message, should be "text/vnd.wap.si" or
+   *        "application/vnd.wap.sic".
+   *        Default value is "application/vnd.wap.sic".
+   * @param msg [optional]
+   *        Optional target object for decoding.
+   *
+   * @return A SI message object or null in case of errors found.
+   */
+  parse: function parse_si(data, contentType, msg) {
+    if (!msg) {
+      msg = {};
+    }
+
+    /**
+     * Message is compressed by WBXML, decode into string.
+     *
+     * @see WAP-192-WBXML-20010725-A
+     */
+    if (!contentType || contentType === "application/vnd.wap.sic") {
+      let globalTokenOverride = {};
+      globalTokenOverride[0xC3] = {
+        number: 0xC3,
+        coder: OpaqueAsDate
+      };
+
+      let appToken = {
+        publicId: PUBLIC_IDENTIFIER_SI,
+        tagToken: SI_TAG_FIELDS,
+        attrToken: SI_ATTRIBUTE_FIELDS,
+        globalTokenOverride: globalTokenOverride
+      }
+
+      WBXML.PduHelper.parse(data, appToken, msg);
+
+      return msg;
+    }
+
+    /**
+     * Message is plain text, transform raw to string.
+     */
+    if (contentType === "text/vnd.wap.si") {
+      let stringData = WSP.Octet.decodeMultiple(data, data.array.length);
+      msg.publicId = PUBLIC_IDENTIFIER_SI;
+      msg.content = WSP.PduHelper.decodeStringContent(stringData, "UTF-8");
+      return msg;
+    }
+
+    return null;
+  },
+
+  /**
+   * @param multiStream
+   *        An exsiting nsIMultiplexInputStream.
+   * @param msg
+   *        A SI message object.
+   *
+   * @return An instance of nsIMultiplexInputStream or null in case of errors.
+   */
+  compose: function compose_si(multiStream, msg) {
+    // Composing SI message is not supported
+    return null;
+  },
+};
+
+/**
+ * Tag tokens
+ *
+ * @see WAP-167-SERVICEIND-20010731-A, clause 8.3.1
+ */
+const SI_TAG_FIELDS = (function () {
+  let names = {};
+  function add(name, number) {
+    let entry = {
+      name: name,
+      number: number,
+    };
+    names[name] = names[number] = entry;
+  }
+
+  add("si",           0x05);
+  add("indication",   0x06);
+  add("info",         0x07);
+  add("item",         0x08);
+
+  return names;
+})();
+
+/**
+ * Attribute Tokens
+ *
+ * @see WAP-167-SERVICEIND-20010731-A, clause 8.3.2
+ */
+const SI_ATTRIBUTE_FIELDS = (function () {
+  let names = {};
+  function add(name, value, number) {
+    let entry = {
+      name: name,
+      value: value,
+      number: number,
+    };
+    names[name] = names[number] = entry;
+  }
+
+  add("action",       "signal-none",    0x05);
+  add("action",       "signal-low",     0x06);
+  add("action",       "signal-medium",  0x07);
+  add("action",       "signal-high",    0x08);
+  add("action",       "delete",         0x09);
+  add("created",      "",               0x0A);
+  add("href",         "",               0x0B);
+  add("href",         "http://",        0x0C);
+  add("href",         "http://www.",    0x0D);
+  add("href",         "https://",       0x0E);
+  add("href",         "https://www.",   0x0F);
+  add("si-expires",   "",               0x10);
+  add("si-id",        "",               0x11);
+  add("class",        "",               0x12);
+  add("",             ".com/",          0x85);
+  add("",             ".edu/",          0x86);
+  add("",             ".net/",          0x87);
+  add("",             ".org/",          0x88);
+
+  return names;
+})();
+
+this.EXPORTED_SYMBOLS = [
+  // Parser
+  "PduHelper",
+];