mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 736941 - B2G RIL: Fetch SIM record. r=philikon a=b2g-only
This commit is contained in:
parent
77c3cee342
commit
5ce156c88f
@ -150,7 +150,7 @@ function RadioInterfaceLayer() {
|
||||
this.radioState = {
|
||||
radioState: RIL.GECKO_RADIOSTATE_UNAVAILABLE,
|
||||
cardState: RIL.GECKO_CARDSTATE_UNAVAILABLE,
|
||||
msisdn: null,
|
||||
icc: null,
|
||||
|
||||
// These objects implement the nsIDOMMozMobileConnectionInfo interface,
|
||||
// although the actual implementation lives in the content process.
|
||||
@ -276,8 +276,8 @@ RadioInterfaceLayer.prototype = {
|
||||
" dst=" + message.dstFlag +
|
||||
" timestamp=" + message.localTimeStampInMS);
|
||||
break;
|
||||
case "siminfo":
|
||||
this.radioState.msisdn = message.msisdn;
|
||||
case "iccinfochange":
|
||||
this.radioState.icc = message;
|
||||
break;
|
||||
default:
|
||||
throw new Error("Don't know about this message type: " + message.type);
|
||||
|
@ -373,34 +373,35 @@ const CALL_PRESENTATION_UNKNOWN = 2;
|
||||
const CALL_PRESENTATION_PAYPHONE = 3;
|
||||
|
||||
// ICC commands, see TS 27.007 +CRSM commands
|
||||
const ICC_COMMAND_READ_BINARY = 0xb0;
|
||||
const ICC_COMMAND_UPDATE_BINARY = 0xd6;
|
||||
const ICC_COMMAND_READ_RECORD = 0xb2;
|
||||
const ICC_COMMAND_UPDATE_RECORD = 0xdc;
|
||||
const ICC_COMMAND_SEEK = 0xa2;
|
||||
const ICC_COMMAND_READ_BINARY = 0xb0;
|
||||
const ICC_COMMAND_READ_RECORD = 0xb2;
|
||||
const ICC_COMMAND_GET_RESPONSE = 0xc0;
|
||||
const ICC_COMMAND_UPDATE_BINARY = 0xd6;
|
||||
const ICC_COMMAND_UPDATE_RECORD = 0xdc;
|
||||
|
||||
// ICC constants, GSM SIM file ids from TS 51.011
|
||||
const ICC_EF_ADN = 0x6F3A;
|
||||
const ICC_EF_FDN = 0x6F3B;
|
||||
const ICC_EF_SDN = 0x6F49;
|
||||
const ICC_EF_EXT1 = 0x6F4A;
|
||||
const ICC_EF_EXT2 = 0x6F4B;
|
||||
const ICC_EF_EXT3 = 0x6F4C;
|
||||
const ICC_EF_EXT6 = 0x6fc8; // Ext record for EF[MBDN]
|
||||
const ICC_EF_MWIS = 0x6FCA;
|
||||
const ICC_EF_MBDN = 0x6fc7;
|
||||
const ICC_EF_PNN = 0x6fc5;
|
||||
const ICC_EF_SPN = 0x6F46;
|
||||
const ICC_EF_SMS = 0x6F3C;
|
||||
const ICC_EF_ICCID = 0x2fe2;
|
||||
const ICC_EF_AD = 0x6FAD;
|
||||
const ICC_EF_MBI = 0x6fc9;
|
||||
const ICC_EF_ICCID = 0x2fe2;
|
||||
const ICC_EF_IMG = 0x4f20;
|
||||
const ICC_EF_SST = 0x6f38;
|
||||
const ICC_EF_UST = 0x6f38; // For USIM
|
||||
const ICC_EF_ADN = 0x6f3a;
|
||||
const ICC_EF_FDN = 0x6f3b;
|
||||
const ICC_EF_SMS = 0x6f3c;
|
||||
const ICC_EF_MSISDN = 0x6f40;
|
||||
const ICC_EF_SPDI = 0x6fcd;
|
||||
const ICC_EF_SST = 0x6f38;
|
||||
const ICC_EF_CFIS = 0x6FCB;
|
||||
const ICC_EF_IMG = 0x4f20;
|
||||
const ICC_EF_SPN = 0x6f46;
|
||||
const ICC_EF_SDN = 0x6f49;
|
||||
const ICC_EF_EXT1 = 0x6f4a;
|
||||
const ICC_EF_EXT2 = 0x6f4b;
|
||||
const ICC_EF_EXT3 = 0x6f4c;
|
||||
const ICC_EF_AD = 0x6fad;
|
||||
const ICC_EF_PNN = 0x6fc5;
|
||||
const ICC_EF_MBDN = 0x6fc7;
|
||||
const ICC_EF_EXT6 = 0x6fc8; // Ext record for EF[MBDN]
|
||||
const ICC_EF_MBI = 0x6fc9;
|
||||
const ICC_EF_MWIS = 0x6fca;
|
||||
const ICC_EF_CFIS = 0x6fcb;
|
||||
const ICC_EF_SPDI = 0x6fcd;
|
||||
|
||||
// Types of files TS 11.11 9.3
|
||||
const TYPE_RFU = 0;
|
||||
@ -408,6 +409,7 @@ const TYPE_MF = 1;
|
||||
const TYPE_DF = 2;
|
||||
const TYPE_EF = 4;
|
||||
|
||||
const RESPONSE_DATA_FILE_SIZE = 2;
|
||||
const RESPONSE_DATA_FILE_ID_1 = 4;
|
||||
const RESPONSE_DATA_FILE_ID_2 = 5;
|
||||
const RESPONSE_DATA_FILE_TYPE = 6;
|
||||
@ -425,9 +427,9 @@ const EF_TYPE_TRANSPARENT = 0;
|
||||
const EF_TYPE_LINEAR_FIXED = 1;
|
||||
const EF_TYPE_CYCLIC = 3;
|
||||
|
||||
// For retriveing MSISDN
|
||||
const FOOTER_SIZE_BYTES = 14;
|
||||
const MAX_NUMBER_SIZE_BYTES = 11;
|
||||
// For retrieving MSISDN, TS 151.011 clause 10.5.5
|
||||
const MSISDN_FOOTER_SIZE_BYTES = 14;
|
||||
const MSISDN_MAX_NUMBER_SIZE_BYTES = 10;
|
||||
|
||||
// READ_RECORD mode, TS 102.221
|
||||
const READ_RECORD_ABSOLUTE_MODE = 4;
|
||||
@ -439,6 +441,7 @@ const GET_RESPONSE_EF_SIZE_BYTES = 15;
|
||||
// EF path
|
||||
const EF_PATH_MF_SIM = "3f00";
|
||||
const EF_PATH_DF_TELECOM = "7f10";
|
||||
const EF_PATH_DF_GSM = "7f20";
|
||||
|
||||
// Status code of sw1 for ICC I/O,
|
||||
// see GSM11.11 and TS 51.011 clause 9.4, and ISO 7816-4
|
||||
|
@ -75,6 +75,8 @@ const UINT16_SIZE = 2;
|
||||
const UINT32_SIZE = 4;
|
||||
const PARCEL_SIZE_SIZE = UINT32_SIZE;
|
||||
|
||||
const PDU_HEX_OCTET_SIZE = 4;
|
||||
|
||||
let RILQUIRKS_CALLSTATE_EXTRA_UINT32 = false;
|
||||
let RILQUIRKS_DATACALLSTATE_DOWN_IS_UP = false;
|
||||
// This flag defaults to true since on RIL v6 and later, we get the
|
||||
@ -202,6 +204,51 @@ let Buf = {
|
||||
* These are all little endian, apart from readParcelSize();
|
||||
*/
|
||||
|
||||
/**
|
||||
* Ensure position specified is readable.
|
||||
*
|
||||
* @param index
|
||||
* Data position in incoming parcel, valid from 0 to
|
||||
* this.currentParcelSize.
|
||||
*/
|
||||
ensureIncomingAvailable: function ensureIncomingAvailable(index) {
|
||||
if (index >= this.currentParcelSize) {
|
||||
throw new Error("Trying to read data beyond the parcel end!");
|
||||
} else if (index < 0) {
|
||||
throw new Error("Trying to read data before the parcel begin!");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Seek in current incoming parcel.
|
||||
*
|
||||
* @param offset
|
||||
* Seek offset in relative to current position.
|
||||
*/
|
||||
seekIncoming: function seekIncoming(offset) {
|
||||
// Translate to 0..currentParcelSize
|
||||
let cur = this.currentParcelSize - this.readAvailable;
|
||||
|
||||
let newIndex = cur + offset;
|
||||
this.ensureIncomingAvailable(newIndex);
|
||||
|
||||
// ... incomingReadIndex -->|
|
||||
// 0 new cur currentParcelSize
|
||||
// |================|=======|===================|
|
||||
// |<-- cur -->|<- readAvailable ->|
|
||||
// |<-- newIndex -->|<-- new readAvailable -->|
|
||||
this.readAvailable = this.currentParcelSize - newIndex;
|
||||
|
||||
// Translate back:
|
||||
if (this.incomingReadIndex < cur) {
|
||||
// The incomingReadIndex is wrapped.
|
||||
newIndex += this.INCOMING_BUFFER_LENGTH;
|
||||
}
|
||||
newIndex += (this.incomingReadIndex - cur);
|
||||
newIndex %= this.INCOMING_BUFFER_LENGTH;
|
||||
this.incomingReadIndex = newIndex;
|
||||
},
|
||||
|
||||
readUint8Unchecked: function readUint8Unchecked() {
|
||||
let value = this.incomingBytes[this.incomingReadIndex];
|
||||
this.incomingReadIndex = (this.incomingReadIndex + 1) %
|
||||
@ -210,9 +257,9 @@ let Buf = {
|
||||
},
|
||||
|
||||
readUint8: function readUint8() {
|
||||
if (!this.readAvailable) {
|
||||
throw new Error("Trying to read data beyond the parcel end!");
|
||||
}
|
||||
// Translate to 0..currentParcelSize
|
||||
let cur = this.currentParcelSize - this.readAvailable;
|
||||
this.ensureIncomingAvailable(cur);
|
||||
|
||||
this.readAvailable--;
|
||||
return this.readUint8Unchecked();
|
||||
@ -567,9 +614,12 @@ let RIL = {
|
||||
*/
|
||||
IMEI: null,
|
||||
IMEISV: null,
|
||||
IMSI: null,
|
||||
SMSC: null,
|
||||
MSISDN: null,
|
||||
|
||||
/**
|
||||
* ICC information, such as MSISDN, IMSI, ...etc.
|
||||
*/
|
||||
iccInfo: {},
|
||||
|
||||
voiceRegistrationState: {},
|
||||
dataRegistrationState: {},
|
||||
@ -766,10 +816,10 @@ let RIL = {
|
||||
*
|
||||
* @param command
|
||||
* The I/O command, one of the ICC_COMMAND_* constants.
|
||||
* @param fileid
|
||||
* @param fileId
|
||||
* The file to operate on, one of the ICC_EF_* constants.
|
||||
* @param pathid
|
||||
* String type, check pathid from TS 27.007 +CRSM
|
||||
* @param pathId
|
||||
* String type, check the 'pathid' parameter from TS 27.007 +CRSM.
|
||||
* @param p1, p2, p3
|
||||
* Arbitrary integer parameters for the command.
|
||||
* @param data
|
||||
@ -780,8 +830,8 @@ let RIL = {
|
||||
iccIO: function iccIO(options) {
|
||||
let token = Buf.newParcel(REQUEST_SIM_IO, options);
|
||||
Buf.writeUint32(options.command);
|
||||
Buf.writeUint32(options.fileid);
|
||||
Buf.writeString(options.pathid);
|
||||
Buf.writeUint32(options.fileId);
|
||||
Buf.writeString(options.pathId);
|
||||
Buf.writeUint32(options.p1);
|
||||
Buf.writeUint32(options.p2);
|
||||
Buf.writeUint32(options.p3);
|
||||
@ -792,19 +842,183 @@ let RIL = {
|
||||
Buf.sendParcel();
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch ICC records.
|
||||
*/
|
||||
fetchICCRecords: function fetchICCRecords() {
|
||||
this.getIMSI();
|
||||
this.getMSISDN();
|
||||
this.getAD();
|
||||
this.getUST();
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the ICC information to RadioInterfaceLayer.
|
||||
*/
|
||||
_handleICCInfoChange: function _handleICCInfoChange() {
|
||||
this.iccInfo.type = "iccinfochange";
|
||||
this.sendDOMMessage(this.iccInfo);
|
||||
},
|
||||
|
||||
getIMSI: function getIMSI() {
|
||||
Buf.simpleRequest(REQUEST_GET_IMSI);
|
||||
},
|
||||
|
||||
/**
|
||||
* Read the MSISDN from the ICC.
|
||||
*/
|
||||
getMSISDN: function getMSISDN() {
|
||||
function callback() {
|
||||
let length = Buf.readUint32();
|
||||
// Each octet is encoded into two chars.
|
||||
let recordLength = length / 2;
|
||||
// Skip prefixed alpha identifier
|
||||
Buf.seekIncoming((recordLength - MSISDN_FOOTER_SIZE_BYTES) *
|
||||
PDU_HEX_OCTET_SIZE);
|
||||
|
||||
// Dialling Number/SSC String
|
||||
let len = GsmPDUHelper.readHexOctet();
|
||||
if (len > MSISDN_MAX_NUMBER_SIZE_BYTES) {
|
||||
debug("ICC_EF_MSISDN: invalid length of BCD number/SSC contents - " + len);
|
||||
return;
|
||||
}
|
||||
this.iccInfo.MSISDN = GsmPDUHelper.readAddress(len);
|
||||
let delimiter = Buf.readUint16();
|
||||
if (!(length & 1)) {
|
||||
delimiter |= Buf.readUint16();
|
||||
}
|
||||
if (DEBUG) {
|
||||
if (delimiter != 0) {
|
||||
debug("Something's wrong, found string delimiter: " + delimiter);
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG) debug("MSISDN: " + this.iccInfo.MSISDN);
|
||||
if (this.iccInfo.MSISDN) {
|
||||
this._handleICCInfoChange();
|
||||
}
|
||||
}
|
||||
|
||||
this.iccIO({
|
||||
command: ICC_COMMAND_GET_RESPONSE,
|
||||
fileid: ICC_EF_MSISDN,
|
||||
pathid: EF_PATH_MF_SIM + EF_PATH_DF_TELECOM,
|
||||
p1: 0, // For GET_RESPONSE, p1 = 0
|
||||
p2: 0, // For GET_RESPONSE, p2 = 0
|
||||
p3: GET_RESPONSE_EF_SIZE_BYTES,
|
||||
data: null,
|
||||
pin2: null,
|
||||
command: ICC_COMMAND_GET_RESPONSE,
|
||||
fileId: ICC_EF_MSISDN,
|
||||
pathId: EF_PATH_MF_SIM + EF_PATH_DF_TELECOM,
|
||||
p1: 0, // For GET_RESPONSE, p1 = 0
|
||||
p2: 0, // For GET_RESPONSE, p2 = 0
|
||||
p3: GET_RESPONSE_EF_SIZE_BYTES,
|
||||
data: null,
|
||||
pin2: null,
|
||||
type: EF_TYPE_LINEAR_FIXED,
|
||||
callback: callback,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Read the AD from the ICC.
|
||||
*/
|
||||
getAD: function getAD() {
|
||||
function callback() {
|
||||
let length = Buf.readUint32();
|
||||
// Each octet is encoded into two chars.
|
||||
let len = length / 2;
|
||||
this.iccInfo.AD = GsmPDUHelper.readHexOctetArray(len);
|
||||
let delimiter = Buf.readUint16();
|
||||
if (!(length & 1)) {
|
||||
delimiter |= Buf.readUint16();
|
||||
}
|
||||
if (DEBUG) {
|
||||
if (delimiter != 0) {
|
||||
debug("Something's wrong, found string delimiter: " + delimiter);
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
let str = "";
|
||||
for (let i = 0; i < this.iccInfo.AD.length; i++) {
|
||||
str += this.iccInfo.AD[i] + ", ";
|
||||
}
|
||||
debug("AD: " + str);
|
||||
}
|
||||
|
||||
if (this.iccInfo.IMSI) {
|
||||
// MCC is the first 3 digits of IMSI
|
||||
this.iccInfo.MCC = this.iccInfo.IMSI.substr(0,3);
|
||||
// The 4th byte of the response is the length of MNC
|
||||
this.iccInfo.MNC = this.iccInfo.IMSI.substr(3, this.iccInfo.AD[3]);
|
||||
if (DEBUG) debug("MCC: " + this.iccInfo.MCC + " MNC: " + this.iccInfo.MNC);
|
||||
this._handleICCInfoChange();
|
||||
}
|
||||
}
|
||||
|
||||
this.iccIO({
|
||||
command: ICC_COMMAND_GET_RESPONSE,
|
||||
fileId: ICC_EF_AD,
|
||||
pathId: EF_PATH_MF_SIM + EF_PATH_DF_GSM,
|
||||
p1: 0, // For GET_RESPONSE, p1 = 0
|
||||
p2: 0, // For GET_RESPONSE, p2 = 0
|
||||
p3: GET_RESPONSE_EF_SIZE_BYTES,
|
||||
data: null,
|
||||
pin2: null,
|
||||
type: EF_TYPE_TRANSPARENT,
|
||||
callback: callback,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Get whether specificed USIM service is available.
|
||||
*
|
||||
* @param service
|
||||
* Service id, valid in 1..N. See 3GPP TS 31.102 4.2.8.
|
||||
* @return
|
||||
* true if the service is enabled,
|
||||
* false otherwise.
|
||||
*/
|
||||
isUSTServiceAvailable: function isUSTServiceAvailable(service) {
|
||||
service -= 1;
|
||||
let index = service / 8;
|
||||
let bitmask = 1 << (service % 8);
|
||||
return this.UST && (index < this.UST.length) && (this.UST[index] & bitmask);
|
||||
},
|
||||
|
||||
/**
|
||||
* Read the UST from the ICC.
|
||||
*/
|
||||
getUST: function getUST() {
|
||||
function callback() {
|
||||
let length = Buf.readUint32();
|
||||
// Each octet is encoded into two chars.
|
||||
let len = length / 2;
|
||||
this.iccInfo.UST = GsmPDUHelper.readHexOctetArray(len);
|
||||
let delimiter = Buf.readUint16();
|
||||
if (!(length & 1)) {
|
||||
delimiter |= Buf.readUint16();
|
||||
}
|
||||
if (DEBUG) {
|
||||
if (delimiter != 0) {
|
||||
debug("Something's wrong, found string delimiter: " + delimiter);
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
let str = "";
|
||||
for (let i = 0; i < this.iccInfo.UST.length; i++) {
|
||||
str += this.iccInfo.UST[i] + ", ";
|
||||
}
|
||||
debug("UST: " + str);
|
||||
}
|
||||
}
|
||||
|
||||
this.iccIO({
|
||||
command: ICC_COMMAND_GET_RESPONSE,
|
||||
fileId: ICC_EF_UST,
|
||||
pathId: EF_PATH_MF_SIM + EF_PATH_DF_GSM,
|
||||
p1: 0, // For GET_RESPONSE, p1 = 0
|
||||
p2: 0, // For GET_RESPONSE, p2 = 0
|
||||
p3: GET_RESPONSE_EF_SIZE_BYTES,
|
||||
data: null,
|
||||
pin2: null,
|
||||
type: EF_TYPE_TRANSPARENT,
|
||||
callback: callback,
|
||||
});
|
||||
},
|
||||
|
||||
@ -1263,7 +1477,7 @@ let RIL = {
|
||||
case CARD_APPSTATE_READY:
|
||||
this.requestNetworkInfo();
|
||||
this.getSignalStrength();
|
||||
this.getMSISDN();
|
||||
this.fetchICCRecords();
|
||||
newCardState = GECKO_CARDSTATE_READY;
|
||||
break;
|
||||
case CARD_APPSTATE_UNKNOWN:
|
||||
@ -1281,33 +1495,119 @@ let RIL = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Process the MSISDN ICC I/O response.
|
||||
* Process a ICC_COMMAND_GET_RESPONSE type command for REQUEST_SIM_IO.
|
||||
*/
|
||||
_processMSISDNResponse: function _processMSISDNResponse(options) {
|
||||
_processICCIOGetResponse: function _processICCIOGetResponse(options) {
|
||||
let length = Buf.readUint32();
|
||||
|
||||
// The format is from TS 51.011, clause 9.2.1
|
||||
|
||||
// Skip RFU, data[0] data[1]
|
||||
Buf.seekIncoming(2 * PDU_HEX_OCTET_SIZE);
|
||||
|
||||
// File size, data[2], data[3]
|
||||
let fileSize = (GsmPDUHelper.readHexOctet() << 8) |
|
||||
GsmPDUHelper.readHexOctet();
|
||||
|
||||
// 2 bytes File id. data[4], data[5]
|
||||
let fileId = (GsmPDUHelper.readHexOctet() << 8) |
|
||||
GsmPDUHelper.readHexOctet();
|
||||
if (fileId != options.fileId) {
|
||||
if (DEBUG) {
|
||||
debug("Expected file ID " + options.fileId + " but read " + fileId);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Type of file, data[6]
|
||||
let fileType = GsmPDUHelper.readHexOctet();
|
||||
if (fileType != TYPE_EF) {
|
||||
if (DEBUG) {
|
||||
debug("Unexpected file type " + fileType);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip 1 byte RFU, data[7],
|
||||
// 3 bytes Access conditions, data[8] data[9] data[10],
|
||||
// 1 byte File status, data[11],
|
||||
// 1 byte Length of the following data, data[12].
|
||||
Buf.seekIncoming(((RESPONSE_DATA_STRUCTURE - RESPONSE_DATA_FILE_TYPE - 1) *
|
||||
PDU_HEX_OCTET_SIZE));
|
||||
|
||||
// Read Structure of EF, data[13]
|
||||
let efType = GsmPDUHelper.readHexOctet();
|
||||
if (efType != options.type) {
|
||||
if (DEBUG) {
|
||||
debug("Expected EF type " + options.type + " but read " + efType);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Length of a record, data[14]
|
||||
let recordSize = GsmPDUHelper.readHexOctet();
|
||||
|
||||
let delimiter = Buf.readUint16();
|
||||
if (!(length & 1)) {
|
||||
delimiter |= Buf.readUint16();
|
||||
}
|
||||
if (DEBUG) {
|
||||
if (delimiter != 0) {
|
||||
debug("Something's wrong, found string delimiter: " + delimiter);
|
||||
}
|
||||
}
|
||||
|
||||
switch (options.type) {
|
||||
case EF_TYPE_LINEAR_FIXED:
|
||||
// Reuse the options object and update some properties.
|
||||
options.command = ICC_COMMAND_READ_RECORD;
|
||||
options.p1 = 1; // Record number, always use the 1st record
|
||||
options.p2 = READ_RECORD_ABSOLUTE_MODE;
|
||||
options.p3 = recordSize;
|
||||
this.iccIO(options);
|
||||
break;
|
||||
case EF_TYPE_TRANSPARENT:
|
||||
// Reuse the options object and update some properties.
|
||||
options.command = ICC_COMMAND_READ_BINARY;
|
||||
options.p3 = fileSize;
|
||||
this.iccIO(options);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Process a ICC_COMMAND_READ_RECORD type command for REQUEST_SIM_IO.
|
||||
*/
|
||||
_processICCIOReadRecord: function _processICCIOReadRecord(options) {
|
||||
if (options.callback) {
|
||||
options.callback.call(this);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Process a ICC_COMMAND_READ_BINARY type command for REQUEST_SIM_IO.
|
||||
*/
|
||||
_processICCIOReadBinary: function _processICCIOReadBinary(options) {
|
||||
if (options.callback) {
|
||||
options.callback.call(this);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Process ICC I/O response.
|
||||
*/
|
||||
_processICCIO: function _processICCIO(options) {
|
||||
switch (options.command) {
|
||||
case ICC_COMMAND_GET_RESPONSE:
|
||||
let response = Buf.readString();
|
||||
let recordSize = parseInt(
|
||||
response.substr(RESPONSE_DATA_RECORD_LENGTH * 2, 2), 16) & 0xff;
|
||||
let options = {
|
||||
command: ICC_COMMAND_READ_RECORD,
|
||||
fileid: ICC_EF_MSISDN,
|
||||
pathid: EF_PATH_MF_SIM + EF_PATH_DF_TELECOM,
|
||||
p1: 1, // Record number, MSISDN is always in the 1st record
|
||||
p2: READ_RECORD_ABSOLUTE_MODE,
|
||||
p3: recordSize,
|
||||
data: null,
|
||||
pin2: null,
|
||||
};
|
||||
this.iccIO(options);
|
||||
this._processICCIOGetResponse(options);
|
||||
break;
|
||||
|
||||
case ICC_COMMAND_READ_RECORD:
|
||||
// Ignore 2 bytes prefix, which is 4 chars
|
||||
let number = GsmPDUHelper.readStringAsBCD().toString().substr(4);
|
||||
if (DEBUG) debug("MSISDN: " + number);
|
||||
this.MSISDN = number || null;
|
||||
this.sendDOMMessage({type: "siminfo", msisdn: this.MSISDN});
|
||||
this._processICCIOReadRecord(options);
|
||||
break;
|
||||
|
||||
case ICC_COMMAND_READ_BINARY:
|
||||
this._processICCIOReadBinary(options);
|
||||
break;
|
||||
}
|
||||
},
|
||||
@ -1869,7 +2169,7 @@ RIL[REQUEST_GET_IMSI] = function REQUEST_GET_IMSI(length, options) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.IMSI = Buf.readString();
|
||||
this.iccInfo.IMSI = Buf.readString();
|
||||
};
|
||||
RIL[REQUEST_HANGUP] = function REQUEST_HANGUP(length, options) {
|
||||
if (options.rilRequestError) {
|
||||
@ -2106,18 +2406,13 @@ RIL[REQUEST_SIM_IO] = function REQUEST_SIM_IO(length, options) {
|
||||
// See GSM11.11, TS 51.011 clause 9.4, and ISO 7816-4 for the error
|
||||
// description.
|
||||
if (DEBUG) {
|
||||
debug("ICC I/O Error EF id = " + options.fileid.toString(16) +
|
||||
debug("ICC I/O Error EF id = " + options.fileId.toString(16) +
|
||||
" command = " + options.command.toString(16) +
|
||||
"(" + sw1.toString(16) + "/" + sw2.toString(16) + ")");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch (options.fileid) {
|
||||
case ICC_EF_MSISDN:
|
||||
this._processMSISDNResponse(options);
|
||||
break;
|
||||
}
|
||||
this._processICCIO(options);
|
||||
};
|
||||
RIL[REQUEST_SEND_USSD] = null;
|
||||
RIL[REQUEST_CANCEL_USSD] = null;
|
||||
@ -2559,6 +2854,17 @@ let GsmPDUHelper = {
|
||||
this.writeHexNibble(octet);
|
||||
},
|
||||
|
||||
/**
|
||||
* Read an array of hex-encoded octets.
|
||||
*/
|
||||
readHexOctetArray: function readHexOctetArray(length) {
|
||||
let array = new Uint8Array(length);
|
||||
for (let i = 0; i < length; i++) {
|
||||
array[i] = this.readHexOctet();
|
||||
}
|
||||
return array;
|
||||
},
|
||||
|
||||
/**
|
||||
* Convert an octet (number) to a BCD number.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user