зеркало из https://github.com/mozilla/pjs.git
Bug 736697 - Part 2: Refactor to share methods. r=philikon
This commit is contained in:
Родитель
5567738301
Коммит
c5c105f38c
|
@ -367,8 +367,6 @@ const CALL_PRESENTATION_RESTRICTED = 1;
|
|||
const CALL_PRESENTATION_UNKNOWN = 2;
|
||||
const CALL_PRESENTATION_PAYPHONE = 3;
|
||||
|
||||
const SMS_HANDLED = 0;
|
||||
|
||||
// ICC commands, see TS 27.007 +CRSM commands
|
||||
const ICC_COMMAND_READ_BINARY = 0xb0;
|
||||
const ICC_COMMAND_UPDATE_BINARY = 0xd6;
|
||||
|
@ -521,10 +519,15 @@ const PDU_MMS_RD = 0x04;// More messages to send. (SMS-DELIVER only) or
|
|||
// Reject duplicates (SMS-SUBMIT only)
|
||||
|
||||
// MTI - Message Type Indicator
|
||||
const PDU_MTI_SMS_RESERVED = 0x03;
|
||||
const PDU_MTI_SMS_STATUS_COMMAND = 0x02;
|
||||
const PDU_MTI_SMS_SUBMIT = 0x01;
|
||||
const PDU_MTI_SMS_DELIVER = 0x00;
|
||||
|
||||
// FCS - Failure Cause
|
||||
const PDU_FCS_OK = 0x00;
|
||||
const PDU_FCS_UNSPECIFIED = 0xFF;
|
||||
|
||||
// User Data max length in septets
|
||||
const PDU_MAX_USER_DATA_7BIT = 160;
|
||||
// User Data max length in octets
|
||||
|
|
|
@ -1468,6 +1468,69 @@ let RIL = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper for processing received SMS parcel data.
|
||||
*
|
||||
* @param length
|
||||
* Length of SMS string in the incoming parcel.
|
||||
*
|
||||
* @return Message parsed or null for invalid message.
|
||||
*/
|
||||
_processReceivedSms: function _processReceivedSms(length) {
|
||||
if (!length) {
|
||||
if (DEBUG) debug("Received empty SMS!");
|
||||
return null;
|
||||
}
|
||||
|
||||
// An SMS is a string, but we won't read it as such, so let's read the
|
||||
// string length and then defer to PDU parsing helper.
|
||||
let messageStringLength = Buf.readUint32();
|
||||
if (DEBUG) debug("Got new SMS, length " + messageStringLength);
|
||||
let message = GsmPDUHelper.readMessage();
|
||||
if (DEBUG) debug(message);
|
||||
|
||||
// Read string delimiters. See Buf.readString().
|
||||
let delimiter = Buf.readUint16();
|
||||
if (!(messageStringLength & 1)) {
|
||||
delimiter |= Buf.readUint16();
|
||||
}
|
||||
if (DEBUG) {
|
||||
if (delimiter != 0) {
|
||||
debug("Something's wrong, found string delimiter: " + delimiter);
|
||||
}
|
||||
}
|
||||
|
||||
return message;
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper for processing SMS-DELIVER PDUs.
|
||||
*
|
||||
* @param length
|
||||
* Length of SMS string in the incoming parcel.
|
||||
*
|
||||
* @return A failure cause defined in 3GPP 23.040 clause 9.2.3.22.
|
||||
*/
|
||||
_processSmsDeliver: function _processSmsDeliver(length) {
|
||||
let message = this._processReceivedSms(length);
|
||||
if (!message) {
|
||||
return PDU_FCS_UNSPECIFIED;
|
||||
}
|
||||
|
||||
if (message.header && (message.header.segmentMaxSeq > 1)) {
|
||||
message = this._processReceivedSmsSegment(message);
|
||||
} else {
|
||||
message.fullBody = message.body;
|
||||
}
|
||||
|
||||
if (message) {
|
||||
message.type = "sms-received";
|
||||
this.sendDOMMessage(message);
|
||||
}
|
||||
|
||||
return PDU_FCS_OK;
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper for processing received multipart SMS.
|
||||
*
|
||||
|
@ -2082,44 +2145,8 @@ RIL[UNSOLICITED_RESPONSE_VOICE_NETWORK_STATE_CHANGED] = function UNSOLICITED_RES
|
|||
this.requestNetworkInfo();
|
||||
};
|
||||
RIL[UNSOLICITED_RESPONSE_NEW_SMS] = function UNSOLICITED_RESPONSE_NEW_SMS(length) {
|
||||
if (!length) {
|
||||
if (DEBUG) debug("Received empty SMS!");
|
||||
//TODO: should we acknowledge the SMS here? maybe only after multiple
|
||||
//failures.
|
||||
return;
|
||||
}
|
||||
// An SMS is a string, but we won't read it as such, so let's read the
|
||||
// string length and then defer to PDU parsing helper.
|
||||
let messageStringLength = Buf.readUint32();
|
||||
if (DEBUG) debug("Got new SMS, length " + messageStringLength);
|
||||
let message = GsmPDUHelper.readMessage();
|
||||
if (DEBUG) debug(message);
|
||||
|
||||
// Read string delimiters. See Buf.readString().
|
||||
let delimiter = Buf.readUint16();
|
||||
if (!(messageStringLength & 1)) {
|
||||
delimiter |= Buf.readUint16();
|
||||
}
|
||||
if (DEBUG) {
|
||||
if (delimiter != 0) {
|
||||
debug("Something's wrong, found string delimiter: " + delimiter);
|
||||
}
|
||||
}
|
||||
|
||||
if (message.header && (message.header.segmentMaxSeq > 1)) {
|
||||
message = this._processReceivedSmsSegment(message);
|
||||
} else {
|
||||
message.fullBody = message.body;
|
||||
}
|
||||
|
||||
if (message) {
|
||||
message.type = "sms-received";
|
||||
this.sendDOMMessage(message);
|
||||
}
|
||||
|
||||
//TODO: this might be a lie? do we want to wait for the mainthread to
|
||||
// report back?
|
||||
this.acknowledgeSMS(true, SMS_HANDLED);
|
||||
let result = this._processSmsDeliver(length);
|
||||
this.acknowledgeSMS(result == PDU_FCS_OK, result);
|
||||
};
|
||||
RIL[UNSOLICITED_RESPONSE_NEW_SMS_STATUS_REPORT] = function UNSOLICITED_RESPONSE_NEW_SMS_STATUS_REPORT(length) {
|
||||
let info = Buf.readStringList();
|
||||
|
@ -2689,6 +2716,65 @@ let GsmPDUHelper = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Read SM-TL Address.
|
||||
*
|
||||
* @see 3GPP TS 23.040 9.1.2.5
|
||||
*/
|
||||
readAddress: function readAddress(len) {
|
||||
// Address Length
|
||||
if (!len || (len < 0)) {
|
||||
if (DEBUG) debug("PDU error: invalid sender address length: " + len);
|
||||
return null;
|
||||
}
|
||||
if (len % 2 == 1) {
|
||||
len += 1;
|
||||
}
|
||||
if (DEBUG) debug("PDU: Going to read address: " + len);
|
||||
|
||||
// Type-of-Address
|
||||
let toa = this.readHexOctet();
|
||||
|
||||
// Address-Value
|
||||
let addr = this.readSwappedNibbleBCD(len / 2).toString();
|
||||
if (addr.length <= 0) {
|
||||
if (DEBUG) debug("PDU error: no number provided");
|
||||
return null;
|
||||
}
|
||||
if ((toa >> 4) == (PDU_TOA_INTERNATIONAL >> 4)) {
|
||||
addr = '+' + addr;
|
||||
}
|
||||
|
||||
return addr;
|
||||
},
|
||||
|
||||
/**
|
||||
* Read GSM TP-Service-Centre-Time-Stamp(TP-SCTS).
|
||||
*
|
||||
* @see 3GPP TS 23.040 9.2.3.11
|
||||
*/
|
||||
readTimestamp: function readTimestamp() {
|
||||
let year = this.readSwappedNibbleBCD(1) + PDU_TIMESTAMP_YEAR_OFFSET;
|
||||
let month = this.readSwappedNibbleBCD(1) - 1;
|
||||
let day = this.readSwappedNibbleBCD(1);
|
||||
let hour = this.readSwappedNibbleBCD(1);
|
||||
let minute = this.readSwappedNibbleBCD(1);
|
||||
let second = this.readSwappedNibbleBCD(1);
|
||||
let timestamp = Date.UTC(year, month, day, hour, minute, second);
|
||||
|
||||
// If the most significant bit of the least significant nibble is 1,
|
||||
// the timezone offset is negative (fourth bit from the right => 0x08).
|
||||
let tzOctet = this.readHexOctet();
|
||||
let tzOffset = this.octetToBCD(tzOctet & ~0x08) * 15 * 60 * 1000;
|
||||
if (tzOctet & 0x08) {
|
||||
timestamp -= tzOffset;
|
||||
} else {
|
||||
timestamp += tzOffset;
|
||||
}
|
||||
|
||||
return timestamp;
|
||||
},
|
||||
|
||||
/**
|
||||
* User data can be 7 bit (default alphabet) data, 8 bit data, or 16 bit
|
||||
* (UCS2) data.
|
||||
|
@ -2697,22 +2783,19 @@ let GsmPDUHelper = {
|
|||
* message object for output.
|
||||
* @param length
|
||||
* length of user data to read in octets.
|
||||
* @param codingScheme
|
||||
* coding scheme used to decode user data.
|
||||
* @param hasHeader
|
||||
* whether a header is embedded.
|
||||
*/
|
||||
readUserData: function readUserData(msg, length, codingScheme, hasHeader) {
|
||||
readUserData: function readUserData(msg, length) {
|
||||
let dcs = msg.dcs;
|
||||
if (DEBUG) {
|
||||
debug("Reading " + length + " bytes of user data.");
|
||||
debug("Coding scheme: " + codingScheme);
|
||||
debug("Coding scheme: " + dcs);
|
||||
}
|
||||
// 7 bit is the default fallback encoding.
|
||||
let encoding = PDU_DCS_MSG_CODING_7BITS_ALPHABET;
|
||||
switch (codingScheme & 0xC0) {
|
||||
switch (dcs & 0xC0) {
|
||||
case 0x0:
|
||||
// bits 7..4 = 00xx
|
||||
switch (codingScheme & 0x0C) {
|
||||
switch (dcs & 0x0C) {
|
||||
case 0x4:
|
||||
encoding = PDU_DCS_MSG_CODING_8BITS_ALPHABET;
|
||||
break;
|
||||
|
@ -2723,12 +2806,12 @@ let GsmPDUHelper = {
|
|||
break;
|
||||
case 0xC0:
|
||||
// bits 7..4 = 11xx
|
||||
switch (codingScheme & 0x30) {
|
||||
switch (dcs & 0x30) {
|
||||
case 0x20:
|
||||
encoding = PDU_DCS_MSG_CODING_16BITS_ALPHABET;
|
||||
break;
|
||||
case 0x30:
|
||||
if (!codingScheme & 0x04) {
|
||||
if (!dcs & 0x04) {
|
||||
encoding = PDU_DCS_MSG_CODING_8BITS_ALPHABET;
|
||||
}
|
||||
break;
|
||||
|
@ -2742,7 +2825,7 @@ let GsmPDUHelper = {
|
|||
if (DEBUG) debug("PDU: message encoding is " + encoding + " bit.");
|
||||
|
||||
let paddingBits = 0;
|
||||
if (hasHeader) {
|
||||
if (msg.udhi) {
|
||||
msg.header = this.readUserDataHeader();
|
||||
|
||||
if (encoding == PDU_DCS_MSG_CODING_7BITS_ALPHABET) {
|
||||
|
@ -2766,8 +2849,8 @@ let GsmPDUHelper = {
|
|||
break;
|
||||
}
|
||||
|
||||
let langIndex = hasHeader ? msg.header.langIndex : PDU_NL_IDENTIFIER_DEFAULT;
|
||||
let langShiftIndex = hasHeader ? msg.header.langShiftIndex : PDU_NL_IDENTIFIER_DEFAULT;
|
||||
let langIndex = msg.udhi ? msg.header.langIndex : PDU_NL_IDENTIFIER_DEFAULT;
|
||||
let langShiftIndex = msg.udhi ? msg.header.langShiftIndex : PDU_NL_IDENTIFIER_DEFAULT;
|
||||
msg.body = this.readSeptetsToString(length, paddingBits, langIndex,
|
||||
langShiftIndex);
|
||||
break;
|
||||
|
@ -2790,7 +2873,11 @@ let GsmPDUHelper = {
|
|||
// An empty message object. This gets filled below and then returned.
|
||||
let msg = {
|
||||
SMSC: null,
|
||||
mti: null,
|
||||
udhi: null,
|
||||
sender: null,
|
||||
pid: null,
|
||||
dcs: null,
|
||||
body: null,
|
||||
timestamp: null
|
||||
};
|
||||
|
@ -2808,64 +2895,45 @@ let GsmPDUHelper = {
|
|||
|
||||
// First octet of this SMS-DELIVER or SMS-SUBMIT message
|
||||
let firstOctet = this.readHexOctet();
|
||||
|
||||
// Message Type Indicator
|
||||
msg.mti = firstOctet & 0x03;
|
||||
// User data header indicator
|
||||
let hasUserDataHeader = firstOctet & PDU_UDHI;
|
||||
msg.udhi = firstOctet & PDU_UDHI;
|
||||
|
||||
switch (msg.mti) {
|
||||
case PDU_MTI_SMS_RESERVED:
|
||||
// `If an MS receives a TPDU with a "Reserved" value in the TP-MTI it
|
||||
// shall process the message as if it were an "SMS-DELIVER" but store
|
||||
// the message exactly as received.` ~ 3GPP TS 23.040 9.2.3.1
|
||||
case PDU_MTI_SMS_DELIVER:
|
||||
return this.readDeliverMessage(msg);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Read and decode a SMS-DELIVER PDU.
|
||||
*
|
||||
* @param msg
|
||||
* message object for output.
|
||||
*/
|
||||
readDeliverMessage: function readDeliverMessage(msg) {
|
||||
// - Sender Address info -
|
||||
// Address length
|
||||
let senderAddressLength = this.readHexOctet();
|
||||
if (senderAddressLength <= 0) {
|
||||
if (DEBUG) debug("PDU error: invalid sender address length: " + senderAddressLength);
|
||||
return null;
|
||||
}
|
||||
// Type-of-Address
|
||||
let senderTypeOfAddress = this.readHexOctet();
|
||||
if (senderAddressLength % 2 == 1) {
|
||||
senderAddressLength += 1;
|
||||
}
|
||||
if (DEBUG) debug("PDU: Going to read sender address: " + senderAddressLength);
|
||||
msg.sender = this.readSwappedNibbleBCD(senderAddressLength / 2).toString();
|
||||
if (msg.sender.length <= 0) {
|
||||
if (DEBUG) debug("PDU error: no sender number provided");
|
||||
return null;
|
||||
}
|
||||
if ((senderTypeOfAddress >> 4) == (PDU_TOA_INTERNATIONAL >> 4)) {
|
||||
msg.sender = '+' + msg.sender;
|
||||
}
|
||||
|
||||
msg.sender = this.readAddress(senderAddressLength);
|
||||
// - TP-Protocolo-Identifier -
|
||||
let protocolIdentifier = this.readHexOctet();
|
||||
|
||||
msg.pid = this.readHexOctet();
|
||||
// - TP-Data-Coding-Scheme -
|
||||
let dataCodingScheme = this.readHexOctet();
|
||||
|
||||
msg.dcs = this.readHexOctet();
|
||||
// - TP-Service-Center-Time-Stamp -
|
||||
let year = this.readSwappedNibbleBCD(1) + PDU_TIMESTAMP_YEAR_OFFSET;
|
||||
let month = this.readSwappedNibbleBCD(1) - 1;
|
||||
let day = this.readSwappedNibbleBCD(1);
|
||||
let hour = this.readSwappedNibbleBCD(1);
|
||||
let minute = this.readSwappedNibbleBCD(1);
|
||||
let second = this.readSwappedNibbleBCD(1);
|
||||
msg.timestamp = Date.UTC(year, month, day, hour, minute, second);
|
||||
|
||||
// If the most significant bit of the least significant nibble is 1,
|
||||
// the timezone offset is negative (fourth bit from the right => 0x08).
|
||||
let tzOctet = this.readHexOctet();
|
||||
let tzOffset = this.octetToBCD(tzOctet & ~0x08) * 15 * 60 * 1000;
|
||||
if (tzOctet & 0x08) {
|
||||
msg.timestamp -= tzOffset;
|
||||
} else {
|
||||
msg.timestamp += tzOffset;
|
||||
}
|
||||
|
||||
msg.timestamp = this.readTimestamp();
|
||||
// - TP-User-Data-Length -
|
||||
let userDataLength = this.readHexOctet();
|
||||
|
||||
// - TP-User-Data -
|
||||
if (userDataLength > 0) {
|
||||
this.readUserData(msg, userDataLength, dataCodingScheme,
|
||||
hasUserDataHeader);
|
||||
this.readUserData(msg, userDataLength);
|
||||
}
|
||||
|
||||
return msg;
|
||||
|
|
Загрузка…
Ссылка в новой задаче