Bug 910091: add cdmaServiceCategory to CellBroadcastMessage. r=vicamo
authorna-kobayashi <na-kobayashi@kddi-tech.com>
Mon, 28 Oct 2013 15:06:48 +0900
changeset 152679 09d749f0368bc52e0b7cd3ab4a036e956e92e8c6
parent 152678 2359a63c86068b43cef49452f6df1b57012ab73e
child 152680 ac5de341a26b2a05ebe5e66e0b3938efd97f6993
push id35608
push useremorley@mozilla.com
push dateTue, 29 Oct 2013 16:36:07 +0000
treeherdermozilla-inbound@936a5d4b340d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvicamo
bugs910091
milestone27.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 910091: add cdmaServiceCategory to CellBroadcastMessage. r=vicamo
dom/cellbroadcast/interfaces/nsIDOMMozCellBroadcastMessage.idl
dom/cellbroadcast/tests/marionette/test_cellbroadcast_etws.js
dom/cellbroadcast/tests/marionette/test_cellbroadcast_gsm.js
dom/system/gonk/RILContentHelper.js
dom/system/gonk/RadioInterfaceLayer.js
dom/system/gonk/ril_consts.js
dom/system/gonk/ril_worker.js
--- a/dom/cellbroadcast/interfaces/nsIDOMMozCellBroadcastMessage.idl
+++ b/dom/cellbroadcast/interfaces/nsIDOMMozCellBroadcastMessage.idl
@@ -5,26 +5,26 @@
 #include "nsISupports.idl"
 
 interface nsIDOMMozCellBroadcastEtwsInfo;
 
 /**
  * MozCellBroadcastMessage encapsulates Cell Broadcast short message service
  * (CBS) messages.
  */
-[scriptable, uuid(cb210e8b-ad9c-4052-b70c-02ec0c25d669)]
+[scriptable, uuid(6abe65de-6729-41f7-906a-3f3a2dbe30ae)]
 interface nsIDOMMozCellBroadcastMessage : nsISupports
 {
   /**
    * Indication of the geographical area over which the Message Code is unique,
    * and the display mode.
    *
    * Possible values are: "cell-immediate", "plmn", "location-area" and "cell".
    */
-  readonly attribute DOMString geographicalScope;
+  readonly attribute DOMString gsmGeographicalScope;
 
   /**
    * The Message Code differentiates between messages from the same source and
    * type (e.g., with the same Message Identifier).
    */
   readonly attribute unsigned short messageCode;
 
   /**
@@ -54,16 +54,21 @@ interface nsIDOMMozCellBroadcastMessage 
    * System time stamp at receival.
    */
   readonly attribute jsval timestamp; // jsval is for Date.
 
   /**
    * Additional ETWS-specific info.
    */
   readonly attribute nsIDOMMozCellBroadcastEtwsInfo etws;
+
+  /**
+   * Service Category.
+   */
+  readonly attribute long cdmaServiceCategory;
 };
 
 /**
  * ETWS (Earthquake and Tsunami Warning service) Primary Notification message
  * specific information.
  */
 [scriptable, uuid(af009d9a-f5e8-4573-a6ee-a85118465bed)]
 interface nsIDOMMozCellBroadcastEtwsInfo : nsISupports
--- a/dom/cellbroadcast/tests/marionette/test_cellbroadcast_etws.js
+++ b/dom/cellbroadcast/tests/marionette/test_cellbroadcast_etws.js
@@ -97,30 +97,31 @@ function testEtwsMessageAttributes() {
     // ok(event instanceof MozCellBroadcastEvent,
     //    "event is instanceof " + event.constructor)
     ok(event, "event is valid");
 
     let message = event.message;
     ok(message, "event.message is valid");
 
     // Attributes other than `language` and `body` should always be assigned.
-    ok(message.geographicalScope != null, "message.geographicalScope");
+    ok(message.gsmGeographicalScope != null, "message.gsmGeographicalScope");
     ok(message.messageCode != null, "message.messageCode");
     ok(message.messageId != null, "message.messageId");
     ok('language' in message, "message.language");
     ok(message.language == null, "message.language");
     ok('body' in message, "message.body");
     ok(message.body == null, "message.body");
     is(message.messageClass, "normal", "message.messageClass");
     ok(message.timestamp != null, "message.timestamp");
     ok(message.etws != null, "message.etws");
     ok(message.etws.warningType != null, "message.etws.warningType");
     ok(message.etws.emergencyUserAlert != null,
        "message.etws.emergencyUserAlert");
     ok(message.etws.popup != null, "message.etws.popup");
+    ok(message.cdmaServiceCategory != null, "message.cdmaServiceCategory");
 
     window.setTimeout(testReceiving_ETWS_GeographicalScope, 0);
   });
 
   // Here we use a simple ETWS message for test.
   let pdu = buildHexStr(0, CB_MESSAGE_SIZE_ETWS * 2); // 6 octets
   sendCellBroadcastMessage(pdu);
 }
@@ -129,18 +130,18 @@ function testReceiving_ETWS_Geographical
   log("Test receiving ETWS Primary Notification - Geographical Scope");
 
   function do_test(gs, nextTest) {
     // Here we use a simple ETWS message for test.
     let pdu = buildHexStr(((gs & 0x03) << 14), 4)
             + buildHexStr(0, (CB_MESSAGE_SIZE_ETWS - 2) * 2);
 
     doTestHelper(pdu, nextTest, function (message) {
-      is(message.geographicalScope, CB_GSM_GEOGRAPHICAL_SCOPE_NAMES[gs],
-         "message.geographicalScope");
+      is(message.gsmGeographicalScope, CB_GSM_GEOGRAPHICAL_SCOPE_NAMES[gs],
+         "message.gsmGeographicalScope");
     });
   }
 
   repeat(do_test, seq(CB_GSM_GEOGRAPHICAL_SCOPE_NAMES.length),
          testReceiving_ETWS_MessageCode);
 }
 
 function testReceiving_ETWS_MessageCode() {
--- a/dom/cellbroadcast/tests/marionette/test_cellbroadcast_gsm.js
+++ b/dom/cellbroadcast/tests/marionette/test_cellbroadcast_gsm.js
@@ -152,29 +152,30 @@ function testGsmMessageAttributes() {
     // ok(event instanceof MozCellBroadcastEvent,
     //    "event is instanceof " + event.constructor)
     ok(event, "event is valid");
 
     let message = event.message;
     ok(message, "event.message is valid");
 
     // Attributes other than `language` and `body` should always be assigned.
-    ok(message.geographicalScope != null, "message.geographicalScope");
+    ok(message.gsmGeographicalScope != null, "message.gsmGeographicalScope");
     ok(message.messageCode != null, "message.messageCode");
     ok(message.messageId != null, "message.messageId");
     ok(message.language != null, "message.language");
     ok(message.body != null, "message.body");
     ok(message.messageClass != null, "message.messageClass");
     ok(message.timestamp != null, "message.timestamp");
     ok('etws' in message, "message.etws");
     if (message.etws) {
       ok('warningType' in message.etws, "message.etws.warningType");
       ok(message.etws.emergencyUserAlert != null, "message.etws.emergencyUserAlert");
       ok(message.etws.popup != null, "message.etws.popup");
     }
+    ok(message.cdmaServiceCategory != null, "message.cdmaServiceCategory");
 
     window.setTimeout(testReceiving_GSM_GeographicalScope, 0);
   });
 
   // Here we use a simple GSM message for test.
   let pdu = buildHexStr(0, CB_MESSAGE_SIZE_GSM * 2);
   sendCellBroadcastMessage(pdu);
 }
@@ -182,18 +183,18 @@ function testGsmMessageAttributes() {
 function testReceiving_GSM_GeographicalScope() {
   log("Test receiving GSM Cell Broadcast - Geographical Scope");
 
   function do_test(gs, nextTest) {
     let pdu = buildHexStr(((gs & 0x03) << 14), 4)
             + buildHexStr(0, (CB_MESSAGE_SIZE_GSM - 2) * 2);
 
     doTestHelper(pdu, nextTest, function (message) {
-      is(message.geographicalScope, CB_GSM_GEOGRAPHICAL_SCOPE_NAMES[gs],
-         "message.geographicalScope");
+      is(message.gsmGeographicalScope, CB_GSM_GEOGRAPHICAL_SCOPE_NAMES[gs],
+         "message.gsmGeographicalScope");
     });
   }
 
   repeat(do_test, seq(CB_GSM_GEOGRAPHICAL_SCOPE_NAMES.length),
          testReceiving_GSM_MessageCode);
 }
 
 function testReceiving_GSM_MessageCode() {
@@ -435,17 +436,36 @@ function testReceiving_GSM_Multipart() {
     }
 
     doTestHelper(pdus, nextTest, function (message) {
       is(message.body.length, (numParts * CB_MAX_CONTENT_7BIT),
          "message.body");
     });
   }
 
-  repeat(do_test, seq(16, 1), cleanUp);
+  repeat(do_test, seq(16, 1), testReceiving_GSM_ServiceCategory);
+}
+
+function testReceiving_GSM_ServiceCategory() {
+  log("Test receiving GSM Cell Broadcast - Service Category");
+
+  cbs.addEventListener("received", function onreceived(event) {
+    cbs.removeEventListener("received", onreceived);
+
+    let message = event.message;
+
+    // Bug 910091
+    // "Service Category" is not defined in GSM.  We should always get '0' here.
+    is(message.cdmaServiceCategory, 0, "message.cdmaServiceCategory");
+
+    window.setTimeout(cleanUp, 0);
+  });
+
+  let pdu = buildHexStr(0, CB_MESSAGE_SIZE_GSM * 2);
+  sendCellBroadcastMessage(pdu);
 }
 
 function cleanUp() {
   if (pendingEmulatorCmdCount > 0) {
     window.setTimeout(cleanUp, 100);
     return;
   }
 
--- a/dom/system/gonk/RILContentHelper.js
+++ b/dom/system/gonk/RILContentHelper.js
@@ -313,49 +313,52 @@ MobileCFInfo.prototype = {
   action: -1,
   reason: -1,
   number: null,
   timeSeconds: 0,
   serviceClass: -1
 };
 
 function CellBroadcastMessage(pdu) {
-  this.geographicalScope = RIL.CB_GSM_GEOGRAPHICAL_SCOPE_NAMES[pdu.geographicalScope];
+  this.gsmGeographicalScope = RIL.CB_GSM_GEOGRAPHICAL_SCOPE_NAMES[pdu.geographicalScope];
   this.messageCode = pdu.messageCode;
   this.messageId = pdu.messageId;
   this.language = pdu.language;
   this.body = pdu.fullBody;
   this.messageClass = pdu.messageClass;
   this.timestamp = new Date(pdu.timestamp);
 
   if (pdu.etws != null) {
     this.etws = new CellBroadcastEtwsInfo(pdu.etws);
   }
+
+  this.cdmaServiceCategory = pdu.serviceCategory;
 }
 CellBroadcastMessage.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMMozCellBroadcastMessage]),
   classID:        CELLBROADCASTMESSAGE_CID,
   classInfo:      XPCOMUtils.generateCI({
     classID:          CELLBROADCASTMESSAGE_CID,
     classDescription: "CellBroadcastMessage",
     flags:            Ci.nsIClassInfo.DOM_OBJECT,
     interfaces:       [Ci.nsIDOMMozCellBroadcastMessage]
   }),
 
   // nsIDOMMozCellBroadcastMessage
 
-  geographicalScope: null,
+  gsmGeographicalScope: null,
   messageCode: null,
   messageId: null,
   language: null,
   body: null,
   messageClass: null,
   timestamp: null,
 
-  etws: null
+  etws: null,
+  cdmaServiceCategory: null
 };
 
 function CellBroadcastEtwsInfo(etwsInfo) {
   if (etwsInfo.warningType != null) {
     this.warningType = RIL.CB_ETWS_WARNING_TYPE_NAMES[etwsInfo.warningType];
   }
   this.emergencyUserAlert = etwsInfo.emergencyUserAlert;
   this.popup = etwsInfo.popup;
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -1055,16 +1055,17 @@ RadioInterface.prototype = {
                                        this.clientId, message);
         break;
       case "sms-received":
         let ackOk = this.handleSmsReceived(message);
         if (ackOk) {
           this.workerMessenger.send("ackSMS", { result: RIL.PDU_FCS_OK });
         }
         return;
+      case "broadcastsms-received":
       case "cellbroadcast-received":
         message.timestamp = Date.now();
         gMessageManager.sendCellBroadcastMessage("RIL:CellBroadcastReceived",
                                                  this.clientId, message);
         break;
       case "datacallstatechange":
         this.handleDataCallState(message);
         break;
--- a/dom/system/gonk/ril_consts.js
+++ b/dom/system/gonk/ril_consts.js
@@ -2758,18 +2758,25 @@ this.PDU_CDMA_MSG_CODING_GSM_DCS = 0x0A;
 this.PDU_CDMA_MSG_TYPE_DELIVER = 0x01;        // Receive
 this.PDU_CDMA_MSG_TYPE_SUBMIT = 0x02;         // Send
 
 // SMS User Data Subparameters, as defined in 3GPP2 C.S0015-A v2.0, Table 4.5-1
 this.PDU_CDMA_MSG_USERDATA_MSG_ID = 0x00;           // Message Identifier
 this.PDU_CDMA_MSG_USERDATA_BODY = 0x01;             // User Data Body
 this.PDU_CDMA_MSG_USERDATA_TIMESTAMP = 0x03;        // Message Center Time Stamp
 this.PDU_CDMA_REPLY_OPTION = 0x0A;                  // Reply Option
+this.PDU_CDMA_LANGUAGE_INDICATOR = 0x0D;            // Language Indicator
 this.PDU_CDMA_MSG_USERDATA_CALLBACK_NUMBER = 0x0E;  // Callback Number
 
+// CDMA Language Indicator: Language groups
+// see 3GPP2 C.R1001-F table 9.2-1
+this.CB_CDMA_LANG_GROUP = [
+  null, "en", "fr", "es", "ja", "ko", "zh", "he"
+];
+
 // IS-91 Message Type, as defined in TIA/EIA/IS-91-A, Table 9
 this.PDU_CDMA_MSG_CODING_IS_91_TYPE_VOICEMAIL_STATUS = 0x82;
 this.PDU_CDMA_MSG_CODING_IS_91_TYPE_SMS_FULL = 0x83;
 this.PDU_CDMA_MSG_CODING_IS_91_TYPE_CLI = 0x84;
 this.PDU_CDMA_MSG_CODING_IS_91_TYPE_SMS = 0x85;
 
 // CDMA roaming preference mode
 this.CDMA_ROAMING_PREFERENCE_HOME = 0;
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -4215,17 +4215,23 @@ let RIL = {
 
     if (message) {
       message.result = PDU_FCS_OK;
       if (message.messageClass == GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_2]) {
         // `MS shall ensure that the message has been to the SMS data field in
         // the (U)SIM before sending an ACK to the SC.`  ~ 3GPP 23.038 clause 4
         message.result = PDU_FCS_RESERVED;
       }
-      message.rilMessageType = "sms-received";
+
+      if (message.messageType == PDU_CDMA_MSG_TYPE_BROADCAST) {
+        message.rilMessageType = "broadcastsms-received";
+      } else {
+        message.rilMessageType = "sms-received";
+      }
+
       this.sendChromeMessage(message);
 
       // We will acknowledge receipt of the SMS after we try to store it
       // in the database.
       return MOZ_FCS_WAIT_FOR_EXPLICIT_ACK;
     }
 
     return PDU_FCS_OK;
@@ -8805,35 +8811,38 @@ let CdmaPDUHelper = {
       message.sender += String.fromCharCode(addrDigit);
     }
 
     // User Data
     this.decodeUserData(message);
 
     // Transform message to GSM msg
     let msg = {
-      SMSC:           "",
-      mti:            0,
-      udhi:           0,
-      sender:         message.sender,
-      recipient:      null,
-      pid:            PDU_PID_DEFAULT,
-      epid:           PDU_PID_DEFAULT,
-      dcs:            0,
-      mwi:            null, //message[PDU_CDMA_MSG_USERDATA_BODY].header ? message[PDU_CDMA_MSG_USERDATA_BODY].header.mwi : null,
-      replace:        false,
-      header:         message[PDU_CDMA_MSG_USERDATA_BODY].header,
-      body:           message[PDU_CDMA_MSG_USERDATA_BODY].body,
-      data:           null,
-      timestamp:      message[PDU_CDMA_MSG_USERDATA_TIMESTAMP],
-      status:         null,
-      scts:           null,
-      dt:             null,
-      encoding:       message[PDU_CDMA_MSG_USERDATA_BODY].encoding,
-      messageClass:   GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]
+      SMSC:            "",
+      mti:             0,
+      udhi:            0,
+      sender:          message.sender,
+      recipient:       null,
+      pid:             PDU_PID_DEFAULT,
+      epid:            PDU_PID_DEFAULT,
+      dcs:             0,
+      mwi:             null, //message[PDU_CDMA_MSG_USERDATA_BODY].header ? message[PDU_CDMA_MSG_USERDATA_BODY].header.mwi : null,
+      replace:         false,
+      header:          message[PDU_CDMA_MSG_USERDATA_BODY].header,
+      body:            message[PDU_CDMA_MSG_USERDATA_BODY].body,
+      data:            null,
+      timestamp:       message[PDU_CDMA_MSG_USERDATA_TIMESTAMP],
+      language:        message[PDU_CDMA_LANGUAGE_INDICATOR],
+      status:          null,
+      scts:            null,
+      dt:              null,
+      encoding:        message[PDU_CDMA_MSG_USERDATA_BODY].encoding,
+      messageClass:    GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL],
+      messageType:     message.messageType,
+      serviceCategory: message.service
     };
 
     return msg;
   },
 
 
   /**
    * Helper for processing received SMS parcel data.
@@ -8925,16 +8934,19 @@ let CdmaPDUHelper = {
           message[id] = this.decodeUserDataMsg(message[PDU_CDMA_MSG_USERDATA_MSG_ID].userHeader);
           break;
         case PDU_CDMA_MSG_USERDATA_TIMESTAMP:
           message[id] = this.decodeUserDataTimestamp();
           break;
         case PDU_CDMA_REPLY_OPTION:
           message[id] = this.decodeUserDataReplyAction();
           break;
+        case PDU_CDMA_LANGUAGE_INDICATOR:
+          message[id] = this.decodeLanguageIndicator();
+          break;
         case PDU_CDMA_MSG_USERDATA_CALLBACK_NUMBER:
           message[id] = this.decodeUserDataCallbackNumber();
           break;
       }
 
       userDataLength -= (length + 2);
       userDataBuffer = [];
     }
@@ -9306,16 +9318,27 @@ let CdmaPDUHelper = {
                    readAck: (replyAction & 0x2) ? true : false,
                    report: (replyAction & 0x1) ? true : false
                  };
 
     return result;
   },
 
   /**
+   * User data subparameter decoder : Language Indicator
+   *
+   * @see 3GGP2 C.S0015-B 2.0, 4.5.14 Language Indicator
+   */
+  decodeLanguageIndicator: function cdma_decodeLanguageIndicator() {
+    let language = BitBufferHelper.readBits(8);
+    let result = CB_CDMA_LANG_GROUP[language];
+    return result;
+  },
+
+  /**
    * User data subparameter decoder : Call-Back Number
    *
    * @see 3GGP2 C.S0015-B 2.0, 4.5.15 Call-Back Number
    */
   decodeUserDataCallbackNumber: function cdma_decodeUserDataCallbackNumber() {
     let digitMode = BitBufferHelper.readBits(1);
     if (digitMode) {
       let numberType = BitBufferHelper.readBits(3),