author | Yoshi Huang <allstars.chh@mozilla.com> |
Thu, 27 Dec 2012 19:06:29 +0800 | |
changeset 119243 | be757f2c314ee56a0a6cc9f85b535750c0d5a186 |
parent 119242 | 03fb2a777aec3418417a83991136b4c0fd803c15 |
child 119244 | ca185542d941878cfc4848f50689c1f7e3009f2d |
push id | 24195 |
push user | Ms2ger@gmail.com |
push date | Sat, 19 Jan 2013 16:10:11 +0000 |
treeherder | mozilla-central@02e12a80aef9 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | hsinyi |
bugs | 821584 |
milestone | 21.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
dom/system/gonk/ril_consts.js | file | annotate | diff | comparison | revisions | |
dom/system/gonk/ril_worker.js | file | annotate | diff | comparison | revisions |
--- a/dom/system/gonk/ril_consts.js +++ b/dom/system/gonk/ril_consts.js @@ -528,16 +528,30 @@ this.ICC_USIM_EFANR_TAG = 0xc4; this.ICC_USIM_EFPBC_TAG = 0xc5; this.ICC_USIM_EFGRP_TAG = 0xc6; this.ICC_USIM_EFAAS_TAG = 0xc7; this.ICC_USIM_EFGSD_TAG = 0xc8; this.ICC_USIM_EFUID_TAG = 0xc9; this.ICC_USIM_EFEMAIL_TAG = 0xca; this.ICC_USIM_EFCCP1_TAG = 0xcb; +this.USIM_TAG_NAME = {}; +this.USIM_TAG_NAME[ICC_USIM_EFADN_TAG] = "adn"; +this.USIM_TAG_NAME[ICC_USIM_EFIAP_TAG] ="iap"; +this.USIM_TAG_NAME[ICC_USIM_EFEXT1_TAG] = "ext1"; +this.USIM_TAG_NAME[ICC_USIM_EFSNE_TAG] = "sne"; +this.USIM_TAG_NAME[ICC_USIM_EFANR_TAG] = "anr"; +this.USIM_TAG_NAME[ICC_USIM_EFPBC_TAG] = "pbc"; +this.USIM_TAG_NAME[ICC_USIM_EFGRP_TAG] = "grp"; +this.USIM_TAG_NAME[ICC_USIM_EFAAS_TAG] = "aas"; +this.USIM_TAG_NAME[ICC_USIM_EFGSD_TAG] = "gsd"; +this.USIM_TAG_NAME[ICC_USIM_EFUID_TAG] = "uid"; +this.USIM_TAG_NAME[ICC_USIM_EFEMAIL_TAG] = "email"; +this.USIM_TAG_NAME[ICC_USIM_EFCCP1_TAG] = "ccp1"; + /** * STK constants. */ // Tags for Ber Tlv. this.BER_UNKNOWN_TAG = 0x00; this.BER_PROACTIVE_COMMAND_TAG = 0xd0; this.BER_SMS_PP_DOWNLOAD_TAG = 0xd1; this.BER_MENU_SELECTION_TAG = 0xd3;
--- a/dom/system/gonk/ril_worker.js +++ b/dom/system/gonk/ril_worker.js @@ -1304,43 +1304,42 @@ let RIL = { return [pnnEntry.fullName, pnnEntry.shortName]; } return null; }, /** * Get UICC Phonebook. * - * @params contactType - * "ADN" or "FDN". + * @param contactType + * "ADN" or "FDN". + * @param requestId + * Request id from RadioInterfaceLayer. */ getICCContacts: function getICCContacts(options) { if (!this.appType) { options.rilMessageType = "icccontacts"; options.errorMsg = GECKO_ERROR_REQUEST_NOT_SUPPORTED; this.sendDOMMessage(options); } - let type = options.contactType; - switch (type) { - case "ADN": - switch (this.appType) { - case CARD_APPTYPE_SIM: - options.fileId = ICC_EF_ADN; - ICCRecordHelper.getADN(options); - break; - case CARD_APPTYPE_USIM: - ICCRecordHelper.getPBR(options); - break; - } - break; - case "FDN": - ICCRecordHelper.getFDN(options); - break; - } + ICCContactHelper.readICCContacts( + this.appType, + options.contactType, + function onsuccess(contacts) { + // Reuse 'options' to get 'requestId' and 'contactType'. + options.rilMessageType = "icccontacts"; + options.contacts = contacts; + RIL.sendDOMMessage(options); + }.bind(this), + function onerror(errorMsg) { + options.rilMessageType = "icccontacts"; + options.errorMsg = errorMsg; + RIL.sendDOMMessage(options); + }.bind(this)); }, /** * Request the phone's radio power to be switched on or off. * * @param on * Boolean indicating the desired power state. */ @@ -4468,40 +4467,26 @@ RIL[REQUEST_SETUP_DATA_CALL] = function return; } // Pass `options` along. That way we retain the APN and other info about // how the data call was set up. this[REQUEST_DATA_CALL_LIST](length, options); }; RIL[REQUEST_SIM_IO] = function REQUEST_SIM_IO(length, options) { if (!length) { - if (options.onerror) { - options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError]; - options.onerror(options); - } + ICCIOHelper.processICCIOError(options); return; } // Don't need to read rilRequestError since we can know error status from // sw1 and sw2. options.sw1 = Buf.readUint32(); options.sw2 = Buf.readUint32(); if (options.sw1 != ICC_STATUS_NORMAL_ENDING) { - // See GSM11.11, TS 51.011 clause 9.4, and ISO 7816-4 for the error - // description. - let msg = "ICC I/O Error EF id = " + options.fileId.toString(16) + - " command = " + options.command.toString(16) + - "(" + options.sw1.toString(16) + "/" + options.sw2.toString(16) + ")" - if (DEBUG) { - debug(msg); - } - if (options.onerror) { - options.errorMsg = msg; - options.onerror(options); - } + ICCIOHelper.processICCIOError(options); return; } ICCIOHelper.processICCIO(options); }; RIL[REQUEST_SEND_USSD] = function REQUEST_SEND_USSD(length, options) { if (DEBUG) { debug("REQUEST_SEND_USSD " + JSON.stringify(options)); } @@ -8519,16 +8504,33 @@ let ICCIOHelper = { /** * Process a ICC_COMMAND_READ_BINARY type command for REQUEST_SIM_IO. */ processICCIOReadBinary: function processICCIOReadBinary(options) { if (options.callback) { options.callback(options); } }, + + /** + * Process ICC IO error. + */ + processICCIOError: function processICCIOError(options) { + let error = options.onerror || debug; + + // See GSM11.11, TS 51.011 clause 9.4, and ISO 7816-4 for the error + // description. + let errorMsg = "ICC I/O Error code " + + RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError] + + "EF id = " + options.fileId.toString(16) + + " command = " + options.command.toString(16) + + "(" + options.sw1.toString(16) + + "/" + options.sw2.toString(16) + ")"; + error(errorMsg); + }, }; ICCIOHelper[ICC_COMMAND_SEEK] = null; ICCIOHelper[ICC_COMMAND_READ_BINARY] = function ICC_COMMAND_READ_BINARY(options) { this.processICCIOReadBinary(options); }; ICCIOHelper[ICC_COMMAND_READ_RECORD] = function ICC_COMMAND_READ_RECORD(options) { this.processICCIOReadRecord(options); }; @@ -8739,99 +8741,76 @@ let ICCRecordHelper = { } // ICC_EF_UST has the same value with ICC_EF_SST. ICCIOHelper.loadTransparentEF({fileId: ICC_EF_SST, callback: callback.bind(this)}); }, /** - * Get ICC FDN. - * - * @param requestId - * Request id from RadioInterfaceLayer. - */ - getFDN: function getFDN(options) { + * Read ICC FDN. + * + * @param onsuccess Callback to be called when success. + * @param onerror Callback to be called when error. + */ + readFDN: function readFDN(onsuccess, onerror) { function callback(options) { let contact = GsmPDUHelper.readAlphaIdDiallingNumber(options.recordSize); if (contact) { - RIL.iccInfo.fdn.push(contact); + contacts.push(contact); + } + + if (options.p1 < options.totalRecords) { + ICCIOHelper.loadNextRecord(options); + } else { + if (onsuccess) { + onsuccess(contacts); + } + } + } + + let contacts = []; + ICCIOHelper.loadLinearFixedEF({fileId: ICC_EF_FDN, + callback: callback.bind(this), + onerror: onerror}); + }, + + /** + * Read ICC ADN. + * + * @param fileId EF id of the ADN. + * @param onsuccess Callback to be called when success. + * @param onerror Callback to be called when error. + */ + readADN: function readADN(fileId, onsuccess, onerror) { + function callback(options) { + let contact = GsmPDUHelper.readAlphaIdDiallingNumber(options.recordSize); + if (contact) { + contact.recordId = options.p1; + contacts.push(contact); } if (options.p1 < options.totalRecords) { ICCIOHelper.loadNextRecord(options); } else { if (DEBUG) { - for (let i = 0; i < RIL.iccInfo.fdn.length; i++) { - debug("FDN[" + i + "] alphaId = " + RIL.iccInfo.fdn[i].alphaId + - " number = " + RIL.iccInfo.fdn[i].number); + for (let i = 0; i < contacts.length; i++) { + debug("ADN[" + i + "] " + JSON.stringify(contacts[i])); } } - // To prevent DataCloneError when sending parcels, we need to delete - // those properties which are not 'Structured Clone Data', in this case, - // those callback functions. - delete options.callback; - delete options.onerror; - options.rilMessageType = "icccontacts"; - options.contacts = RIL.iccInfo.fdn; - RIL.sendDOMMessage(options); - } - } - - RIL.iccInfo.fdn = []; - options.fileId = ICC_EF_FDN; - options.callback = callback.bind(this); - ICCIOHelper.loadLinearFixedEF(options); - }, - - /** - * Get ICC ADN. - * - * @param fileId - * EF id of the ADN. - * @param requestId - * Request id from RadioInterfaceLayer. - */ - getADN: function getADN(options) { - function callback(options) { - let contact = GsmPDUHelper.readAlphaIdDiallingNumber(options.recordSize); - if (contact) { - RIL.iccInfo.adn.push(contact); - } - - if (options.p1 < options.totalRecords) { - ICCIOHelper.loadNextRecord(options); - } else { - if (DEBUG) { - for (let i = 0; i < RIL.iccInfo.adn.length; i++) { - debug("ADN[" + i + "] " + JSON.stringify(RIL.iccInfo.adn[i])); - } + if (onsuccess) { + onsuccess(contacts); } - // To prevent DataCloneError when sending parcels, we need to delete - // those properties which are not 'Structured Clone Data', in this case, - // those callback functions. - delete options.callback; - delete options.onerror; - options.rilMessageType = "icccontacts"; - options.contacts = RIL.iccInfo.adn; - RIL.sendDOMMessage(options); - } - } - - function error(options) { - delete options.callback; - delete options.onerror; - options.rilMessageType = "icccontacts"; - RIL.sendDOMMessage(options); - } - - RIL.iccInfo.adn = []; - options.callback = callback.bind(this); - options.onerror = error.bind(this); - ICCIOHelper.loadLinearFixedEF(options); + } + } + + let contacts = []; + ICCIOHelper.loadLinearFixedEF({fileId: fileId, + callback: callback.bind(this), + onerror: onerror}); }, /** * Get ICC MBDN. (Mailbox Dialling Number) * * @see TS 131.102, clause 4.2.60 */ getMBDN: function getMBDN() { @@ -8848,47 +8827,60 @@ let ICCRecordHelper = { RIL.sendDOMMessage(contact); } ICCIOHelper.loadLinearFixedEF({fileId: ICC_EF_MBDN, callback: callback.bind(this)}); }, /** - * Get USIM Phonebook. - * - * @param requestId - * Request id from RadioInterfaceLayer. - */ - getPBR: function getPBR(options) { + * Read USIM Phonebook. + * + * @param onsuccess Callback to be called when success. + * @param onerror Callback to be called when error. + */ + readPBR: function readPBR(onsuccess, onerror) { function callback(options) { - let bufLen = Buf.readUint32(); - - let tag = GsmPDUHelper.readHexOctet(); - let length = GsmPDUHelper.readHexOctet(); - let value = ICCUtilsHelper.decodeSimTlvs(length); - - let adn = ICCUtilsHelper.searchForIccUsimTag(value, ICC_USIM_EFADN_TAG); - options.fileId = (adn.value[0] << 8) | adn.value[1]; - Buf.readStringDelimiter(bufLen); - - this.getADN(options); - } - - function error(options) { - delete options.callback; - delete options.onerror; - options.rilMessageType = "icccontacts"; - RIL.sendDOMMessage(options); - } - - options.fileId = ICC_EF_PBR; - options.callback = callback.bind(this); - options.onerror = error.bind(this); - ICCIOHelper.loadLinearFixedEF(options); + let strLen = Buf.readUint32(); + let octetLen = strLen / 2, readLen = 0; + + let pbrTlvs = []; + while (readLen < octetLen) { + let tag = GsmPDUHelper.readHexOctet(); + if (tag == 0xff) { + readLen++; + Buf.seekIncoming((octetLen - readLen) * PDU_HEX_OCTET_SIZE); + break; + } + + let tlvLen = GsmPDUHelper.readHexOctet(); + let tlvs = ICCUtilsHelper.decodeSimTlvs(tlvLen); + pbrTlvs.push({tag: tag, + length: tlvLen, + value: tlvs}); + + readLen += tlvLen + 2; // +2 for tag and tlvLen + } + Buf.readStringDelimiter(strLen); + + if (pbrTlvs.length == 0) { + let error = onerror || debug; + error("Cannot access Phonebook."); + return; + } + + let pbr = ICCUtilsHelper.parsePbrTlvs(pbrTlvs); + if (onsuccess) { + onsuccess(pbr); + } + } + + ICCIOHelper.loadLinearFixedEF({fileId : ICC_EF_PBR, + callback: callback.bind(this), + onerror: onerror}); }, /** * Read the PLMNsel (Public Land Mobile Network) from the ICC. * * See ETSI TS 100.977 section 10.3.4 EF_PLMNsel */ getPLMNSelector: function getPLMNSelector() { @@ -9342,23 +9334,48 @@ let ICCUtilsHelper = { }; simTlv.value = GsmPDUHelper.readHexOctetArray(simTlv.length) tlvs.push(simTlv); index += simTlv.length + 2 /* The length of 'tag' and 'length' field */; } return tlvs; }, - searchForIccUsimTag: function searchForIccUsimTag(tlvs, tag) { - for (let i = 0; i < tlvs.length; i++) { - if (tlvs[i].tag == tag) { - return tlvs[i]; - } - } - return null; + /** + * Parse those TLVs and convert it to an object. + */ + parsePbrTlvs: function parsePbrTlvs(pbrTlvs) { + let pbr = {}; + for (let i = 0; i < pbrTlvs.length; i++) { + let pbrTlv = pbrTlvs[i]; + for (let j = 0; j < pbrTlv.value.length; j++) { + let tlv = pbrTlv.value[j]; + let tagName = USIM_TAG_NAME[tlv.tag]; + + // ANR could have multiple files. + if (tlv.tag == ICC_USIM_EFANR_TAG) { + if (!pbr.anr) { + pbr.anr = []; + } + pbr.anr.push(tlv); + } else { + pbr[tagName] = tlv; + } + + pbr[tagName].fileType = pbrTlv.tag; + pbr[tagName].fileId = (tlv.value[0] << 8) | tlv.value[1]; + + // For Type 2, the order of files is in the same order in IAP. + if (pbrTlv.tag == ICC_USIM_TYPE2_TAG) { + pbr[tagName].indexInIAP = j; + } + } + } + + return pbr; }, /** * Update the ICC information to RadioInterfaceLayer. */ handleICCInfoChange: function handleICCInfoChange() { RIL.iccInfo.rilMessageType = "iccinfochange"; RIL.sendDOMMessage(RIL.iccInfo); @@ -9451,16 +9468,77 @@ let ICCUtilsHelper = { } } return true; }, }; /** + * Helper for ICC Contacts. + */ +let ICCContactHelper = { + /** + * Helper function to read ICC contacts. + * + * @param appType CARD_APPTYPE_SIM or CARD_APPTYPE_USIM. + * @param contactType "ADN" or "FDN" + * @param onsuccess Callback to be called when success. + * @param onerror Callback to be called when error. + */ + readICCContacts: function readICCContacts(appType, contactType, onsuccess, onerror) { + switch (contactType) { + case "ADN": + switch (appType) { + case CARD_APPTYPE_SIM: + this.readSimContacts(onsuccess, onerror); + break; + case CARD_APPTYPE_USIM: + this.readUSimContacts(onsuccess, onerror); + break; + } + break; + case "FDN": + ICCRecordHelper.readFDN(onsuccess, onerror); + break; + } + }, + + /** + * Read contacts from USIM. + * + * @param onsuccess Callback to be called when success. + * @param onerror Callback to be called when error. + */ + readUSimContacts: function readUSimContacts(onsuccess, onerror) { + let gotPbrCb = function gotPbrCb(pbr) { + if (pbr.adn) { + let fileId = pbr.adn.fileId; + ICCRecordHelper.readADN(fileId, onsuccess, onerror); + } else { + let error = onerror || debug; + error("Cannot access ADN."); + } + }.bind(this); + + ICCRecordHelper.readPBR(gotPbrCb, onerror); + }, + + /** + * Read contacts from SIM. + * + * @param onsuccess Callback to be called when success. + * @param onerror Callback to be called when error. + */ + readSimContacts: function readSimContacts(onsuccess, onerror) { + ICCRecordHelper.readADN(ICC_EF_ADN, onsuccess, onerror); + }, +}; + +/** * Global stuff. */ if (!this.debug) { // Debugging stub that goes nowhere. this.debug = function debug(message) { dump("RIL Worker: " + message + "\n"); };