Bug 768441 - Part 1: Support Stored Message Waiting Indicators. r=vyang
--- 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();