Bug 768441 - Part 1: Support Stored Message Waiting Indicators. r=vyang
authorBevis Tseng <btseng@mozilla.com>
Fri, 06 Dec 2013 17:35:13 +0800
changeset 160335 9b08b5ca29095f69e9534c16e6a9c0c2afb9462a
parent 160334 2768c8b69ee31244ba37183574750236ee4ebe2b
child 160336 2ea15bd93a1b8f99fc561aa3360f03b8decc8ea2
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersvyang
bugs768441
milestone29.0a1
Bug 768441 - Part 1: Support Stored Message Waiting Indicators. r=vyang
dom/system/gonk/RadioInterfaceLayer.js
dom/system/gonk/ril_consts.js
dom/system/gonk/ril_worker.js
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -1253,16 +1253,20 @@ RadioInterface.prototype = {
         this.handleIccInfoChange(message);
         break;
       case "iccimsi":
         this.rilContext.imsi = message.imsi;
         break;
       case "iccmbdn":
         this.handleIccMbdn(message);
         break;
+      case "iccmwis":
+        gMessageManager.sendVoicemailMessage("RIL:VoicemailNotification",
+                                             this.clientId, message.mwi);
+        break;
       case "USSDReceived":
         if (DEBUG) this.debug("USSDReceived " + JSON.stringify(message));
         this.handleUSSDReceived(message);
         break;
       case "stkcommand":
         this.handleStkProactiveCommand(message);
         break;
       case "stksessionend":
@@ -2099,21 +2103,16 @@ RadioInterface.prototype = {
                                                message.read);
 
       Services.obs.notifyObservers(domMessage,
                                    kSilentSmsReceivedObserverTopic,
                                    null);
       return true;
     }
 
-    // TODO: Bug #768441
-    // For now we don't store indicators persistently. When the mwi.discard
-    // flag is false, we'll need to persist the indicator to EFmwis.
-    // See TS 23.040 9.2.3.24.2
-
     let mwi = message.mwi;
     if (mwi) {
       mwi.returnNumber = message.sender;
       mwi.returnMessage = message.fullBody;
       gMessageManager.sendVoicemailMessage("RIL:VoicemailNotification",
                                            this.clientId, mwi);
 
       // Dicarded MWI comes without text body.
--- a/dom/system/gonk/ril_consts.js
+++ b/dom/system/gonk/ril_consts.js
@@ -1201,31 +1201,33 @@ this.GECKO_ICC_SERVICES = {
     SDN: 18,
     DATA_DOWNLOAD_SMS_CB: 25,
     DATA_DOWNLOAD_SMS_PP: 26,
     CBMIR: 30,
     BDN: 31,
     PNN: 51,
     OPL: 52,
     MDN: 53,
+    MWIS: 54,
     SPDI: 56
   },
   usim: {
     FDN: 2,
     SDN: 4,
     BDN: 6,
     CBMI: 15,
     CBMIR: 16,
     SPN: 19,
     MSISDN: 21,
     DATA_DOWNLOAD_SMS_PP: 28,
     DATA_DOWNLOAD_SMS_CB: 29,
     PNN: 45,
     OPL: 46,
     MDN: 47,
+    MWIS: 48,
     SPDI: 51
   },
   ruim: {
     ENHANCED_PHONEBOOK: 6,
     SPN: 17
   }
 };
 
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -4201,16 +4201,21 @@ let RIL = {
       if (message.messageType == PDU_CDMA_MSG_TYPE_BROADCAST) {
         message.rilMessageType = "broadcastsms-received";
       } else {
         message.rilMessageType = "sms-received";
       }
 
       this.sendChromeMessage(message);
 
+      // Update MWI Status into ICC if present.
+      if (message.mwi && ICCUtilsHelper.isICCServiceAvailable("MWIS")) {
+        SimRecordHelper.updateMWIS(message.mwi);
+      }
+
       // 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;
   },
 
@@ -10932,16 +10937,17 @@ let ICCFileHelper = {
   getSimEFPath: function getSimEFPath(fileId) {
     switch (fileId) {
       case ICC_EF_FDN:
       case ICC_EF_MSISDN:
       case ICC_EF_SMS:
         return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM;
       case ICC_EF_AD:
       case ICC_EF_MBDN:
+      case ICC_EF_MWIS:
       case ICC_EF_PLMNsel:
       case ICC_EF_SPN:
       case ICC_EF_SPDI:
       case ICC_EF_SST:
       case ICC_EF_PHASE:
       case ICC_EF_CBMI:
       case ICC_EF_CBMID:
       case ICC_EF_CBMIR:
@@ -10956,16 +10962,17 @@ let ICCFileHelper = {
   /**
    * This function handles EFs for USIM.
    */
   getUSimEFPath: function getUSimEFPath(fileId) {
     switch (fileId) {
       case ICC_EF_AD:
       case ICC_EF_FDN:
       case ICC_EF_MBDN:
+      case ICC_EF_MWIS:
       case ICC_EF_UST:
       case ICC_EF_MSISDN:
       case ICC_EF_SPN:
       case ICC_EF_SPDI:
       case ICC_EF_CBMI:
       case ICC_EF_CBMID:
       case ICC_EF_CBMIR:
       case ICC_EF_OPL:
@@ -11911,16 +11918,23 @@ let SimRecordHelper = {
 
       if (ICCUtilsHelper.isICCServiceAvailable("MDN")) {
         if (DEBUG) debug("MDN: MDN available.");
         this.readMBDN();
       } else {
         if (DEBUG) debug("MDN: MDN service is not available");
       }
 
+      if (ICCUtilsHelper.isICCServiceAvailable("MWIS")) {
+        if (DEBUG) debug("MWIS: MWIS is available");
+        this.readMWIS();
+      } else {
+        if (DEBUG) debug("MWIS: MWIS is not available");
+      }
+
       if (ICCUtilsHelper.isICCServiceAvailable("SPDI")) {
         if (DEBUG) debug("SPDI: SPDI available.");
         this.readSPDI();
       } else {
         if (DEBUG) debug("SPDI: SPDI service is not available");
       }
 
       if (ICCUtilsHelper.isICCServiceAvailable("PNN")) {
@@ -11981,16 +11995,101 @@ let SimRecordHelper = {
       RIL.sendChromeMessage(contact);
     }
 
     ICCIOHelper.loadLinearFixedEF({fileId: ICC_EF_MBDN,
                                    callback: callback.bind(this)});
   },
 
   /**
+   * Read ICC MWIS. (Message Waiting Indication Status)
+   *
+   * @see TS 31.102, clause 4.2.63 for USIM and TS 51.011, clause 10.3.45 for SIM.
+   */
+  readMWIS: function readMWIS() {
+    function callback(options) {
+      let strLen = Buf.readInt32();
+      // Each octet is encoded into two chars.
+      let octetLen = strLen / 2;
+      let mwis = GsmPDUHelper.readHexOctetArray(octetLen);
+      Buf.readStringDelimiter(strLen);
+      if (!mwis) {
+        return;
+      }
+      RIL.iccInfoPrivate.mwis = mwis; //Keep raw MWIS for updateMWIS()
+
+      let mwi = {};
+      // b8 b7 B6 b5 b4 b3 b2 b1   4.2.63, TS 31.102 version 11.6.0
+      //  |  |  |  |  |  |  |  |__ Voicemail
+      //  |  |  |  |  |  |  |_____ Fax
+      //  |  |  |  |  |  |________ Electronic Mail
+      //  |  |  |  |  |___________ Other
+      //  |  |  |  |______________ Videomail
+      //  |__|__|_________________ RFU
+      mwi.active = ((mwis[0] & 0x01) != 0);
+
+      if (mwi.active) {
+        // In TS 23.040 msgCount is in the range from 0 to 255.
+        // The value 255 shall be taken to mean 255 or greater.
+        //
+        // However, There is no definition about 0 when MWI is active.
+        //
+        // Normally, when mwi is active, the msgCount must be larger than 0.
+        // Refer to other reference phone,
+        // 0 is usually treated as UNKNOWN for storing 2nd level MWI status (DCS).
+        mwi.msgCount = (mwis[1] === 0) ? GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN
+                                       : mwis[1];
+      } else {
+        mwi.msgCount = 0;
+      }
+
+      RIL.sendChromeMessage({ rilMessageType: "iccmwis",
+                              mwi: mwi });
+    }
+
+    ICCIOHelper.loadLinearFixedEF({ fileId: ICC_EF_MWIS,
+                                    recordNumber: 1, // Get 1st Subscriber Profile.
+                                    callback: callback });
+  },
+
+  /**
+   * Update ICC MWIS. (Message Waiting Indication Status)
+   *
+   * @see TS 31.102, clause 4.2.63 for USIM and TS 51.011, clause 10.3.45 for SIM.
+   */
+  updateMWIS: function updateMWIS(mwi) {
+    if (!RIL.iccInfoPrivate.mwis) {
+      return;
+    }
+
+    function dataWriter(recordSize) {
+      let mwis = RIL.iccInfoPrivate.mwis;
+
+      let msgCount =
+          (mwi.msgCount === GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN) ? 0 : mwi.msgCount;
+
+      [mwis[0], mwis[1]] = (mwi.active) ? [(mwis[0] | 0x01), msgCount]
+                                        : [(mwis[0] & 0xFE), 0];
+
+      let strLen = recordSize * 2;
+      Buf.writeInt32(strLen);
+
+      for (let i = 0; i < mwis.length; i++) {
+        GsmPDUHelper.writeHexOctet(mwis[i]);
+      }
+
+      Buf.writeStringDelimiter(strLen);
+    }
+
+    ICCIOHelper.updateLinearFixedEF({ fileId: ICC_EF_MWIS,
+                                      recordNumber: 1, // Update 1st Subscriber Profile.
+                                      dataWriter: dataWriter });
+  },
+
+  /**
    * Read the SPDI (Service Provider Display Information) from the (U)SIM.
    *
    * See TS 131.102 section 4.2.66 for USIM and TS 51.011 section 10.3.50
    * for SIM.
    */
   readSPDI: function readSPDI() {
     function callback() {
       let strLen = Buf.readInt32();