dom/wappush/src/gonk/WapPushManager.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/wappush/src/gonk/WapPushManager.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,182 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +"use strict";
     1.9 +
    1.10 +const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
    1.11 +
    1.12 +Cu.import("resource://gre/modules/XPCOMUtils.jsm");
    1.13 +Cu.import("resource://gre/modules/Services.jsm");
    1.14 +Cu.import("resource://gre/modules/PhoneNumberUtils.jsm");
    1.15 +Cu.import("resource://gre/modules/WspPduHelper.jsm", this);
    1.16 +
    1.17 +const DEBUG = false; // set to true to see debug messages
    1.18 +
    1.19 +/**
    1.20 + * WAP Push decoders
    1.21 + */
    1.22 +XPCOMUtils.defineLazyGetter(this, "SI", function () {
    1.23 +  let SI = {};
    1.24 +  Cu.import("resource://gre/modules/SiPduHelper.jsm", SI);
    1.25 +  return SI;
    1.26 +});
    1.27 +
    1.28 +XPCOMUtils.defineLazyGetter(this, "SL", function () {
    1.29 +  let SL = {};
    1.30 +  Cu.import("resource://gre/modules/SlPduHelper.jsm", SL);
    1.31 +  return SL;
    1.32 +});
    1.33 +
    1.34 +XPCOMUtils.defineLazyGetter(this, "CP", function () {
    1.35 +  let CP = {};
    1.36 +  Cu.import("resource://gre/modules/CpPduHelper.jsm", CP);
    1.37 +  return CP;
    1.38 +});
    1.39 +
    1.40 +XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger",
    1.41 +                                   "@mozilla.org/system-message-internal;1",
    1.42 +                                   "nsISystemMessagesInternal");
    1.43 +XPCOMUtils.defineLazyServiceGetter(this, "gRIL",
    1.44 +                                   "@mozilla.org/ril;1",
    1.45 +                                   "nsIRadioInterfaceLayer");
    1.46 +
    1.47 +/**
    1.48 + * Helpers for WAP PDU processing.
    1.49 + */
    1.50 +this.WapPushManager = {
    1.51 +
    1.52 +  /**
    1.53 +   * Parse raw PDU data and deliver to a proper target.
    1.54 +   *
    1.55 +   * @param data
    1.56 +   *        A wrapped object containing raw PDU data.
    1.57 +   * @param options
    1.58 +   *        Extra context for decoding.
    1.59 +   */
    1.60 +  processMessage: function processMessage(data, options) {
    1.61 +    try {
    1.62 +      PduHelper.parse(data, true, options);
    1.63 +      debug("options: " + JSON.stringify(options));
    1.64 +    } catch (ex) {
    1.65 +      debug("Failed to parse sessionless WSP PDU: " + ex.message);
    1.66 +      return;
    1.67 +    }
    1.68 +
    1.69 +    let appid = options.headers["x-wap-application-id"];
    1.70 +    if (!appid) {
    1.71 +      // Assume message without applicatioin ID is WAP Push
    1.72 +      debug("Push message doesn't contains X-Wap-Application-Id.");
    1.73 +    }
    1.74 +
    1.75 +    // MMS
    1.76 +    if (appid == "x-wap-application:mms.ua") {
    1.77 +      let mmsService = Cc["@mozilla.org/mms/rilmmsservice;1"]
    1.78 +                       .getService(Ci.nsIMmsService);
    1.79 +      mmsService.QueryInterface(Ci.nsIWapPushApplication)
    1.80 +                .receiveWapPush(data.array, data.array.length, data.offset, options);
    1.81 +      return;
    1.82 +    }
    1.83 +
    1.84 +    /**
    1.85 +    * Non-MMS, handled according to content type
    1.86 +    *
    1.87 +    * WAP Type            content-type                              x-wap-application-id
    1.88 +    * MMS                 "application/vnd.wap.mms-message"         "x-wap-application:mms.ua"
    1.89 +    * SI                  "text/vnd.wap.si"                         "x-wap-application:wml.ua"
    1.90 +    * SI(WBXML)           "application/vnd.wap.sic"                 "x-wap-application:wml.ua"
    1.91 +    * SL                  "text/vnd.wap.sl"                         "x-wap-application:wml.ua"
    1.92 +    * SL(WBXML)           "application/vnd.wap.slc"                 "x-wap-application:wml.ua"
    1.93 +    * Provisioning        "text/vnd.wap.connectivity-xml"           "x-wap-application:wml.ua"
    1.94 +    * Provisioning(WBXML) "application/vnd.wap.connectivity-wbxml"  "x-wap-application:wml.ua"
    1.95 +    *
    1.96 +    * @see http://technical.openmobilealliance.org/tech/omna/omna-wsp-content-type.aspx
    1.97 +    */
    1.98 +    let contentType = options.headers["content-type"].media;
    1.99 +    let msg;
   1.100 +    let authInfo = null;
   1.101 +
   1.102 +    if (contentType === "text/vnd.wap.si" ||
   1.103 +        contentType === "application/vnd.wap.sic") {
   1.104 +      msg = SI.PduHelper.parse(data, contentType);
   1.105 +    } else if (contentType === "text/vnd.wap.sl" ||
   1.106 +               contentType === "application/vnd.wap.slc") {
   1.107 +      msg = SL.PduHelper.parse(data, contentType);
   1.108 +    } else if (contentType === "text/vnd.wap.connectivity-xml" ||
   1.109 +               contentType === "application/vnd.wap.connectivity-wbxml") {
   1.110 +      // Apply HMAC authentication on WBXML encoded CP message.
   1.111 +      if (contentType === "application/vnd.wap.connectivity-wbxml") {
   1.112 +        let params = options.headers["content-type"].params;
   1.113 +        let sec = params && params.sec;
   1.114 +        let mac = params && params.mac;
   1.115 +        authInfo = CP.Authenticator.check(data.array.subarray(data.offset),
   1.116 +                                          sec, mac, function getNetworkPin() {
   1.117 +          let imsi = gRIL.getRadioInterface(options.serviceId).rilContext.imsi;
   1.118 +          return CP.Authenticator.formatImsi(imsi);
   1.119 +        });
   1.120 +      }
   1.121 +
   1.122 +      msg = CP.PduHelper.parse(data, contentType);
   1.123 +    } else {
   1.124 +      // Unsupported type, provide raw data.
   1.125 +      msg = {
   1.126 +        contentType: contentType,
   1.127 +        content: data.array
   1.128 +      };
   1.129 +      msg.content.length = data.array.length;
   1.130 +    }
   1.131 +
   1.132 +    let sender = PhoneNumberUtils.normalize(options.sourceAddress, false);
   1.133 +    let parsedSender = PhoneNumberUtils.parse(sender);
   1.134 +    if (parsedSender && parsedSender.internationalNumber) {
   1.135 +      sender = parsedSender.internationalNumber;
   1.136 +    }
   1.137 +
   1.138 +    gSystemMessenger.broadcastMessage("wappush-received", {
   1.139 +      sender:         sender,
   1.140 +      contentType:    msg.contentType,
   1.141 +      content:        msg.content,
   1.142 +      authInfo:       authInfo,
   1.143 +      serviceId:      options.serviceId
   1.144 +    });
   1.145 +  },
   1.146 +
   1.147 +  /**
   1.148 +   * @param array
   1.149 +   *        A Uint8Array or an octet array representing raw PDU data.
   1.150 +   * @param length
   1.151 +   *        Length of the array.
   1.152 +   * @param offset
   1.153 +   *        Offset of the array that a raw PDU data begins.
   1.154 +   * @param options
   1.155 +   *        WDP bearer information.
   1.156 +   */
   1.157 +  receiveWdpPDU: function receiveWdpPDU(array, length, offset, options) {
   1.158 +    if ((options.bearer == null) || !options.sourceAddress
   1.159 +        || (options.sourcePort == null) || !array) {
   1.160 +      debug("Incomplete WDP PDU");
   1.161 +      return;
   1.162 +    }
   1.163 +
   1.164 +    if (options.destinationPort != WDP_PORT_PUSH) {
   1.165 +      debug("Not WAP Push port: " + options.destinationPort);
   1.166 +      return;
   1.167 +    }
   1.168 +
   1.169 +    this.processMessage({array: array, offset: offset}, options);
   1.170 +  },
   1.171 +};
   1.172 +
   1.173 +let debug;
   1.174 +if (DEBUG) {
   1.175 +  debug = function (s) {
   1.176 +    dump("-*- WapPushManager: " + s + "\n");
   1.177 +  };
   1.178 +} else {
   1.179 +  debug = function (s) {};
   1.180 +}
   1.181 +
   1.182 +this.EXPORTED_SYMBOLS = ALL_CONST_SYMBOLS.concat([
   1.183 +  "WapPushManager",
   1.184 +]);
   1.185 +

mercurial