From 80e0f05c52b88f8bc81a63b8ca049a085fb84106 Mon Sep 17 00:00:00 2001 From: yoshi huang Date: Wed, 7 Mar 2012 14:14:37 -0800 Subject: [PATCH] Bug 720638 - B2G RIL: Read MSISDN. r=philikon --- dom/system/b2g/ril_consts.js | 74 +++++++++++++++++++++ dom/system/b2g/ril_worker.js | 121 ++++++++++++++++++++++++++++++++++- 2 files changed, 194 insertions(+), 1 deletion(-) diff --git a/dom/system/b2g/ril_consts.js b/dom/system/b2g/ril_consts.js index 0a157fc3160..d75d27a890b 100644 --- a/dom/system/b2g/ril_consts.js +++ b/dom/system/b2g/ril_consts.js @@ -260,6 +260,80 @@ 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; +const ICC_COMMAND_READ_RECORD = 0xb2; +const ICC_COMMAND_UPDATE_RECORD = 0xdc; +const ICC_COMMAND_SEEK = 0xa2; +const ICC_COMMAND_GET_RESPONSE = 0xc0; + +// 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_MSISDN = 0x6f40; +const ICC_EF_SPDI = 0x6fcd; +const ICC_EF_SST = 0x6f38; +const ICC_EF_CFIS = 0x6FCB; +const ICC_EF_IMG = 0x4f20; + +// Types of files TS 11.11 9.3 +const TYPE_RFU = 0; +const TYPE_MF = 1; +const TYPE_DF = 2; +const TYPE_EF = 4; + +const RESPONSE_DATA_FILE_ID_1 = 4; +const RESPONSE_DATA_FILE_ID_2 = 5; +const RESPONSE_DATA_FILE_TYPE = 6; +const RESPONSE_DATA_RFU_3 = 7; +const RESPONSE_DATA_ACCESS_CONDITION_1 = 8; +const RESPONSE_DATA_ACCESS_CONDITION_2 = 9; +const RESPONSE_DATA_ACCESS_CONDITION_3 = 10; +const RESPONSE_DATA_FILE_STATUS = 11; +const RESPONSE_DATA_LENGTH = 12; +const RESPONSE_DATA_STRUCTURE = 13; +const RESPONSE_DATA_RECORD_LENGTH = 14; + +// Types of files TS 11.11 9.3 +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; + +// READ_RECORD mode, TS 102.221 +const READ_RECORD_ABSOLUTE_MODE = 4; + +// GET_RESPONSE mandatory response size for EF, see TS 51.011 clause 9, +// 'Response data in case of an EF.' +const GET_RESPONSE_EF_SIZE_BYTES = 15; + +// EF path +const EF_PATH_MF_SIM = "3f00"; +const EF_PATH_DF_TELECOM = "7f10"; + +// Status code for ICC I/O, +// see GSM11.11 and TS 51.011 clause 9.4. +const STATUS_NORMAL_ENDING = 0x90; +const STATUS_NORMAL_ENDING_WITH_EXTRA = 0x91; +const STATUS_WITH_SIM_DATA = 0x9e; +const STATUS_WITH_RESPONSE_DATA = 0x9f; /** * GSM PDU constants diff --git a/dom/system/b2g/ril_worker.js b/dom/system/b2g/ril_worker.js index ee021ad2945..a7ac5c4f950 100644 --- a/dom/system/b2g/ril_worker.js +++ b/dom/system/b2g/ril_worker.js @@ -912,6 +912,41 @@ let RIL = { return token; }, + /** + * Request an ICC I/O operation. + * + * See TS 27.007 "restricted SIM" operation, "AT Command +CRSM". + * The sequence is in the same order as how libril reads this parcel, + * see the struct RIL_SIM_IO_v5 or RIL_SIM_IO_v6 defined in ril.h + * + * @param command + * The I/O command, one of the ICC_COMMAND_* constants. + * @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 p1, p2, p3 + * Arbitrary integer parameters for the command. + * @param data + * String parameter for the command. + * @param pin2 [optional] + * String containing the PIN2. + */ + iccIO: function iccIO (options) { + let token = Buf.newParcel(REQUEST_SIM_IO, options); + Buf.writeUint32(options.command); + Buf.writeUint32(options.fileid); + Buf.writeString(options.path); + Buf.writeUint32(options.p1); + Buf.writeUint32(options.p2); + Buf.writeUint32(options.p3); + Buf.writeString(options.data); + if (request.pin2 != null) { + Buf.writeString(pin2); + } + Buf.sendParcel(); + }, + /** * Deactivate a data call. * @@ -1125,7 +1160,9 @@ RIL[REQUEST_SETUP_DATA_CALL] = function REQUEST_SETUP_DATA_CALL() { let [cid, ifname, ipaddr, dns, gw] = Buf.readStringList(); Phone.onSetupDataCall(Buf.lastSolicitedToken, cid, ifname, ipaddr, dns, gw); }; -RIL[REQUEST_SIM_IO] = null; +RIL[REQUEST_SIM_IO] = function REQUEST_SIM_IO(length, options) { + Phone.onICCIO(options); +}; RIL[REQUEST_SEND_USSD] = null; RIL[REQUEST_CANCEL_USSD] = null; RIL[REQUEST_GET_CLIR] = null; @@ -1338,6 +1375,7 @@ let Phone = { IMEISV: null, IMSI: null, SMSC: null, + MSISDN: null, registrationState: {}, gprsRegistrationState: {}, @@ -1484,6 +1522,7 @@ let Phone = { this.requestNetworkInfo(); RIL.getSignalStrength(); RIL.getSMSCAddress(); + this.getMSISDN(); this.sendDOMMessage({type: "cardstatechange", cardState: GECKO_CARDSTATE_READY}); } @@ -1687,6 +1726,52 @@ let Phone = { this.IMEISV = imeiSV; }, + onICCIO: function onICCIO(options) { + switch (options.fileid) { + case ICC_EF_MSISDN: + this.readMSISDNResponse(options); + break; + } + }, + + readMSISDNResponse: function readMSISDNResponse(options) { + let sw1 = Buf.readUint32(); + let sw2 = Buf.readUint32(); + // See GSM11.11 section 9.4 for sw1 and sw2 + if (sw1 != STATUS_NORMAL_ENDING) { + // TODO: error + // Wait for fix for Bug 713451 to report error. + debug("Error in iccIO"); + } + if (DEBUG) debug("ICC I/O (" + sw1 + "/" + sw2 + ")"); + + 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 request = { + 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, + }; + RIL.iccIO(request); + 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; + break; + } + }, + onRegistrationState: function onRegistrationState(state) { let rs = this.registrationState; let stateChanged = false; @@ -2142,6 +2227,23 @@ let Phone = { RIL.getFailCauseCode(); }, + /** + * Get MSISDN + */ + getMSISDN: function getMSISDN() { + let request = { + 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, + }; + RIL.iccIO(request); + }, + /** * Handle incoming messages from the main UI thread. * @@ -2270,6 +2372,8 @@ let GsmPDUHelper = { let number = 0; for (let i = 0; i < length; i++) { let octet = this.readHexOctet(); + if (octet == 0xff) + continue; // If the first nibble is an "F" , only the second nibble is to be taken // into account. if ((octet & 0xf0) == 0xf0) { @@ -2283,6 +2387,21 @@ let GsmPDUHelper = { return number; }, + /** + * Read a string from Buf and convert it to BCD + * + * @return the decimal as a number. + */ + readStringAsBCD: function readStringAsBCD() { + let length = Buf.readUint32(); + let bcd = this.readSwappedNibbleBCD(length / 2); + let delimiter = Buf.readUint16(); + if (!(length & 1)) { + delimiter |= Buf.readUint16(); + } + return bcd; + }, + /** * Write numerical data as swapped nibble BCD. *