зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1122376 - Support read SIM contact dialling number exceed 20 digits. r=echen
This commit is contained in:
Родитель
95f260a070
Коммит
c288c4bd19
|
@ -9,8 +9,9 @@ function testReadContacts(aIcc, aType) {
|
|||
let iccId = aIcc.iccInfo.iccid;
|
||||
return aIcc.readContacts(aType)
|
||||
.then((aResult) => {
|
||||
|
||||
is(Array.isArray(aResult), true);
|
||||
is(aResult.length, 4, "Check contact number.");
|
||||
is(aResult.length, 6, "Check contact number.");
|
||||
|
||||
// Alpha Id(Encoded with GSM 8 bit): "Mozilla", Dialling Number: 15555218201
|
||||
is(aResult[0].name[0], "Mozilla");
|
||||
|
@ -31,6 +32,18 @@ function testReadContacts(aIcc, aType) {
|
|||
is(aResult[3].name[0], "Huang 黃");
|
||||
is(aResult[3].tel[0].value, "15555218204");
|
||||
is(aResult[3].id, iccId + "4");
|
||||
|
||||
// Alpha Id(Encoded with GSM 8 bit): "Contact001",
|
||||
// Dialling Number: 9988776655443322110001234567890123456789
|
||||
is(aResult[4].name[0], "Contact001");
|
||||
is(aResult[4].tel[0].value, "9988776655443322110001234567890123456789");
|
||||
is(aResult[4].id, iccId + "5");
|
||||
|
||||
// Alpha Id(Encoded with GSM 8 bit): "Contact002",
|
||||
// Dialling Number: 0123456789012345678999887766554433221100
|
||||
is(aResult[5].name[0], "Contact002");
|
||||
is(aResult[5].tel[0].value, "0123456789012345678999887766554433221100");
|
||||
is(aResult[5].id, iccId + "6");
|
||||
}, (aError) => {
|
||||
ok(false, "Cannot get " + aType + " contacts");
|
||||
});
|
||||
|
|
|
@ -574,6 +574,12 @@ this.ADN_MAX_BCD_NUMBER_BYTES = 11;
|
|||
// Maximum digits of the Dialling Number in ADN.
|
||||
// See TS 151.011 clause 10.5.1 EF_ADN, 'Dialling Number'.
|
||||
this.ADN_MAX_NUMBER_DIGITS = 20;
|
||||
// Maximum size of BCD numbers in EXT.
|
||||
// See TS 151.011 clause 10.5.10 EF_EXT1, 'Extension data'.
|
||||
this.EXT_MAX_BCD_NUMBER_BYTES = 10;
|
||||
// Maximum digits of the Dialling Number in EXT.
|
||||
// See TS 151.011 clause 10.5.10 EF_EXT1, 'Extension data'.
|
||||
this.EXT_MAX_NUMBER_DIGITS = 20;
|
||||
|
||||
// READ_RECORD mode, TS 102.221
|
||||
this.READ_RECORD_ABSOLUTE_MODE = 4;
|
||||
|
@ -1262,10 +1268,13 @@ this.GECKO_ICC_SERVICES = {
|
|||
FDN: 3,
|
||||
PLMNSEL: 7,
|
||||
MSISDN: 9,
|
||||
EXT1: 10,
|
||||
EXT2: 11,
|
||||
CBMI: 14,
|
||||
GID1: 15,
|
||||
SPN: 17,
|
||||
SDN: 18,
|
||||
EXT3: 19,
|
||||
DATA_DOWNLOAD_SMS_CB: 25,
|
||||
DATA_DOWNLOAD_SMS_PP: 26,
|
||||
CBMIR: 30,
|
||||
|
@ -1280,7 +1289,9 @@ this.GECKO_ICC_SERVICES = {
|
|||
// @see 3GPP TS 31.102 4.2.8 (USIM).
|
||||
usim: {
|
||||
FDN: 2,
|
||||
EXT2: 3,
|
||||
SDN: 4,
|
||||
EXT3: 5,
|
||||
BDN: 6,
|
||||
CBMI: 15,
|
||||
CBMIR: 16,
|
||||
|
@ -1300,8 +1311,11 @@ this.GECKO_ICC_SERVICES = {
|
|||
ruim: {
|
||||
FDN: 3,
|
||||
ENHANCED_PHONEBOOK: 6,
|
||||
EXT1: 10,
|
||||
EXT2: 11,
|
||||
SPN: 17,
|
||||
SDN: 18
|
||||
SDN: 18,
|
||||
EXT3: 19,
|
||||
},
|
||||
// @see B.3.1.1 CPHS Information in CPHS Phase 2:
|
||||
// Indicates which of the CPHS 'optional' data-fields are present in the SIM card:
|
||||
|
|
|
@ -11108,6 +11108,9 @@ ICCFileHelperObject.prototype = {
|
|||
case ICC_EF_FDN:
|
||||
case ICC_EF_MSISDN:
|
||||
case ICC_EF_SMS:
|
||||
case ICC_EF_EXT1:
|
||||
case ICC_EF_EXT2:
|
||||
case ICC_EF_EXT3:
|
||||
return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM;
|
||||
case ICC_EF_AD:
|
||||
case ICC_EF_MBDN:
|
||||
|
@ -11177,6 +11180,9 @@ ICCFileHelperObject.prototype = {
|
|||
case ICC_EF_CSIM_SPN:
|
||||
return EF_PATH_MF_SIM + EF_PATH_DF_CDMA;
|
||||
case ICC_EF_FDN:
|
||||
case ICC_EF_EXT1:
|
||||
case ICC_EF_EXT2:
|
||||
case ICC_EF_EXT3:
|
||||
return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM;
|
||||
default:
|
||||
return null;
|
||||
|
@ -11582,24 +11588,20 @@ ICCRecordHelperObject.prototype = {
|
|||
/**
|
||||
* Read ICC ADN like EF, i.e. EF_ADN, EF_FDN.
|
||||
*
|
||||
* @param fileId EF id of the ADN or FDN.
|
||||
* @param fileId EF id of the ADN, FDN or SDN.
|
||||
* @param extFileId EF id of the EXT.
|
||||
* @param onsuccess Callback to be called when success.
|
||||
* @param onerror Callback to be called when error.
|
||||
*/
|
||||
readADNLike: function(fileId, onsuccess, onerror) {
|
||||
readADNLike: function(fileId, extFileId, onsuccess, onerror) {
|
||||
let ICCIOHelper = this.context.ICCIOHelper;
|
||||
|
||||
function callback(options) {
|
||||
let contact =
|
||||
this.context.ICCPDUHelper.readAlphaIdDiallingNumber(options.recordSize);
|
||||
if (contact) {
|
||||
contact.recordId = options.p1;
|
||||
contacts.push(contact);
|
||||
}
|
||||
|
||||
if (options.p1 < options.totalRecords) {
|
||||
ICCIOHelper.loadNextRecord(options);
|
||||
} else {
|
||||
let loadNextContactRecord = () => {
|
||||
if (options.p1 < options.totalRecords) {
|
||||
ICCIOHelper.loadNextRecord(options);
|
||||
return;
|
||||
}
|
||||
if (DEBUG) {
|
||||
for (let i = 0; i < contacts.length; i++) {
|
||||
this.context.debug("contact [" + i + "] " +
|
||||
|
@ -11609,7 +11611,29 @@ ICCRecordHelperObject.prototype = {
|
|||
if (onsuccess) {
|
||||
onsuccess(contacts);
|
||||
}
|
||||
};
|
||||
|
||||
let contact =
|
||||
this.context.ICCPDUHelper.readAlphaIdDiallingNumber(options.recordSize);
|
||||
if (contact) {
|
||||
let record = {
|
||||
recordId: options.p1,
|
||||
alphaId: contact.alphaId,
|
||||
number: contact.number
|
||||
};
|
||||
contacts.push(record);
|
||||
|
||||
if (extFileId && contact.extRecordNumber != 0xff) {
|
||||
this.readExtension(extFileId, contact.extRecordNumber, (number) => {
|
||||
if (number) {
|
||||
record.number += number;
|
||||
}
|
||||
loadNextContactRecord();
|
||||
}, () => loadNextContactRecord());
|
||||
return;
|
||||
}
|
||||
}
|
||||
loadNextContactRecord();
|
||||
}
|
||||
|
||||
let contacts = [];
|
||||
|
@ -12084,6 +12108,64 @@ ICCRecordHelperObject.prototype = {
|
|||
callback: callback.bind(this),
|
||||
onerror: onerror});
|
||||
},
|
||||
|
||||
/**
|
||||
* Read Extension Number from TS 151.011 clause 10.5.10, TS 31.102, clause 4.4.2.4
|
||||
*
|
||||
* @param fileId EF Extension id
|
||||
* @param recordNumber The number of the record shall be loaded.
|
||||
* @param onsuccess Callback to be called when success.
|
||||
* @param onerror Callback to be called when error.
|
||||
*/
|
||||
readExtension: function(fileId, recordNumber, onsuccess, onerror) {
|
||||
let callback = (options) => {
|
||||
let Buf = this.context.Buf;
|
||||
let length = Buf.readInt32();
|
||||
let recordType = this.context.GsmPDUHelper.readHexOctet();
|
||||
let number = "";
|
||||
|
||||
// TS 31.102, clause 4.4.2.4 EFEXT1
|
||||
// Case 1, Extension1 record is additional data
|
||||
if (recordType & 0x02) {
|
||||
let numLen = this.context.GsmPDUHelper.readHexOctet();
|
||||
if (numLen != 0xff) {
|
||||
if (numLen > EXT_MAX_BCD_NUMBER_BYTES) {
|
||||
if (DEBUG) {
|
||||
this.context.debug(
|
||||
"Error: invalid length of BCD number/SSC contents - " + numLen);
|
||||
}
|
||||
// +1 to skip Identifier
|
||||
Buf.seekIncoming((EXT_MAX_BCD_NUMBER_BYTES + 1) * Buf.PDU_HEX_OCTET_SIZE);
|
||||
Buf.readStringDelimiter(length);
|
||||
onerror();
|
||||
return;
|
||||
}
|
||||
|
||||
number = this.context.GsmPDUHelper.readSwappedNibbleExtendedBcdString(numLen);
|
||||
if (DEBUG) this.context.debug("Contact Extension Number: "+ number);
|
||||
Buf.seekIncoming((EXT_MAX_BCD_NUMBER_BYTES - numLen) * Buf.PDU_HEX_OCTET_SIZE);
|
||||
} else {
|
||||
Buf.seekIncoming(EXT_MAX_BCD_NUMBER_BYTES * Buf.PDU_HEX_OCTET_SIZE);
|
||||
}
|
||||
} else {
|
||||
// Don't support Case 2, Extension1 record is Called Party Subaddress.
|
||||
// +1 skip numLen
|
||||
Buf.seekIncoming((EXT_MAX_BCD_NUMBER_BYTES + 1) * Buf.PDU_HEX_OCTET_SIZE);
|
||||
}
|
||||
|
||||
// Skip Identifier
|
||||
Buf.seekIncoming(Buf.PDU_HEX_OCTET_SIZE);
|
||||
Buf.readStringDelimiter(length);
|
||||
onsuccess(number);
|
||||
}
|
||||
|
||||
this.context.ICCIOHelper.loadLinearFixedEF({
|
||||
fileId: fileId,
|
||||
recordNumber: recordNumber,
|
||||
callback: callback,
|
||||
onerror: onerror
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -13994,7 +14076,9 @@ ICCContactHelperObject.prototype = {
|
|||
switch (contactType) {
|
||||
case GECKO_CARDCONTACT_TYPE_ADN:
|
||||
if (!this.hasDfPhoneBook(appType)) {
|
||||
ICCRecordHelper.readADNLike(ICC_EF_ADN, onsuccess, onerror);
|
||||
ICCRecordHelper.readADNLike(ICC_EF_ADN,
|
||||
(ICCUtilsHelper.isICCServiceAvailable("EXT1")) ? ICC_EF_EXT1 : null,
|
||||
onsuccess, onerror);
|
||||
} else {
|
||||
this.readUSimContacts(onsuccess, onerror);
|
||||
}
|
||||
|
@ -14004,7 +14088,9 @@ ICCContactHelperObject.prototype = {
|
|||
onerror(CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
|
||||
break;
|
||||
}
|
||||
ICCRecordHelper.readADNLike(ICC_EF_FDN, onsuccess, onerror);
|
||||
ICCRecordHelper.readADNLike(ICC_EF_FDN,
|
||||
(ICCUtilsHelper.isICCServiceAvailable("EXT2")) ? ICC_EF_EXT2 : null,
|
||||
onsuccess, onerror);
|
||||
break;
|
||||
case GECKO_CARDCONTACT_TYPE_SDN:
|
||||
if (!ICCUtilsHelper.isICCServiceAvailable("SDN")) {
|
||||
|
@ -14012,7 +14098,9 @@ ICCContactHelperObject.prototype = {
|
|||
break;
|
||||
}
|
||||
|
||||
ICCRecordHelper.readADNLike(ICC_EF_SDN, onsuccess, onerror);
|
||||
ICCRecordHelper.readADNLike(ICC_EF_SDN,
|
||||
(ICCUtilsHelper.isICCServiceAvailable("EXT3")) ? ICC_EF_EXT3 : null,
|
||||
onsuccess, onerror);
|
||||
break;
|
||||
default:
|
||||
if (DEBUG) {
|
||||
|
@ -14224,11 +14312,13 @@ ICCContactHelperObject.prototype = {
|
|||
* @param onerror Callback to be called when error.
|
||||
*/
|
||||
readPhonebookSet: function(pbr, onsuccess, onerror) {
|
||||
let ICCRecordHelper = this.context.ICCRecordHelper;
|
||||
let gotAdnCb = function gotAdnCb(contacts) {
|
||||
this.readSupportedPBRFields(pbr, contacts, onsuccess, onerror);
|
||||
}.bind(this);
|
||||
|
||||
this.context.ICCRecordHelper.readADNLike(pbr.adn.fileId, gotAdnCb, onerror);
|
||||
ICCRecordHelper.readADNLike(pbr.adn.fileId,
|
||||
(pbr.ext1) ? pbr.ext1.fileId : null, gotAdnCb, onerror);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -494,6 +494,74 @@ add_test(function test_update_iap() {
|
|||
do_test([1, 2]);
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify ICCRecordHelper.readADNLike.
|
||||
*/
|
||||
add_test(function test_read_adn_like() {
|
||||
const RECORD_SIZE = 0x20;
|
||||
|
||||
let worker = newUint8Worker();
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
let helper = context.GsmPDUHelper;
|
||||
let record = context.ICCRecordHelper;
|
||||
let buf = context.Buf;
|
||||
let io = context.ICCIOHelper;
|
||||
let ril = context.RIL;
|
||||
|
||||
function do_test(extFileId, rawEF, expectedExtRecordNumber, expectedNumber) {
|
||||
io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
|
||||
// Write data size
|
||||
buf.writeInt32(rawEF.length * 2);
|
||||
|
||||
// Write adn
|
||||
for (let i = 0; i < rawEF.length; i += 2) {
|
||||
helper.writeHexOctet(parseInt(rawEF.substr(i, 2), 16));
|
||||
}
|
||||
|
||||
// Write string delimiter
|
||||
buf.writeStringDelimiter(rawEF.length * 2);
|
||||
|
||||
options.p1 = 1;
|
||||
options.recordSize = RECORD_SIZE;
|
||||
options.totalRecords = 1;
|
||||
if (options.callback) {
|
||||
options.callback(options);
|
||||
}
|
||||
};
|
||||
|
||||
record.readExtension = function(fileId, recordNumber, onsuccess, onerror) {
|
||||
onsuccess("1234");
|
||||
}
|
||||
|
||||
let successCb = function successCb(contacts) {
|
||||
ok(contacts[0].number == expectedNumber);
|
||||
};
|
||||
|
||||
let errorCb = function errorCb(errorMsg) {
|
||||
do_print("Reading ADNLike failed, msg = " + errorMsg);
|
||||
ok(false);
|
||||
};
|
||||
|
||||
record.readADNLike(ICC_EF_ADN, extFileId, successCb, errorCb);
|
||||
}
|
||||
|
||||
ril.appType = CARD_APPTYPE_SIM;
|
||||
// Valid extension
|
||||
do_test(ICC_EF_EXT1,"436f6e74616374303031ffffffffffffffff0b8199887766554433221100ff01",
|
||||
0x01,"998877665544332211001234");
|
||||
// Empty extension
|
||||
do_test(ICC_EF_EXT1,"436f6e74616374303031ffffffffffffffff0b8199887766554433221100ffff",
|
||||
0xff, "99887766554433221100");
|
||||
// Unsupport extension
|
||||
do_test(null,"436f6e74616374303031ffffffffffffffff0b8199887766554433221100ffff",
|
||||
0xff, "99887766554433221100");
|
||||
// Empty dialling number contact
|
||||
do_test(null,"436f6e74616374303031ffffffffffffffffffffffffffffffffffffffffffff",
|
||||
0xff, null);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify ICCRecordHelper.updateADNLike.
|
||||
*/
|
||||
|
@ -721,3 +789,60 @@ add_test(function test_handling_iccid() {
|
|||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify ICCRecordHelper.readExtension
|
||||
*/
|
||||
add_test(function test_read_extension() {
|
||||
let worker = newUint8Worker();
|
||||
let context = worker.ContextPool._contexts[0];
|
||||
let helper = context.GsmPDUHelper;
|
||||
let record = context.ICCRecordHelper;
|
||||
let buf = context.Buf;
|
||||
let io = context.ICCIOHelper;
|
||||
|
||||
function do_test(rawExtension, expectedExtensionNumber) {
|
||||
io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
|
||||
// Write data size
|
||||
buf.writeInt32(rawExtension.length * 2);
|
||||
|
||||
// Write ext
|
||||
for (let i = 0; i < rawExtension.length; i += 2) {
|
||||
helper.writeHexOctet(parseInt(rawExtension.substr(i, 2), 16));
|
||||
}
|
||||
|
||||
// Write string delimiter
|
||||
buf.writeStringDelimiter(rawExtension.length);
|
||||
|
||||
if (options.callback) {
|
||||
options.callback(options);
|
||||
}
|
||||
};
|
||||
|
||||
let successCb = function successCb(number) {
|
||||
do_print("extension number:" + number);
|
||||
equal(number, expectedExtensionNumber);
|
||||
};
|
||||
|
||||
let errorCb = function errorCb() {
|
||||
ok(expectedExtensionNumber == null);
|
||||
};
|
||||
|
||||
record.readExtension(0x6f4a, 1, successCb, errorCb);
|
||||
}
|
||||
|
||||
// Test unsupported record type 0x01
|
||||
do_test("010a10325476981032547698ff", "");
|
||||
// Test invalid length 0xc1
|
||||
do_test("020c10325476981032547698ff", null);
|
||||
// Test extension chain which we don't support
|
||||
do_test("020a1032547698103254769802", "01234567890123456789");
|
||||
// Test valid Extension
|
||||
do_test("020a10325476981032547698ff", "01234567890123456789");
|
||||
// Test valid Extension
|
||||
do_test("0209103254769810325476ffff", "012345678901234567");
|
||||
// Test empty Extension
|
||||
do_test("02ffffffffffffffffffffffff", "");
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче