diff options
Diffstat (limited to 'dom/system/gonk/tests/test_ril_worker_icc_SimRecordHelper.js')
-rw-r--r-- | dom/system/gonk/tests/test_ril_worker_icc_SimRecordHelper.js | 1648 |
1 files changed, 1648 insertions, 0 deletions
diff --git a/dom/system/gonk/tests/test_ril_worker_icc_SimRecordHelper.js b/dom/system/gonk/tests/test_ril_worker_icc_SimRecordHelper.js new file mode 100644 index 000000000..6500cc663 --- /dev/null +++ b/dom/system/gonk/tests/test_ril_worker_icc_SimRecordHelper.js @@ -0,0 +1,1648 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); + +function run_test() { + run_next_test(); +} + +/** + * Verify reading EF_AD and parsing MCC/MNC + */ +add_test(function test_reading_ad_and_parsing_mcc_mnc() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let record = context.SimRecordHelper; + let helper = context.GsmPDUHelper; + let ril = context.RIL; + let buf = context.Buf; + let io = context.ICCIOHelper; + + function do_test(mncLengthInEf, imsi, expectedMcc, expectedMnc) { + ril.iccInfoPrivate.imsi = imsi; + + io.loadTransparentEF = function fakeLoadTransparentEF(options) { + let ad = [0x00, 0x00, 0x00]; + if (typeof mncLengthInEf === 'number') { + ad.push(mncLengthInEf); + } + + // Write data size + buf.writeInt32(ad.length * 2); + + // Write data + for (let i = 0; i < ad.length; i++) { + helper.writeHexOctet(ad[i]); + } + + // Write string delimiter + buf.writeStringDelimiter(ad.length * 2); + + if (options.callback) { + options.callback(options); + } + }; + + record.readAD(); + + equal(ril.iccInfo.mcc, expectedMcc); + equal(ril.iccInfo.mnc, expectedMnc); + } + + do_test(undefined, "466923202422409", "466", "92" ); + do_test(0x00, "466923202422409", "466", "92" ); + do_test(0x01, "466923202422409", "466", "92" ); + do_test(0x02, "466923202422409", "466", "92" ); + do_test(0x03, "466923202422409", "466", "923"); + do_test(0x04, "466923202422409", "466", "92" ); + do_test(0xff, "466923202422409", "466", "92" ); + + do_test(undefined, "310260542718417", "310", "260"); + do_test(0x00, "310260542718417", "310", "260"); + do_test(0x01, "310260542718417", "310", "260"); + do_test(0x02, "310260542718417", "310", "26" ); + do_test(0x03, "310260542718417", "310", "260"); + do_test(0x04, "310260542718417", "310", "260"); + do_test(0xff, "310260542718417", "310", "260"); + + run_next_test(); +}); + +add_test(function test_reading_optional_efs() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let record = context.SimRecordHelper; + let gsmPdu = context.GsmPDUHelper; + let ril = context.RIL; + let buf = context.Buf; + let io = context.ICCIOHelper; + + function buildSST(supportedEf) { + let sst = []; + let len = supportedEf.length; + for (let i = 0; i < len; i++) { + let index, bitmask, iccService; + if (ril.appType === CARD_APPTYPE_SIM) { + iccService = GECKO_ICC_SERVICES.sim[supportedEf[i]]; + iccService -= 1; + index = Math.floor(iccService / 4); + bitmask = 2 << ((iccService % 4) << 1); + } else if (ril.appType === CARD_APPTYPE_USIM){ + iccService = GECKO_ICC_SERVICES.usim[supportedEf[i]]; + iccService -= 1; + index = Math.floor(iccService / 8); + bitmask = 1 << ((iccService % 8) << 0); + } + + if (sst) { + sst[index] |= bitmask; + } + } + return sst; + } + + ril.updateCellBroadcastConfig = function fakeUpdateCellBroadcastConfig() { + // Ignore updateCellBroadcastConfig after reading SST + }; + + function do_test(sst, supportedEf) { + // Clone supportedEf to local array for testing + let testEf = supportedEf.slice(0); + + record.readMSISDN = function fakeReadMSISDN() { + testEf.splice(testEf.indexOf("MSISDN"), 1); + }; + + record.readMBDN = function fakeReadMBDN() { + testEf.splice(testEf.indexOf("MDN"), 1); + }; + + record.readMWIS = function fakeReadMWIS() { + testEf.splice(testEf.indexOf("MWIS"), 1); + }; + + io.loadTransparentEF = function fakeLoadTransparentEF(options) { + // Write data size + buf.writeInt32(sst.length * 2); + + // Write data + for (let i = 0; i < sst.length; i++) { + gsmPdu.writeHexOctet(sst[i] || 0); + } + + // Write string delimiter + buf.writeStringDelimiter(sst.length * 2); + + if (options.callback) { + options.callback(options); + } + + if (testEf.length !== 0) { + do_print("Un-handled EF: " + JSON.stringify(testEf)); + ok(false); + } + }; + + record.readSST(); + } + + // TODO: Add all necessary optional EFs eventually + let supportedEf = ["MSISDN", "MDN", "MWIS"]; + ril.appType = CARD_APPTYPE_SIM; + do_test(buildSST(supportedEf), supportedEf); + ril.appType = CARD_APPTYPE_USIM; + do_test(buildSST(supportedEf), supportedEf); + + run_next_test(); +}); + +/** + * Verify fetchSimRecords. + */ +add_test(function test_fetch_sim_records() { + let worker = newWorker(); + let context = worker.ContextPool._contexts[0]; + let RIL = context.RIL; + let iccRecord = context.ICCRecordHelper; + let simRecord = context.SimRecordHelper; + + function testFetchSimRecordes(expectCalled, expectCphsSuccess) { + let ifCalled = []; + + RIL.getIMSI = function() { + ifCalled.push("getIMSI"); + }; + + simRecord.readAD = function() { + ifCalled.push("readAD"); + }; + + simRecord.readCphsInfo = function(onsuccess, onerror) { + ifCalled.push("readCphsInfo"); + if (expectCphsSuccess) { + onsuccess(); + } else { + onerror(); + } + }; + + simRecord.readSST = function() { + ifCalled.push("readSST"); + }; + + simRecord.fetchSimRecords(); + + for (let i = 0; i < expectCalled.length; i++ ) { + if (ifCalled[i] != expectCalled[i]) { + do_print(expectCalled[i] + " is not called."); + ok(false); + } + } + } + + let expectCalled = ["getIMSI", "readAD", "readCphsInfo", "readSST"]; + testFetchSimRecordes(expectCalled, true); + testFetchSimRecordes(expectCalled, false); + + run_next_test(); +}); + +/** + * Verify SimRecordHelper.readMWIS + */ +add_test(function test_read_mwis() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let helper = context.GsmPDUHelper; + let recordHelper = context.SimRecordHelper; + let buf = context.Buf; + let io = context.ICCIOHelper; + let mwisData; + let postedMessage; + + worker.postMessage = function fakePostMessage(message) { + postedMessage = message; + }; + + io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { + if (mwisData) { + // Write data size + buf.writeInt32(mwisData.length * 2); + + // Write MWIS + for (let i = 0; i < mwisData.length; i++) { + helper.writeHexOctet(mwisData[i]); + } + + // Write string delimiter + buf.writeStringDelimiter(mwisData.length * 2); + + options.recordSize = mwisData.length; + if (options.callback) { + options.callback(options); + } + } else { + do_print("mwisData[] is not set."); + } + }; + + function buildMwisData(isActive, msgCount) { + if (msgCount < 0 || msgCount === GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN) { + msgCount = 0; + } else if (msgCount > 255) { + msgCount = 255; + } + + mwisData = [ (isActive) ? 0x01 : 0x00, + msgCount, + 0xFF, 0xFF, 0xFF ]; + } + + function do_test(isActive, msgCount) { + buildMwisData(isActive, msgCount); + recordHelper.readMWIS(); + + equal("iccmwis", postedMessage.rilMessageType); + equal(isActive, postedMessage.mwi.active); + equal((isActive) ? msgCount : 0, postedMessage.mwi.msgCount); + } + + do_test(true, GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN); + do_test(true, 1); + do_test(true, 255); + + do_test(false, 0); + do_test(false, 255); // Test the corner case when mwi is disable with incorrect msgCount. + + run_next_test(); +}); + +/** + * Verify SimRecordHelper.updateMWIS + */ +add_test(function test_update_mwis() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let pduHelper = context.GsmPDUHelper; + let ril = context.RIL; + ril.appType = CARD_APPTYPE_USIM; + ril.iccInfoPrivate.mwis = [0x00, 0x00, 0x00, 0x00, 0x00]; + let recordHelper = context.SimRecordHelper; + let buf = context.Buf; + let ioHelper = context.ICCIOHelper; + let recordSize = ril.iccInfoPrivate.mwis.length; + let recordNum = 1; + + ioHelper.updateLinearFixedEF = function(options) { + options.pathId = context.ICCFileHelper.getEFPath(options.fileId); + options.command = ICC_COMMAND_UPDATE_RECORD; + options.p1 = options.recordNumber; + options.p2 = READ_RECORD_ABSOLUTE_MODE; + options.p3 = recordSize; + ril.iccIO(options); + }; + + function do_test(isActive, count) { + let mwis = ril.iccInfoPrivate.mwis; + let isUpdated = false; + + function buildMwisData() { + let result = mwis.slice(0); + result[0] = isActive? (mwis[0] | 0x01) : (mwis[0] & 0xFE); + result[1] = (count === GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN) ? 0 : count; + + return result; + } + + buf.sendParcel = function() { + isUpdated = true; + + // Request Type. + equal(this.readInt32(), REQUEST_SIM_IO); + + // Token : we don't care + this.readInt32(); + + // command. + equal(this.readInt32(), ICC_COMMAND_UPDATE_RECORD); + + // fileId. + equal(this.readInt32(), ICC_EF_MWIS); + + // pathId. + equal(this.readString(), + EF_PATH_MF_SIM + ((ril.appType === CARD_APPTYPE_USIM) ? EF_PATH_ADF_USIM : EF_PATH_DF_GSM)); + + // p1. + equal(this.readInt32(), recordNum); + + // p2. + equal(this.readInt32(), READ_RECORD_ABSOLUTE_MODE); + + // p3. + equal(this.readInt32(), recordSize); + + // data. + let strLen = this.readInt32(); + equal(recordSize * 2, strLen); + let expectedMwis = buildMwisData(); + for (let i = 0; i < recordSize; i++) { + equal(expectedMwis[i], pduHelper.readHexOctet()); + } + this.readStringDelimiter(strLen); + + // pin2. + equal(this.readString(), null); + + // AID. Ignore because it's from modem. + this.readInt32(); + }; + + ok(!isUpdated); + + recordHelper.updateMWIS({ active: isActive, + msgCount: count }); + + ok((ril.iccInfoPrivate.mwis) ? isUpdated : !isUpdated); + } + + do_test(true, GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN); + do_test(true, 1); + do_test(true, 255); + + do_test(false, 0); + + // Test if Path ID is correct for SIM. + ril.appType = CARD_APPTYPE_SIM; + do_test(false, 0); + + // Test if loadLinearFixedEF() is not invoked in updateMWIS() when + // EF_MWIS is not loaded/available. + delete ril.iccInfoPrivate.mwis; + do_test(false, 0); + + run_next_test(); +}); + +/** + * Verify the call flow of receiving Class 2 SMS stored in SIM: + * 1. UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM. + * 2. SimRecordHelper.readSMS(). + * 3. sendChromeMessage() with rilMessageType == "sms-received". + */ +add_test(function test_read_new_sms_on_sim() { + // Instead of reusing newUint8Worker defined in this file, + // we define our own worker to fake the methods in WorkerBuffer dynamically. + function newSmsOnSimWorkerHelper() { + let _postedMessage; + let _worker = newWorker({ + postRILMessage: function(data) { + }, + postMessage: function(message) { + _postedMessage = message; + } + }); + + _worker.debug = do_print; + + return { + get postedMessage() { + return _postedMessage; + }, + get worker() { + return _worker; + }, + fakeWokerBuffer: function() { + let context = _worker.ContextPool._contexts[0]; + let index = 0; // index for read + let buf = []; + context.Buf.writeUint8 = function(value) { + buf.push(value); + }; + context.Buf.readUint8 = function() { + return buf[index++]; + }; + context.Buf.seekIncoming = function(offset) { + index += offset; + }; + context.Buf.getReadAvailable = function() { + return buf.length - index; + }; + } + }; + } + + let workerHelper = newSmsOnSimWorkerHelper(); + let worker = workerHelper.worker; + let context = worker.ContextPool._contexts[0]; + + context.ICCIOHelper.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { + // SimStatus: Unread, SMSC:+0123456789, Sender: +9876543210, Text: How are you? + let SimSmsPduHex = "0306911032547698040A9189674523010000208062917314080CC8F71D14969741F977FD07" + // In 4.2.25 EF_SMS Short Messages of 3GPP TS 31.102: + // 1. Record length == 176 bytes. + // 2. Any bytes in the record following the TPDU shall be filled with 'FF'. + + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"; + + workerHelper.fakeWokerBuffer(); + + context.Buf.writeString(SimSmsPduHex); + + options.recordSize = 176; // Record length is fixed to 176 bytes. + if (options.callback) { + options.callback(options); + } + }; + + function newSmsOnSimParcel() { + let data = new Uint8Array(4 + 4); // Int32List with 1 element. + let offset = 0; + + function writeInt(value) { + data[offset++] = value & 0xFF; + data[offset++] = (value >> 8) & 0xFF; + data[offset++] = (value >> 16) & 0xFF; + data[offset++] = (value >> 24) & 0xFF; + } + + writeInt(1); // Length of Int32List + writeInt(1); // RecordNum = 1. + + return newIncomingParcel(-1, + RESPONSE_TYPE_UNSOLICITED, + UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM, + data); + } + + function do_test() { + worker.onRILMessage(0, newSmsOnSimParcel()); + + let postedMessage = workerHelper.postedMessage; + + equal("sms-received", postedMessage.rilMessageType); + equal("+0123456789", postedMessage.SMSC); + equal("+9876543210", postedMessage.sender); + equal("How are you?", postedMessage.body); + } + + do_test(); + + run_next_test(); +}); + +/** + * Verify the result of updateDisplayCondition after reading EF_SPDI | EF_SPN. + */ +add_test(function test_update_display_condition() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let record = context.SimRecordHelper; + let helper = context.GsmPDUHelper; + let ril = context.RIL; + let buf = context.Buf; + let io = context.ICCIOHelper; + + function do_test_spdi() { + // No EF_SPN, but having EF_SPDI. + // It implies "ril.iccInfoPrivate.spnDisplayCondition = undefined;". + io.loadTransparentEF = function fakeLoadTransparentEF(options) { + // PLMN lists are : 234-136 and 466-92. + let spdi = [0xA3, 0x0B, 0x80, 0x09, 0x32, 0x64, 0x31, 0x64, 0x26, 0x9F, + 0xFF, 0xFF, 0xFF]; + + // Write data size. + buf.writeInt32(spdi.length * 2); + + // Write data. + for (let i = 0; i < spdi.length; i++) { + helper.writeHexOctet(spdi[i]); + } + + // Write string delimiter. + buf.writeStringDelimiter(spdi.length * 2); + + if (options.callback) { + options.callback(options); + } + }; + + record.readSPDI(); + + equal(ril.iccInfo.isDisplayNetworkNameRequired, true); + equal(ril.iccInfo.isDisplaySpnRequired, false); + } + + function do_test_spn(displayCondition, + expectedPlmnNameDisplay, + expectedSpnDisplay) { + io.loadTransparentEF = function fakeLoadTransparentEF(options) { + // "Android" as Service Provider Name. + let spn = [0x41, 0x6E, 0x64, 0x72, 0x6F, 0x69, 0x64]; + if (typeof displayCondition === 'number') { + spn.unshift(displayCondition); + } + + // Write data size. + buf.writeInt32(spn.length * 2); + + // Write data. + for (let i = 0; i < spn.length; i++) { + helper.writeHexOctet(spn[i]); + } + + // Write string delimiter. + buf.writeStringDelimiter(spn.length * 2); + + if (options.callback) { + options.callback(options); + } + }; + + record.readSPN(); + + equal(ril.iccInfo.isDisplayNetworkNameRequired, expectedPlmnNameDisplay); + equal(ril.iccInfo.isDisplaySpnRequired, expectedSpnDisplay); + } + + // Create empty operator object. + ril.operator = {}; + // Setup SIM MCC-MNC to 310-260 as home network. + ril.iccInfo.mcc = 310; + ril.iccInfo.mnc = 260; + + do_test_spdi(); + + // No network. + do_test_spn(0x00, true, true); + do_test_spn(0x01, true, true); + do_test_spn(0x02, true, false); + do_test_spn(0x03, true, false); + + // Home network. + ril.operator.mcc = 310; + ril.operator.mnc = 260; + do_test_spn(0x00, false, true); + do_test_spn(0x01, true, true); + do_test_spn(0x02, false, true); + do_test_spn(0x03, true, true); + + // Not HPLMN but in PLMN list. + ril.iccInfoPrivate.SPDI = [{"mcc":"234","mnc":"136"},{"mcc":"466","mnc":"92"}]; + ril.operator.mcc = 466; + ril.operator.mnc = 92; + do_test_spn(0x00, false, true); + do_test_spn(0x01, true, true); + do_test_spn(0x02, false, true); + do_test_spn(0x03, true, true); + ril.iccInfoPrivate.SPDI = null; // reset SPDI to null; + + // Non-Home network. + ril.operator.mcc = 466; + ril.operator.mnc = 01; + do_test_spn(0x00, true, true); + do_test_spn(0x01, true, true); + do_test_spn(0x02, true, false); + do_test_spn(0x03, true, false); + + run_next_test(); +}); + +/** + * Verify reading EF_IMG and EF_IIDF with ICC_IMG_CODING_SCHEME_BASIC + */ +add_test(function test_reading_img_basic() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let record = context.SimRecordHelper; + let helper = context.GsmPDUHelper; + let ril = context.RIL; + let buf = context.Buf; + let io = context.ICCIOHelper; + + let test_data = [ + {img: [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x06], + iidf: [ + [/* Header */ + 0x05, 0x05, + /* Image body */ + 0x11, 0x33, 0x55, 0xfe]], + expected: [ + {width: 0x05, + height: 0x05, + codingScheme: ICC_IMG_CODING_SCHEME_BASIC, + body: [0x11, 0x33, 0x55, 0xfe]}]}, + {img: [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x06, + /* Padding */ + 0xff, 0xff], + iidf: [ + [/* Header */ + 0x05, 0x05, + /* Image body */ + 0x11, 0x33, 0x55, 0xfe]], + expected: [ + {width: 0x05, + height: 0x05, + codingScheme: ICC_IMG_CODING_SCHEME_BASIC, + body: [0x11, 0x33, 0x55, 0xfe]}]}, + {img: [0x02, 0x10, 0x01, 0x11, 0x4f, 0x04, 0x00, 0x05, 0x00, 0x04, 0x10, + 0x01, 0x11, 0x4f, 0x05, 0x00, 0x05, 0x00, 0x04], + iidf: [ + [/* Data offset */ + 0xff, 0xff, 0xff, 0xff, 0xff, + /* Header */ + 0x10, 0x01, + /* Image body */ + 0x11, 0x99, + /* Trailing data */ + 0xff, 0xff, 0xff], + [/* Data offset */ + 0xff, 0xff, 0xff, 0xff, 0xff, + /* Header */ + 0x10, 0x01, + /* Image body */ + 0x99, 0x11]], + expected: [ + {width: 0x10, + height: 0x01, + codingScheme: ICC_IMG_CODING_SCHEME_BASIC, + body: [0x11, 0x99]}, + {width: 0x10, + height: 0x01, + codingScheme: ICC_IMG_CODING_SCHEME_BASIC, + body: [0x99, 0x11]}]}, + {img: [0x01, 0x28, 0x20, 0x11, 0x4f, 0xac, 0x00, 0x0b, 0x00, 0xa2], + iidf: [ + [/* Data offset */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* Header */ + 0x28, 0x20, + /* Image body */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, + 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, + 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, + 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x00, 0x01, 0x02, + 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, + 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f]], + expected: [ + {width: 0x28, + height: 0x20, + codingScheme: ICC_IMG_CODING_SCHEME_BASIC, + body: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, + 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, + 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f]}]}]; + + function do_test(img, iidf, expected) { + io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { + // Write data size + buf.writeInt32(img.length * 2); + + // Write data + for (let i = 0; i < img.length; i++) { + helper.writeHexOctet(img[i]); + } + + // Write string delimiter + buf.writeStringDelimiter(img.length * 2); + + if (options.callback) { + options.callback(options); + } + }; + + let instanceIndex = 0; + io.loadTransparentEF = function fakeLoadTransparentEF(options) { + // Write data size + buf.writeInt32(iidf[instanceIndex].length * 2); + + // Write data + for (let i = 0; i < iidf[instanceIndex].length; i++) { + helper.writeHexOctet(iidf[instanceIndex][i]); + } + + // Write string delimiter + buf.writeStringDelimiter(iidf[instanceIndex].length * 2); + + instanceIndex++; + + if (options.callback) { + options.callback(options); + } + }; + + let onsuccess = function(icons) { + equal(icons.length, expected.length); + for (let i = 0; i < icons.length; i++) { + let icon = icons[i]; + let exp = expected[i]; + equal(icon.width, exp.width); + equal(icon.height, exp.height); + equal(icon.codingScheme, exp.codingScheme); + + equal(icon.body.length, exp.body.length); + for (let j = 0; j < icon.body.length; j++) { + equal(icon.body[j], exp.body[j]); + } + } + }; + record.readIMG(0, onsuccess); + } + + for (let i = 0; i< test_data.length; i++) { + do_test(test_data[i].img, test_data[i].iidf, test_data[i].expected); + } + run_next_test(); +}); + +/** + * Verify reading EF_IMG and EF_IIDF with the case data length is not enough + */ +add_test(function test_reading_img_length_error() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let record = context.SimRecordHelper; + let helper = context.GsmPDUHelper; + let ril = context.RIL; + let buf = context.Buf; + let io = context.ICCIOHelper; + + let test_data = [ + {/* Offset length not enough, should be 4. */ + img: [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x04, 0x00, 0x06], + iidf: [0xff, 0xff, 0xff, // Offset. + 0x05, 0x05, 0x11, 0x22, 0x33, 0xfe]}, + {/* iidf data length not enough, should be 6. */ + img: [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x06], + iidf: [0x05, 0x05, 0x11, 0x22, 0x33]}]; + + function do_test(img, iidf) { + io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { + // Write data size + buf.writeInt32(img.length * 2); + + // Write data + for (let i = 0; i < img.length; i++) { + helper.writeHexOctet(img[i]); + } + + // Write string delimiter + buf.writeStringDelimiter(img.length * 2); + + if (options.callback) { + options.callback(options); + } + }; + + io.loadTransparentEF = function fakeLoadTransparentEF(options) { + // Write data size + buf.writeInt32(iidf.length * 2); + + // Write data + for (let i = 0; i < iidf.length; i++) { + helper.writeHexOctet(iidf[i]); + } + + // Write string delimiter + buf.writeStringDelimiter(iidf.length * 2); + + if (options.callback) { + options.callback(options); + } + }; + + let onsuccess = function() { + do_print("onsuccess shouldn't be called."); + ok(false); + }; + + let onerror = function() { + do_print("onerror called as expected."); + ok(true); + }; + + record.readIMG(0, onsuccess, onerror); + } + + for (let i = 0; i < test_data.length; i++) { + do_test(test_data[i].img, test_data[i].iidf); + } + run_next_test(); +}); + +/** + * Verify reading EF_IMG and EF_IIDF with an invalid fileId + */ +add_test(function test_reading_img_invalid_fileId() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let record = context.SimRecordHelper; + let helper = context.GsmPDUHelper; + let ril = context.RIL; + let buf = context.Buf; + let io = context.ICCIOHelper; + + // Test invalid fileId: 0x5f00. + let img_test = [0x01, 0x05, 0x05, 0x11, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x06]; + let iidf_test = [0x05, 0x05, 0x11, 0x22, 0x33, 0xfe]; + + io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { + // Write data size + buf.writeInt32(img_test.length * 2); + + // Write data + for (let i = 0; i < img_test.length; i++) { + helper.writeHexOctet(img_test[i]); + } + + // Write string delimiter + buf.writeStringDelimiter(img_test.length * 2); + + if (options.callback) { + options.callback(options); + } + }; + + io.loadTransparentEF = function fakeLoadTransparentEF(options) { + // Write data size + buf.writeInt32(iidf_test.length * 2); + + // Write data + for (let i = 0; i < iidf_test.length; i++) { + helper.writeHexOctet(iidf_test[i]); + } + + // Write string delimiter + buf.writeStringDelimiter(iidf_test.length * 2); + + if (options.callback) { + options.callback(options); + } + }; + + let onsuccess = function() { + do_print("onsuccess shouldn't be called."); + ok(false); + }; + + let onerror = function() { + do_print("onerror called as expected."); + ok(true); + }; + + record.readIMG(0, onsuccess, onerror); + + run_next_test(); +}); + +/** + * Verify reading EF_IMG with a wrong record length + */ +add_test(function test_reading_img_wrong_record_length() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let record = context.SimRecordHelper; + let helper = context.GsmPDUHelper; + let ril = context.RIL; + let buf = context.Buf; + let io = context.ICCIOHelper; + + let test_data = [ + [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00], + [0x02, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x06]]; + + function do_test(img) { + io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { + // Write data size + buf.writeInt32(img.length * 2); + + // Write data + for (let i = 0; i < img.length; i++) { + helper.writeHexOctet(img[i]); + } + + // Write string delimiter + buf.writeStringDelimiter(img.length * 2); + + if (options.callback) { + options.callback(options); + } + }; + + let onsuccess = function() { + do_print("onsuccess shouldn't be called."); + ok(false); + }; + + let onerror = function() { + do_print("onerror called as expected."); + ok(true); + }; + + record.readIMG(0, onsuccess, onerror); + } + + for (let i = 0; i < test_data.length; i++) { + do_test(test_data[i]); + } + run_next_test(); +}); + +/** + * Verify reading EF_IMG and EF_IIDF with ICC_IMG_CODING_SCHEME_COLOR + */ +add_test(function test_reading_img_color() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let record = context.SimRecordHelper; + let helper = context.GsmPDUHelper; + let ril = context.RIL; + let buf = context.Buf; + let io = context.ICCIOHelper; + + let test_data = [ + {img: [0x01, 0x05, 0x05, 0x21, 0x4f, 0x11, 0x00, 0x00, 0x00, 0x13], + iidf: [ + [/* Header */ + 0x05, 0x05, 0x03, 0x08, 0x00, 0x13, + /* Image body */ + 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, + 0xb0, 0xc0, 0xd0, + /* Clut entries */ + 0x00, 0x01, 0x02, + 0x10, 0x11, 0x12, + 0x20, 0x21, 0x22, + 0x30, 0x31, 0x32, + 0x40, 0x41, 0x42, + 0x50, 0x51, 0x52, + 0x60, 0x61, 0x62, + 0x70, 0x71, 0x72]], + expected: [ + {width: 0x05, + height: 0x05, + codingScheme: ICC_IMG_CODING_SCHEME_COLOR, + bitsPerImgPoint: 0x03, + numOfClutEntries: 0x08, + body: [0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0, + 0xc0, 0xd0], + clut: [0x00, 0x01, 0x02, + 0x10, 0x11, 0x12, + 0x20, 0x21, 0x22, + 0x30, 0x31, 0x32, + 0x40, 0x41, 0x42, + 0x50, 0x51, 0x52, + 0x60, 0x61, 0x62, + 0x70, 0x71, 0x72]}]}, + {img: [0x02, 0x01, 0x06, 0x21, 0x4f, 0x33, 0x00, 0x02, 0x00, 0x08, 0x01, + 0x06, 0x21, 0x4f, 0x44, 0x00, 0x02, 0x00, 0x08], + iidf: [ + [/* Data offset */ + 0xff, 0xff, + /* Header */ + 0x01, 0x06, 0x02, 0x04, 0x00, 0x0d, + /* Image body */ + 0x40, 0x50, + /* Clut offset */ + 0xaa, 0xbb, 0xcc, + /* Clut entries */ + 0x01, 0x03, 0x05, + 0x21, 0x23, 0x25, + 0x41, 0x43, 0x45, + 0x61, 0x63, 0x65], + [/* Data offset */ + 0xff, 0xff, + /* Header */ + 0x01, 0x06, 0x02, 0x04, 0x00, 0x0d, + /* Image body */ + 0x4f, 0x5f, + /* Clut offset */ + 0xaa, 0xbb, 0xcc, + /* Clut entries */ + 0x11, 0x13, 0x15, + 0x21, 0x23, 0x25, + 0x41, 0x43, 0x45, + 0x61, 0x63, 0x65]], + expected: [ + {width: 0x01, + height: 0x06, + codingScheme: ICC_IMG_CODING_SCHEME_COLOR, + bitsPerImgPoint: 0x02, + numOfClutEntries: 0x04, + body: [0x40, 0x50], + clut: [0x01, 0x03, 0x05, + 0x21, 0x23, 0x25, + 0x41, 0x43, 0x45, + 0x61, 0x63, 0x65]}, + {width: 0x01, + height: 0x06, + codingScheme: ICC_IMG_CODING_SCHEME_COLOR, + bitsPerImgPoint: 0x02, + numOfClutEntries: 0x04, + body: [0x4f, 0x5f], + clut: [0x11, 0x13, 0x15, + 0x21, 0x23, 0x25, + 0x41, 0x43, 0x45, + 0x61, 0x63, 0x65]}]}]; + + function do_test(img, iidf, expected) { + io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { + // Write data size + buf.writeInt32(img.length * 2); + + // Write data + for (let i = 0; i < img.length; i++) { + helper.writeHexOctet(img[i]); + } + + // Write string delimiter + buf.writeStringDelimiter(img.length * 2); + + if (options.callback) { + options.callback(options); + } + }; + + let instanceIndex = 0; + io.loadTransparentEF = function fakeLoadTransparentEF(options) { + // Write data size + buf.writeInt32(iidf[instanceIndex].length * 2); + + // Write data + for (let i = 0; i < iidf[instanceIndex].length; i++) { + helper.writeHexOctet(iidf[instanceIndex][i]); + } + + // Write string delimiter + buf.writeStringDelimiter(iidf[instanceIndex].length * 2); + + instanceIndex++; + + if (options.callback) { + options.callback(options); + } + }; + + let onsuccess = function(icons) { + equal(icons.length, expected.length); + for (let i = 0; i < icons.length; i++) { + let icon = icons[i]; + let exp = expected[i]; + equal(icon.width, exp.width); + equal(icon.height, exp.height); + equal(icon.codingScheme, exp.codingScheme); + + equal(icon.body.length, exp.body.length); + for (let j = 0; j < icon.body.length; j++) { + equal(icon.body[j], exp.body[j]); + } + + equal(icon.clut.length, exp.clut.length); + for (let j = 0; j < icon.clut.length; j++) { + equal(icon.clut[j], exp.clut[j]); + } + } + }; + + record.readIMG(0, onsuccess); + } + + for (let i = 0; i< test_data.length; i++) { + do_test(test_data[i].img, test_data[i].iidf, test_data[i].expected); + } + run_next_test(); +}); + +/** + * Verify reading EF_IMG and EF_IIDF with + * ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY + */ +add_test(function test_reading_img_color() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let record = context.SimRecordHelper; + let helper = context.GsmPDUHelper; + let ril = context.RIL; + let buf = context.Buf; + let io = context.ICCIOHelper; + + let test_data = [ + {img: [0x01, 0x05, 0x05, 0x22, 0x4f, 0x11, 0x00, 0x00, 0x00, 0x13], + iidf: [ + [/* Header */ + 0x05, 0x05, 0x03, 0x08, 0x00, 0x13, + /* Image body */ + 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, + 0xb0, 0xc0, 0xd0, + /* Clut entries */ + 0x00, 0x01, 0x02, + 0x10, 0x11, 0x12, + 0x20, 0x21, 0x22, + 0x30, 0x31, 0x32, + 0x40, 0x41, 0x42, + 0x50, 0x51, 0x52, + 0x60, 0x61, 0x62, + 0x70, 0x71, 0x72]], + expected: [ + {width: 0x05, + height: 0x05, + codingScheme: ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY, + bitsPerImgPoint: 0x03, + numOfClutEntries: 0x08, + body: [0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, + 0xa0, 0xb0, 0xc0, 0xd0], + clut: [0x00, 0x01, 0x02, + 0x10, 0x11, 0x12, + 0x20, 0x21, 0x22, + 0x30, 0x31, 0x32, + 0x40, 0x41, 0x42, + 0x50, 0x51, 0x52, + 0x60, 0x61, 0x62, + 0x70, 0x71, 0x72]}]}, + {img: [0x02, 0x01, 0x06, 0x22, 0x4f, 0x33, 0x00, 0x02, 0x00, 0x08, 0x01, + 0x06, 0x22, 0x4f, 0x33, 0x00, 0x02, 0x00, 0x08], + iidf: [ + [/* Data offset */ + 0xff, 0xff, + /* Header */ + 0x01, 0x06, 0x02, 0x04, 0x00, 0x0d, + /* Image body */ + 0x40, 0x50, + /* Clut offset */ + 0x0a, 0x0b, 0x0c, + /* Clut entries */ + 0x01, 0x03, 0x05, + 0x21, 0x23, 0x25, + 0x41, 0x43, 0x45, + 0x61, 0x63, 0x65], + [/* Data offset */ + 0xff, 0xff, + /* Header */ + 0x01, 0x06, 0x02, 0x04, 0x00, 0x0d, + /* Image body */ + 0x4f, 0x5f, + /* Clut offset */ + 0x0a, 0x0b, 0x0c, + /* Clut entries */ + 0x11, 0x13, 0x15, + 0x21, 0x23, 0x25, + 0x41, 0x43, 0x45, + 0x61, 0x63, 0x65]], + expected: [ + {width: 0x01, + height: 0x06, + codingScheme: ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY, + bitsPerImgPoint: 0x02, + numOfClutEntries: 0x04, + body: [0x40, 0x50], + clut: [0x01, 0x03, 0x05, + 0x21, 0x23, 0x25, + 0x41, 0x43, 0x45, + 0x61, 0x63, 0x65]}, + {width: 0x01, + height: 0x06, + codingScheme: ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY, + bitsPerImgPoint: 0x02, + numOfClutEntries: 0x04, + body: [0x4f, 0x5f], + clut: [0x11, 0x13, 0x15, + 0x21, 0x23, 0x25, + 0x41, 0x43, 0x45, + 0x61, 0x63, 0x65]}]}]; + + function do_test(img, iidf, expected) { + io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { + // Write data size + buf.writeInt32(img.length * 2); + + // Write data + for (let i = 0; i < img.length; i++) { + helper.writeHexOctet(img[i]); + } + + // Write string delimiter + buf.writeStringDelimiter(img.length * 2); + + if (options.callback) { + options.callback(options); + } + }; + + let instanceIndex = 0; + io.loadTransparentEF = function fakeLoadTransparentEF(options) { + // Write data size + buf.writeInt32(iidf[instanceIndex].length * 2); + + // Write data + for (let i = 0; i < iidf[instanceIndex].length; i++) { + helper.writeHexOctet(iidf[instanceIndex][i]); + } + + // Write string delimiter + buf.writeStringDelimiter(iidf[instanceIndex].length * 2); + + instanceIndex++; + + if (options.callback) { + options.callback(options); + } + }; + + let onsuccess = function(icons) { + equal(icons.length, expected.length); + for (let i = 0; i < icons.length; i++) { + let icon = icons[i]; + let exp = expected[i]; + equal(icon.width, exp.width); + equal(icon.height, exp.height); + equal(icon.codingScheme, exp.codingScheme); + + equal(icon.body.length, exp.body.length); + for (let j = 0; j < icon.body.length; j++) { + equal(icon.body[j], exp.body[j]); + } + + equal(icon.clut.length, exp.clut.length); + for (let j = 0; j < icon.clut.length; j++) { + equal(icon.clut[j], exp.clut[j]); + } + } + }; + + record.readIMG(0, onsuccess); + } + + for (let i = 0; i< test_data.length; i++) { + do_test(test_data[i].img, test_data[i].iidf, test_data[i].expected); + } + run_next_test(); +}); + +/** + * Verify SimRecordHelper.readCphsInfo + */ +add_test(function test_read_cphs_info() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let RIL = context.RIL; + let pduHelper = context.GsmPDUHelper; + let recordHelper = context.SimRecordHelper; + let buf = context.Buf; + let io = context.ICCIOHelper; + let cphsPDU = new Uint8Array(3); + + io.loadTransparentEF = function(options) { + if (cphsPDU) { + // Write data size + buf.writeInt32(cphsPDU.length * 2); + + // Write CPHS INFO + for (let i = 0; i < cphsPDU.length; i++) { + pduHelper.writeHexOctet(cphsPDU[i]); + } + + // Write string delimiter + buf.writeStringDelimiter(cphsPDU.length * 2); + + if (options.callback) { + options.callback(options); + } + } else { + do_print("cphsPDU[] is not set."); + } + }; + + function do_test(cphsInfo, cphsSt) { + let onsuccess = false; + let onerror = false; + + delete RIL.iccInfoPrivate.cphsSt; + cphsPDU.set(cphsInfo); + recordHelper.readCphsInfo(() => { onsuccess = true; }, + () => { onerror = true; }); + + ok((cphsSt) ? onsuccess : onerror); + ok(!((cphsSt) ? onerror : onsuccess)); + if (cphsSt) { + equal(RIL.iccInfoPrivate.cphsSt.length, cphsSt.length); + for (let i = 0; i < cphsSt.length; i++) { + equal(RIL.iccInfoPrivate.cphsSt[i], cphsSt[i]); + } + } else { + equal(RIL.iccInfoPrivate.cphsSt, cphsSt); + } + } + + do_test([ + 0x01, // Phase 1 + 0xFF, // All available & activated + 0x03 // All available & activated + ], + [ + 0x3F, // All services except ONSF(bit 8-7) are available and activated. + 0x00 // INFO_NUM shall not be available & activated. + ]); + + do_test([ + 0x02, // Phase 2 + 0xFF, // All available & activated + 0x03 // All available & activated + ], + [ + 0xF3, // All services except ONSF are available and activated. + 0x03 // INFO_NUM shall not be available & activated. + ]); + + do_test([ + 0x03, // Phase 3 + 0xFF, // All available & activated + 0x03 // All available & activated + ], + undefined); // RIL.iccInfoPrivate.cphsSt shall be remained as 'undefined'. + + run_next_test(); +}); + +/** + * Verify SimRecordHelper.readMBDN/SimRecordHelper.readCphsMBN + */ +add_test(function test_read_voicemail_number() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let RIL = context.RIL; + let pduHelper = context.GsmPDUHelper; + let recordHelper = context.SimRecordHelper; + let buf = context.Buf; + let io = context.ICCIOHelper; + let postedMessage; + + worker.postMessage = function(message) { + postedMessage = message; + }; + + io.loadLinearFixedEF = function(options) { + let mbnData = [ + 0x56, 0x6F, 0x69, 0x63, 0x65, 0x6D, 0x61, 0x69, + 0x6C, 0xFF, // Alpha Identifier: Voicemail + 0x03, // Length of BCD number: 3 + 0x80, // TOA: Unknown + 0x11, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, // Dialing Number: 111 + 0xFF, // Capability/Configuration Record Identifier + 0xFF // Extension Record Identifier + ]; + + // Write data size + buf.writeInt32(mbnData.length * 2); + + // Write MBN + for (let i = 0; i < mbnData.length; i++) { + pduHelper.writeHexOctet(mbnData[i]); + } + + // Write string delimiter + buf.writeStringDelimiter(mbnData.length * 2); + + options.recordSize = mbnData.length; + if (options.callback) { + options.callback(options); + } + }; + + function do_test(funcName, msgCount) { + postedMessage = null; + delete RIL.iccInfoPrivate.mbdn; + recordHelper[funcName](); + + equal("iccmbdn", postedMessage.rilMessageType); + equal("Voicemail", postedMessage.alphaId); + equal("111", postedMessage.number); + } + + do_test("readMBDN"); + do_test("readCphsMBN"); + + run_next_test(); +}); + +/** + * Verify the recovery from SimRecordHelper.readCphsMBN() if MBDN is not valid + * or is empty after SimRecordHelper.readMBDN(). + */ +add_test(function test_read_mbdn_recovered_from_cphs_mbn() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let RIL = context.RIL; + let pduHelper = context.GsmPDUHelper; + let recordHelper = context.SimRecordHelper; + let iccUtilsHelper = context.ICCUtilsHelper; + let buf = context.Buf; + let io = context.ICCIOHelper; + + io.loadLinearFixedEF = function(options) { + let mbnData = [ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + ]; + + // Write data size + buf.writeInt32(mbnData.length * 2); + + // Write MBN + for (let i = 0; i < mbnData.length; i++) { + pduHelper.writeHexOctet(mbnData[i]); + } + + // Write string delimiter + buf.writeStringDelimiter(mbnData.length * 2); + + options.recordSize = mbnData.length; + if (options.callback) { + options.callback(options); + } + }; + + iccUtilsHelper.isCphsServiceAvailable = function(geckoService) { + return geckoService == "MBN"; + }; + + let isRecovered = false; + recordHelper.readCphsMBN = function(onComplete) { + isRecovered = true; + }; + + recordHelper.readMBDN(); + + equal(RIL.iccInfoPrivate.mbdn, undefined); + ok(isRecovered); + + run_next_test(); +}); + +/** + * Verify reading EF_PNN with different coding scheme. + */ +add_test(function test_pnn_with_different_coding_scheme() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let record = context.SimRecordHelper; + let pduHelper = context.GsmPDUHelper; + let ril = context.RIL; + let buf = context.Buf; + let io = context.ICCIOHelper; + + let test_data = [{ + // Cell Broadcast data coding scheme - "Test1" + pnn: [0x43, 0x06, 0x85, 0xD4, 0xF2, 0x9C, 0x1E, 0x03], + expectedResult: "Test1" + },{ + // UCS2 with 0x80 - "Test1" + pnn: [0x43, 0x0C, 0x90, 0x80, 0x00, 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x31], + expectedResult: "Test1" + },{ + // UCS2 with 0x81 - "Mozilla\u694a" + pnn: [0x43, 0x0E, 0x90, 0x81, 0x08, 0xd2, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, 0xff, 0xff], + expectedResult: "Mozilla\u694a" + },{ + // UCS2 with 0x82 - "Mozilla\u694a" + pnn: [0x43, 0x0F, 0x90, 0x82, 0x08, 0x69, 0x00, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, 0xff, 0xff], + expectedResult: "Mozilla\u694a" + }]; + + function do_test_pnn(pnn, expectedResult) { + io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { + // Write data size. + buf.writeInt32(pnn.length * 2); + + // Write data. + for (let i = 0; i < pnn.length; i++) { + pduHelper.writeHexOctet(pnn[i]); + } + + // Write string delimiter. + buf.writeStringDelimiter(pnn.length * 2); + + if (options.callback) { + options.callback(options); + } + }; + + record.readPNN(); + + equal(ril.iccInfoPrivate.PNN[0].fullName, expectedResult); + // Reset PNN info for next test + ril.iccInfoPrivate.PNN = null; + } + + ril.appType = CARD_APPTYPE_SIM; + for (let i = 0; i < test_data.length; i++) { + do_test_pnn(test_data[i].pnn, test_data[i].expectedResult); + } + + run_next_test(); +}); + +/** + * Verify reading EF_PNN with different content. + */ +add_test(function test_pnn_with_different_content() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let record = context.SimRecordHelper; + let pduHelper = context.GsmPDUHelper; + let ril = context.RIL; + let buf = context.Buf; + let io = context.ICCIOHelper; + + let test_data = [{ + // [0]: {"fullName":"Test1","shortName":"Test1"} + pnn: [0x43, 0x06, 0x85, 0xD4, 0xF2, 0x9C, 0x1E, 0x03, + 0x45, 0x06, 0x85, 0xD4, 0xF2, 0x9C, 0x1E, 0x03], + expectedResult: {"fullName": "Test1","shortName": "Test1"} + },{ + // [1]: {"fullName":"Test2"} + pnn: [0x43, 0x06, 0x85, 0xD4, 0xF2, 0x9C, 0x2E, 0x03], + expectedResult: {"fullName": "Test2"} + },{ + // [2]: undefined + pnn: [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF], + },{ + // [3]: {"fullName": "Test4"} + pnn: [0x43, 0x06, 0x85, 0xD4, 0xF2, 0x9C, 0x4E, 0x03], + expectedResult: {"fullName": "Test4"} + },{ + // [4]: undefined + pnn: [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF], + }]; + + function do_test_pnn() { + ril.iccIO = function fakeIccIO(options) { + let index = options.p1 - 1; + let pnn = test_data[index].pnn; + + // Write data size. + buf.writeInt32(pnn.length * 2); + + // Write data. + for (let i = 0; i < pnn.length; i++) { + pduHelper.writeHexOctet(pnn[i]); + } + + // Write string delimiter. + buf.writeStringDelimiter(pnn.length * 2); + + if (options.callback) { + options.callback(options); + } + }; + + io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { + options.p1 = 1; + options.totalRecords = test_data.length; + + ril.iccIO(options); + }; + + record.readPNN(); + + equal(test_data.length, ril.iccInfoPrivate.PNN.length); + for (let i = 0; i < test_data.length; i++) { + if (test_data[i].expectedResult) { + equal(test_data[i].expectedResult.fullName, + ril.iccInfoPrivate.PNN[i].fullName); + equal(test_data[i].expectedResult.shortName, + ril.iccInfoPrivate.PNN[i].shortName); + } else { + equal(test_data[i].expectedResult, ril.iccInfoPrivate.PNN[i]); + } + } + } + + ril.appType = CARD_APPTYPE_SIM; + do_test_pnn(); + + run_next_test(); +}); |