зеркало из https://github.com/mozilla/gecko-dev.git
Bug 736706 - Part 4: Handle Message Class 2, r=philikon
This commit is contained in:
Родитель
dbe0f38b77
Коммит
ab5011a770
|
@ -449,6 +449,13 @@ const EF_TYPE_TRANSPARENT = 0;
|
|||
const EF_TYPE_LINEAR_FIXED = 1;
|
||||
const EF_TYPE_CYCLIC = 3;
|
||||
|
||||
// Status code of EFsms
|
||||
// see 3GPP TS 51.011 clause 10.5.3
|
||||
const EFSMS_STATUS_FREE = 0x00;
|
||||
const EFSMS_STATUS_READ = 0x01;
|
||||
const EFSMS_STATUS_TO_BE_READ = 0x03;
|
||||
const EFSMS_STATUS_TO_BE_SENT = 0x07;
|
||||
|
||||
// For retrieving MSISDN, TS 151.011 clause 10.5.5
|
||||
const MSISDN_FOOTER_SIZE_BYTES = 14;
|
||||
const MSISDN_MAX_NUMBER_SIZE_BYTES = 10;
|
||||
|
@ -471,6 +478,7 @@ const EF_PATH_ADF_USIM = "7fff";
|
|||
// see GSM11.11 and TS 51.011 clause 9.4, and ISO 7816-4
|
||||
const ICC_STATUS_NORMAL_ENDING = 0x90;
|
||||
const ICC_STATUS_NORMAL_ENDING_WITH_EXTRA = 0x91;
|
||||
const ICC_STATUS_SAT_BUSY = 0x93;
|
||||
const ICC_STATUS_WITH_SIM_DATA = 0x9e;
|
||||
const ICC_STATUS_WITH_RESPONSE_DATA = 0x9f;
|
||||
const ICC_STATUS_ERROR_WRONG_LENGTH = 0x67;
|
||||
|
@ -516,6 +524,7 @@ const ICC_USIM_EFCCP1_TAG = 0xcb;
|
|||
// Tags for Ber Tlv.
|
||||
const BER_UNKNOWN_TAG = 0x00;
|
||||
const BER_PROACTIVE_COMMAND_TAG = 0xd0;
|
||||
const BER_SMS_PP_DOWNLOAD_TAG = 0xd1;
|
||||
const BER_MENU_SELECTION_TAG = 0xd3;
|
||||
const BER_EVENT_DOWNLOAD_TAG = 0xd6;
|
||||
|
||||
|
@ -529,6 +538,7 @@ const COMPREHENSIONTLV_TAG_RESULT = 0x03;
|
|||
const COMPREHENSIONTLV_TAG_DURATION = 0x04;
|
||||
const COMPREHENSIONTLV_TAG_ALPHA_ID = 0x05;
|
||||
const COMPREHENSIONTLV_TAG_ADDRESS = 0x06;
|
||||
const COMPREHENSIONTLV_TAG_SMS_TPDU = 0x0b;
|
||||
const COMPREHENSIONTLV_TAG_TEXT_STRING = 0x0d;
|
||||
const COMPREHENSIONTLV_TAG_ITEM = 0x0f;
|
||||
const COMPREHENSIONTLV_TAG_ITEM_ID = 0x10;
|
||||
|
@ -728,12 +738,14 @@ const GECKO_ICC_SERVICES = {
|
|||
ADN: 2,
|
||||
FDN: 3,
|
||||
SDN: 18,
|
||||
DATA_DOWNLOAD_SMS_PP: 26,
|
||||
BDN: 31
|
||||
},
|
||||
usim: {
|
||||
FDN: 2,
|
||||
SDN: 4,
|
||||
BDN: 6
|
||||
BDN: 6,
|
||||
DATA_DOWNLOAD_SMS_PP: 28
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -825,8 +837,16 @@ const PDU_PI_PROTOCOL_IDENTIFIER = 0x01;
|
|||
const PDU_PI_RESERVED = 0x78;
|
||||
|
||||
// FCS - Failure Cause
|
||||
const PDU_FCS_OK = 0x00;
|
||||
const PDU_FCS_UNSPECIFIED = 0xFF;
|
||||
// 0...127 see 3GPP TS 24.011 clause E.2
|
||||
// 128...255 see 3GPP TS 23.040 clause 9.2.3.22
|
||||
// others see 3GPP TS 27.005 clause 3.2.5
|
||||
const PDU_FCS_OK = 0x00;
|
||||
const PDU_FCS_PROTOCOL_ERROR = 0x6F;
|
||||
const PDU_FCS_MEMORY_CAPACITY_EXCEEDED = 0XD3;
|
||||
const PDU_FCS_USAT_BUSY = 0XD4;
|
||||
const PDU_FCS_USIM_DATA_DOWNLOAD_ERROR = 0xD5;
|
||||
const PDU_FCS_RESERVED = 0xE0;
|
||||
const PDU_FCS_UNSPECIFIED = 0xFF;
|
||||
|
||||
// ST - Status
|
||||
// Bit 7..0 = 000xxxxx, short message transaction completed
|
||||
|
|
|
@ -3080,6 +3080,164 @@ let RIL = {
|
|||
network.mnc = mnc;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param message A decoded SMS-DELIVER message.
|
||||
*
|
||||
* @see 3GPP TS 31.111 section 7.1.1
|
||||
*/
|
||||
dataDownloadViaSMSPP: function dataDownloadViaSMSPP(message) {
|
||||
let options = {
|
||||
pid: message.pid,
|
||||
dcs: message.dcs,
|
||||
encoding: message.encoding,
|
||||
};
|
||||
Buf.newParcel(REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, options);
|
||||
|
||||
Buf.seekIncoming(-1 * (Buf.currentParcelSize - Buf.readAvailable
|
||||
- 2 * UINT32_SIZE)); // Skip response_type & request_type.
|
||||
let messageStringLength = Buf.readUint32(); // In semi-octets
|
||||
let smscLength = GsmPDUHelper.readHexOctet(); // In octets, inclusive of TOA
|
||||
let tpduLength = (messageStringLength / 2) - (smscLength + 1); // In octets
|
||||
|
||||
// Device identities: 4 bytes
|
||||
// Address: 0 or (2 + smscLength)
|
||||
// SMS TPDU: (2 or 3) + tpduLength
|
||||
let berLen = 4 +
|
||||
(smscLength ? (2 + smscLength) : 0) +
|
||||
(tpduLength <= 127 ? 2 : 3) + tpduLength; // In octets
|
||||
|
||||
let parcelLength = (berLen <= 127 ? 2 : 3) + berLen; // In octets
|
||||
Buf.writeUint32(parcelLength * 2); // In semi-octets
|
||||
|
||||
// Write a BER-TLV
|
||||
GsmPDUHelper.writeHexOctet(BER_SMS_PP_DOWNLOAD_TAG);
|
||||
if (berLen > 127) {
|
||||
GsmPDUHelper.writeHexOctet(0x81);
|
||||
}
|
||||
GsmPDUHelper.writeHexOctet(berLen);
|
||||
|
||||
// Device Identifies-TLV
|
||||
GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_DEVICE_ID |
|
||||
COMPREHENSIONTLV_FLAG_CR);
|
||||
GsmPDUHelper.writeHexOctet(0x02);
|
||||
GsmPDUHelper.writeHexOctet(STK_DEVICE_ID_NETWORK);
|
||||
GsmPDUHelper.writeHexOctet(STK_DEVICE_ID_SIM);
|
||||
|
||||
// Address-TLV
|
||||
if (smscLength) {
|
||||
GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_ADDRESS);
|
||||
GsmPDUHelper.writeHexOctet(smscLength);
|
||||
Buf.copyIncomingToOutgoing(PDU_HEX_OCTET_SIZE * smscLength);
|
||||
}
|
||||
|
||||
// SMS TPDU-TLV
|
||||
GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_SMS_TPDU |
|
||||
COMPREHENSIONTLV_FLAG_CR);
|
||||
if (tpduLength > 127) {
|
||||
GsmPDUHelper.writeHexOctet(0x81);
|
||||
}
|
||||
GsmPDUHelper.writeHexOctet(tpduLength);
|
||||
Buf.copyIncomingToOutgoing(PDU_HEX_OCTET_SIZE * tpduLength);
|
||||
|
||||
// Write 2 string delimitors for the total string length must be even.
|
||||
Buf.writeStringDelimiter(0);
|
||||
|
||||
Buf.sendParcel();
|
||||
},
|
||||
|
||||
/**
|
||||
* @param success A boolean value indicating the result of previous
|
||||
* SMS-DELIVER message handling.
|
||||
* @param responsePduLen ICC IO response PDU length in octets.
|
||||
* @param options An object that contains four attributes: `pid`, `dcs`,
|
||||
* `encoding` and `responsePduLen`.
|
||||
*
|
||||
* @see 3GPP TS 23.040 section 9.2.2.1a
|
||||
*/
|
||||
acknowledgeIncomingGsmSmsWithPDU: function acknowledgeIncomingGsmSmsWithPDU(success, responsePduLen, options) {
|
||||
Buf.newParcel(REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU);
|
||||
|
||||
// Two strings.
|
||||
Buf.writeUint32(2);
|
||||
|
||||
// String 1: Success
|
||||
Buf.writeString(success ? "1" : "0");
|
||||
|
||||
// String 2: RP-ACK/RP-ERROR PDU
|
||||
Buf.writeUint32(2 * (responsePduLen + (success ? 5 : 6))); // In semi-octet
|
||||
// 1. TP-MTI & TP-UDHI
|
||||
GsmPDUHelper.writeHexOctet(PDU_MTI_SMS_DELIVER);
|
||||
if (!success) {
|
||||
// 2. TP-FCS
|
||||
GsmPDUHelper.writeHexOctet(PDU_FCS_USIM_DATA_DOWNLOAD_ERROR);
|
||||
}
|
||||
// 3. TP-PI
|
||||
GsmPDUHelper.writeHexOctet(PDU_PI_USER_DATA_LENGTH |
|
||||
PDU_PI_DATA_CODING_SCHEME |
|
||||
PDU_PI_PROTOCOL_IDENTIFIER);
|
||||
// 4. TP-PID
|
||||
GsmPDUHelper.writeHexOctet(options.pid);
|
||||
// 5. TP-DCS
|
||||
GsmPDUHelper.writeHexOctet(options.dcs);
|
||||
// 6. TP-UDL
|
||||
if (options.encoding == PDU_DCS_MSG_CODING_7BITS_ALPHABET) {
|
||||
GsmPDUHelper.writeHexOctet(Math.floor(responsePduLen * 8 / 7));
|
||||
} else {
|
||||
GsmPDUHelper.writeHexOctet(responsePduLen);
|
||||
}
|
||||
// TP-UD
|
||||
Buf.copyIncomingToOutgoing(PDU_HEX_OCTET_SIZE * responsePduLen);
|
||||
// Write 2 string delimitors for the total string length must be even.
|
||||
Buf.writeStringDelimiter(0);
|
||||
|
||||
Buf.sendParcel();
|
||||
},
|
||||
|
||||
/**
|
||||
* @param message A decoded SMS-DELIVER message.
|
||||
*/
|
||||
writeSmsToSIM: function writeSmsToSIM(message) {
|
||||
Buf.newParcel(REQUEST_WRITE_SMS_TO_SIM);
|
||||
|
||||
// Write EFsms Status
|
||||
Buf.writeUint32(EFSMS_STATUS_FREE);
|
||||
|
||||
Buf.seekIncoming(-1 * (Buf.currentParcelSize - Buf.readAvailable
|
||||
- 2 * UINT32_SIZE)); // Skip response_type & request_type.
|
||||
let messageStringLength = Buf.readUint32(); // In semi-octets
|
||||
let smscLength = GsmPDUHelper.readHexOctet(); // In octets, inclusive of TOA
|
||||
let pduLength = (messageStringLength / 2) - (smscLength + 1); // In octets
|
||||
|
||||
// 1. Write PDU first.
|
||||
if (smscLength > 0) {
|
||||
Buf.seekIncoming(smscLength * PDU_HEX_OCTET_SIZE);
|
||||
}
|
||||
// Write EFsms PDU string length
|
||||
Buf.writeUint32(2 * pduLength); // In semi-octets
|
||||
if (pduLength) {
|
||||
Buf.copyIncomingToOutgoing(PDU_HEX_OCTET_SIZE * pduLength);
|
||||
}
|
||||
// Write 2 string delimitors for the total string length must be even.
|
||||
Buf.writeStringDelimiter(0);
|
||||
|
||||
// 2. Write SMSC
|
||||
// Write EFsms SMSC string length
|
||||
Buf.writeUint32(2 * (smscLength + 1)); // Plus smscLength itself, in semi-octets
|
||||
// Write smscLength
|
||||
GsmPDUHelper.writeHexOctet(smscLength);
|
||||
// Write TOA & SMSC Address
|
||||
if (smscLength) {
|
||||
Buf.seekIncoming(-1 * (Buf.currentParcelSize - Buf.readAvailable
|
||||
- 2 * UINT32_SIZE // Skip response_type, request_type.
|
||||
- 2 * PDU_HEX_OCTET_SIZE)); // Skip messageStringLength & smscLength.
|
||||
Buf.copyIncomingToOutgoing(PDU_HEX_OCTET_SIZE * smscLength);
|
||||
}
|
||||
// Write 2 string delimitors for the total string length must be even.
|
||||
Buf.writeStringDelimiter(0);
|
||||
|
||||
Buf.sendParcel();
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper for processing received SMS parcel data.
|
||||
*
|
||||
|
@ -3128,12 +3286,44 @@ let RIL = {
|
|||
return PDU_FCS_OK;
|
||||
}
|
||||
|
||||
if (message.messageClass == PDU_DCS_MSG_CLASS_SIM_SPECIFIC) {
|
||||
switch (message.epid) {
|
||||
case PDU_PID_ANSI_136_R_DATA:
|
||||
case PDU_PID_USIM_DATA_DOWNLOAD:
|
||||
if (this.isICCServiceAvailable("DATA_DOWNLOAD_SMS_PP")) {
|
||||
// `If the service "data download via SMS Point-to-Point" is
|
||||
// allocated and activated in the (U)SIM Service Table, ... then the
|
||||
// ME shall pass the message transparently to the UICC using the
|
||||
// ENVELOPE (SMS-PP DOWNLOAD).` ~ 3GPP TS 31.111 7.1.1.1
|
||||
this.dataDownloadViaSMSPP(message);
|
||||
|
||||
// `the ME shall not display the message, or alert the user of a
|
||||
// short message waiting.` ~ 3GPP TS 31.111 7.1.1.1
|
||||
return PDU_FCS_RESERVED;
|
||||
}
|
||||
|
||||
// If the service "data download via SMS-PP" is not available in the
|
||||
// (U)SIM Service Table, ..., then the ME shall store the message in
|
||||
// EFsms in accordance with TS 31.102` ~ 3GPP TS 31.111 7.1.1.1
|
||||
default:
|
||||
this.writeSmsToSIM(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Bug 739143: B2G SMS: Support SMS Storage Full event
|
||||
if ((message.messageClass != PDU_DCS_MSG_CLASS_0) && !true) {
|
||||
// `When a mobile terminated message is class 0..., the MS shall display
|
||||
// the message immediately and send a ACK to the SC ..., irrespective of
|
||||
// whether there is memory available in the (U)SIM or ME.` ~ 3GPP 23.038
|
||||
// clause 4.
|
||||
|
||||
if (message.messageClass == PDU_DCS_MSG_CLASS_SIM_SPECIFIC) {
|
||||
// `If all the short message storage at the MS is already in use, the
|
||||
// MS shall return "memory capacity exceeded".` ~ 3GPP 23.038 clause 4.
|
||||
return PDU_FCS_MEMORY_CAPACITY_EXCEEDED;
|
||||
}
|
||||
|
||||
return PDU_FCS_UNSPECIFIED;
|
||||
}
|
||||
|
||||
|
@ -3154,6 +3344,12 @@ let RIL = {
|
|||
this.sendDOMMessage(message);
|
||||
}
|
||||
|
||||
if (message.messageClass == PDU_DCS_MSG_CLASS_SIM_SPECIFIC) {
|
||||
// `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
|
||||
return PDU_FCS_RESERVED;
|
||||
}
|
||||
|
||||
return PDU_FCS_OK;
|
||||
},
|
||||
|
||||
|
@ -4059,7 +4255,17 @@ RIL[REQUEST_OEM_HOOK_RAW] = null;
|
|||
RIL[REQUEST_OEM_HOOK_STRINGS] = null;
|
||||
RIL[REQUEST_SCREEN_STATE] = null;
|
||||
RIL[REQUEST_SET_SUPP_SVC_NOTIFICATION] = null;
|
||||
RIL[REQUEST_WRITE_SMS_TO_SIM] = null;
|
||||
RIL[REQUEST_WRITE_SMS_TO_SIM] = function REQUEST_WRITE_SMS_TO_SIM(length, options) {
|
||||
if (options.rilRequestError) {
|
||||
// `The MS shall return a "protocol error, unspecified" error message if
|
||||
// the short message cannot be stored in the (U)SIM, and there is other
|
||||
// message storage available at the MS` ~ 3GPP TS 23.038 section 4. Here
|
||||
// we assume we always have indexed db as another storage.
|
||||
this.acknowledgeSMS(false, PDU_FCS_PROTOCOL_ERROR);
|
||||
} else {
|
||||
this.acknowledgeSMS(true, PDU_FCS_OK);
|
||||
}
|
||||
};
|
||||
RIL[REQUEST_DELETE_SMS_ON_SIM] = null;
|
||||
RIL[REQUEST_SET_BAND_MODE] = null;
|
||||
RIL[REQUEST_QUERY_AVAILABLE_BAND_MODE] = null;
|
||||
|
@ -4106,6 +4312,33 @@ RIL[REQUEST_GET_SMSC_ADDRESS] = function REQUEST_GET_SMSC_ADDRESS(length, option
|
|||
RIL[REQUEST_SET_SMSC_ADDRESS] = null;
|
||||
RIL[REQUEST_REPORT_SMS_MEMORY_STATUS] = null;
|
||||
RIL[REQUEST_REPORT_STK_SERVICE_IS_RUNNING] = null;
|
||||
RIL[REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU] = null;
|
||||
RIL[REQUEST_STK_SEND_ENVELOPE_WITH_STATUS] = function REQUEST_STK_SEND_ENVELOPE_WITH_STATUS(length, options) {
|
||||
if (options.rilRequestError) {
|
||||
this.acknowledgeSMS(false, PDU_FCS_UNSPECIFIED);
|
||||
return;
|
||||
}
|
||||
|
||||
let sw1 = Buf.readUint32();
|
||||
let sw2 = Buf.readUint32();
|
||||
if ((sw1 == ICC_STATUS_SAT_BUSY) && (sw2 == 0x00)) {
|
||||
this.acknowledgeSMS(false, PDU_FCS_USAT_BUSY);
|
||||
return;
|
||||
}
|
||||
|
||||
let success = ((sw1 == ICC_STATUS_NORMAL_ENDING) && (sw2 == 0x00))
|
||||
|| (sw1 == ICC_STATUS_NORMAL_ENDING_WITH_EXTRA);
|
||||
|
||||
let messageStringLength = Buf.readUint32(); // In semi-octets
|
||||
let responsePduLen = messageStringLength / 2; // In octets
|
||||
if (!responsePduLen) {
|
||||
this.acknowledgeSMS(success, success ? PDU_FCS_OK
|
||||
: PDU_FCS_USIM_DATA_DOWNLOAD_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
this.acknowledgeIncomingGsmSmsWithPDU(success, responsePduLen, options);
|
||||
};
|
||||
RIL[UNSOLICITED_RESPONSE_RADIO_STATE_CHANGED] = function UNSOLICITED_RESPONSE_RADIO_STATE_CHANGED() {
|
||||
let radioState = Buf.readUint32();
|
||||
|
||||
|
@ -4175,7 +4408,10 @@ RIL[UNSOLICITED_RESPONSE_VOICE_NETWORK_STATE_CHANGED] = function UNSOLICITED_RES
|
|||
};
|
||||
RIL[UNSOLICITED_RESPONSE_NEW_SMS] = function UNSOLICITED_RESPONSE_NEW_SMS(length) {
|
||||
let result = this._processSmsDeliver(length);
|
||||
this.acknowledgeSMS(result == PDU_FCS_OK, result);
|
||||
if (result != PDU_FCS_RESERVED) {
|
||||
// Not reserved FCS values, send ACK now.
|
||||
this.acknowledgeSMS(result == PDU_FCS_OK, result);
|
||||
}
|
||||
};
|
||||
RIL[UNSOLICITED_RESPONSE_NEW_SMS_STATUS_REPORT] = function UNSOLICITED_RESPONSE_NEW_SMS_STATUS_REPORT(length) {
|
||||
let result = this._processSmsStatusReport(length);
|
||||
|
@ -5152,6 +5388,8 @@ let GsmPDUHelper = {
|
|||
// Bit 7..0 = 01xxxxxx
|
||||
switch (msg.epid) {
|
||||
case PDU_PID_SHORT_MESSAGE_TYPE_0:
|
||||
case PDU_PID_ANSI_136_R_DATA:
|
||||
case PDU_PID_USIM_DATA_DOWNLOAD:
|
||||
return;
|
||||
case PDU_PID_RETURN_CALL_MESSAGE:
|
||||
// Level 1 of message waiting indication:
|
||||
|
|
Загрузка…
Ссылка в новой задаче