Bug 824611 - Part 1: Add ICC PDU Helper. r=yoshi

This commit is contained in:
Georgia Wang 2013-11-11 14:28:20 +08:00
Родитель 7ba509dc4d
Коммит a7e8a7d504
1 изменённых файлов: 421 добавлений и 416 удалений

Просмотреть файл

@ -2857,7 +2857,7 @@ let RIL = {
ComprehensionTlvHelper.writeLength(
Math.ceil(options.address.length/2) + 1 // address BCD + TON
);
GsmPDUHelper.writeDiallingNumber(options.address);
ICCPDUHelper.writeDiallingNumber(options.address);
}
// Cause of disconnection.
@ -6684,96 +6684,6 @@ let GsmPDUHelper = {
}
},
/**
* Read GSM 8-bit unpacked octets,
* which are SMS default 7-bit alphabets with bit 8 set to 0.
*
* @param numOctets
* Number of octets to be read.
*/
read8BitUnpackedToString: function read8BitUnpackedToString(numOctets) {
let ret = "";
let escapeFound = false;
let i;
const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
for(i = 0; i < numOctets; i++) {
let octet = this.readHexOctet();
if (octet == 0xff) {
i++;
break;
}
if (escapeFound) {
escapeFound = false;
if (octet == PDU_NL_EXTENDED_ESCAPE) {
// According to 3GPP TS 23.038, section 6.2.1.1, NOTE 1, "On
// receipt of this code, a receiving entity shall display a space
// until another extensiion table is defined."
ret += " ";
} else if (octet == PDU_NL_RESERVED_CONTROL) {
// According to 3GPP TS 23.038 B.2, "This code represents a control
// character and therefore must not be used for language specific
// characters."
ret += " ";
} else {
ret += langShiftTable[octet];
}
} else if (octet == PDU_NL_EXTENDED_ESCAPE) {
escapeFound = true;
} else {
ret += langTable[octet];
}
}
Buf.seekIncoming((numOctets - i) * Buf.PDU_HEX_OCTET_SIZE);
return ret;
},
/**
* Write GSM 8-bit unpacked octets.
*
* @param numOctets Number of total octets to be writen, including trailing
* 0xff.
* @param str String to be written. Could be null.
*/
writeStringTo8BitUnpacked: function writeStringTo8BitUnpacked(numOctets, str) {
const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
// If the character is GSM extended alphabet, two octets will be written.
// So we need to keep track of number of octets to be written.
let i, j;
let len = str ? str.length : 0;
for (i = 0, j = 0; i < len && j < numOctets; i++) {
let c = str.charAt(i);
let octet = langTable.indexOf(c);
if (octet == -1) {
// Make sure we still have enough space to write two octets.
if (j + 2 > numOctets) {
break;
}
octet = langShiftTable.indexOf(c);
if (octet == -1) {
// Fallback to ASCII space.
octet = langTable.indexOf(' ');
}
this.writeHexOctet(PDU_NL_EXTENDED_ESCAPE);
j++;
}
this.writeHexOctet(octet);
j++;
}
// trailing 0xff
while (j++ < numOctets) {
this.writeHexOctet(0xff);
}
},
/**
* Read user data and decode as a UCS2 string.
*
@ -6809,103 +6719,6 @@ let GsmPDUHelper = {
}
},
/**
* Read UCS2 String on UICC.
*
* @see TS 101.221, Annex A.
* @param scheme
* Coding scheme for UCS2 on UICC. One of 0x80, 0x81 or 0x82.
* @param numOctets
* Number of octets to be read as UCS2 string.
*/
readICCUCS2String: function readICCUCS2String(scheme, numOctets) {
let str = "";
switch (scheme) {
/**
* +------+---------+---------+---------+---------+------+------+
* | 0x80 | Ch1_msb | Ch1_lsb | Ch2_msb | Ch2_lsb | 0xff | 0xff |
* +------+---------+---------+---------+---------+------+------+
*/
case 0x80:
let isOdd = numOctets % 2;
let i;
for (i = 0; i < numOctets - isOdd; i += 2) {
let code = (this.readHexOctet() << 8) | this.readHexOctet();
if (code == 0xffff) {
i += 2;
break;
}
str += String.fromCharCode(code);
}
// Skip trailing 0xff
Buf.seekIncoming((numOctets - i) * Buf.PDU_HEX_OCTET_SIZE);
break;
case 0x81: // Fall through
case 0x82:
/**
* +------+-----+--------+-----+-----+-----+--------+------+
* | 0x81 | len | offset | Ch1 | Ch2 | ... | Ch_len | 0xff |
* +------+-----+--------+-----+-----+-----+--------+------+
*
* len : The length of characters.
* offset : 0hhh hhhh h000 0000
* Ch_n: bit 8 = 0
* GSM default alphabets
* bit 8 = 1
* UCS2 character whose char code is (Ch_n & 0x7f) + offset
*
* +------+-----+------------+------------+-----+-----+-----+--------+
* | 0x82 | len | offset_msb | offset_lsb | Ch1 | Ch2 | ... | Ch_len |
* +------+-----+------------+------------+-----+-----+-----+--------+
*
* len : The length of characters.
* offset_msb, offset_lsn: offset
* Ch_n: bit 8 = 0
* GSM default alphabets
* bit 8 = 1
* UCS2 character whose char code is (Ch_n & 0x7f) + offset
*/
let len = this.readHexOctet();
let offset, headerLen;
if (scheme == 0x81) {
offset = this.readHexOctet() << 7;
headerLen = 2;
} else {
offset = (this.readHexOctet() << 8) | this.readHexOctet();
headerLen = 3;
}
for (let i = 0; i < len; i++) {
let ch = this.readHexOctet();
if (ch & 0x80) {
// UCS2
str += String.fromCharCode((ch & 0x7f) + offset);
} else {
// GSM 8bit
let count = 0, gotUCS2 = 0;
while ((i + count + 1 < len)) {
count++;
if (this.readHexOctet() & 0x80) {
gotUCS2 = 1;
break;
}
}
// Unread.
// +1 for the GSM alphabet indexed at i,
Buf.seekIncoming(-1 * (count + 1) * Buf.PDU_HEX_OCTET_SIZE);
str += this.read8BitUnpackedToString(count + 1 - gotUCS2);
i += count - gotUCS2;
}
}
// Skipping trailing 0xff
Buf.seekIncoming((numOctets - len - headerLen) * Buf.PDU_HEX_OCTET_SIZE);
break;
}
return str;
},
/**
* Read 1 + UDHL octets and construct user data header.
*
@ -7156,219 +6969,6 @@ let GsmPDUHelper = {
return addr;
},
/**
* Read Alpha Id and Dialling number from TS TS 151.011 clause 10.5.1
*
* @param recordSize The size of linear fixed record.
*/
readAlphaIdDiallingNumber: function readAlphaIdDiallingNumber(recordSize) {
let length = Buf.readInt32();
let alphaLen = recordSize - ADN_FOOTER_SIZE_BYTES;
let alphaId = this.readAlphaIdentifier(alphaLen);
let number = this.readNumberWithLength();
// Skip 2 unused octets, CCP and EXT1.
Buf.seekIncoming(2 * Buf.PDU_HEX_OCTET_SIZE);
Buf.readStringDelimiter(length);
let contact = null;
if (alphaId || number) {
contact = {alphaId: alphaId,
number: number};
}
return contact;
},
/**
* Write Alpha Identifier and Dialling number from TS 151.011 clause 10.5.1
*
* @param recordSize The size of linear fixed record.
* @param alphaId Alpha Identifier to be written.
* @param number Dialling Number to be written.
*/
writeAlphaIdDiallingNumber: function writeAlphaIdDiallingNumber(recordSize,
alphaId,
number) {
// Write String length
let strLen = recordSize * 2;
Buf.writeInt32(strLen);
let alphaLen = recordSize - ADN_FOOTER_SIZE_BYTES;
this.writeAlphaIdentifier(alphaLen, alphaId);
this.writeNumberWithLength(number);
// Write unused octets 0xff, CCP and EXT1.
this.writeHexOctet(0xff);
this.writeHexOctet(0xff);
Buf.writeStringDelimiter(strLen);
},
/**
* Read Alpha Identifier.
*
* @see TS 131.102
*
* @param numOctets
* Number of octets to be read.
*
* It uses either
* 1. SMS default 7-bit alphabet with bit 8 set to 0.
* 2. UCS2 string.
*
* Unused bytes should be set to 0xff.
*/
readAlphaIdentifier: function readAlphaIdentifier(numOctets) {
if (numOctets === 0) {
return "";
}
let temp;
// Read the 1st octet to determine the encoding.
if ((temp = GsmPDUHelper.readHexOctet()) == 0x80 ||
temp == 0x81 ||
temp == 0x82) {
numOctets--;
return this.readICCUCS2String(temp, numOctets);
} else {
Buf.seekIncoming(-1 * Buf.PDU_HEX_OCTET_SIZE);
return this.read8BitUnpackedToString(numOctets);
}
},
/**
* Write Alpha Identifier.
*
* @param numOctets
* Total number of octets to be written. This includes the length of
* alphaId and the length of trailing unused octets(0xff).
* @param alphaId
* Alpha Identifier to be written.
*
* Unused octets will be written as 0xff.
*/
writeAlphaIdentifier: function writeAlphaIdentifier(numOctets, alphaId) {
if (numOctets === 0) {
return;
}
// If alphaId is empty or it's of GSM 8 bit.
if (!alphaId || ICCUtilsHelper.isGsm8BitAlphabet(alphaId)) {
this.writeStringTo8BitUnpacked(numOctets, alphaId);
} else {
// Currently only support UCS2 coding scheme 0x80.
this.writeHexOctet(0x80);
numOctets--;
// Now the alphaId is UCS2 string, each character will take 2 octets.
if (alphaId.length * 2 > numOctets) {
alphaId = alphaId.substring(0, Math.floor(numOctets / 2));
}
this.writeUCS2String(alphaId);
for (let i = alphaId.length * 2; i < numOctets; i++) {
this.writeHexOctet(0xff);
}
}
},
/**
* Read Dialling number.
*
* @see TS 131.102
*
* @param len
* The Length of BCD number.
*
* From TS 131.102, in EF_ADN, EF_FDN, the field 'Length of BCD number'
* means the total bytes should be allocated to store the TON/NPI and
* the dialing number.
* For example, if the dialing number is 1234567890,
* and the TON/NPI is 0x81,
* The field 'Length of BCD number' should be 06, which is
* 1 byte to store the TON/NPI, 0x81
* 5 bytes to store the BCD number 2143658709.
*
* Here the definition of the length is different from SMS spec,
* TS 23.040 9.1.2.5, which the length means
* "number of useful semi-octets within the Address-Value field".
*/
readDiallingNumber: function readDiallingNumber(len) {
if (DEBUG) debug("PDU: Going to read Dialling number: " + len);
if (len === 0) {
return "";
}
// TOA = TON + NPI
let toa = this.readHexOctet();
let number = this.readSwappedNibbleBcdString(len - 1);
if (number.length <= 0) {
if (DEBUG) debug("No number provided");
return "";
}
if ((toa >> 4) == (PDU_TOA_INTERNATIONAL >> 4)) {
number = '+' + number;
}
return number;
},
/**
* Write Dialling Number.
*
* @param number The Dialling number
*/
writeDiallingNumber: function writeDiallingNumber(number) {
let toa = PDU_TOA_ISDN; // 81
if (number[0] == '+') {
toa = PDU_TOA_INTERNATIONAL | PDU_TOA_ISDN; // 91
number = number.substring(1);
}
this.writeHexOctet(toa);
this.writeSwappedNibbleBCD(number);
},
readNumberWithLength: function readNumberWithLength() {
let number;
let numLen = this.readHexOctet();
if (numLen != 0xff) {
if (numLen > ADN_MAX_BCD_NUMBER_BYTES) {
throw new Error("invalid length of BCD number/SSC contents - " + numLen);
}
number = this.readDiallingNumber(numLen);
Buf.seekIncoming((ADN_MAX_BCD_NUMBER_BYTES - numLen) * Buf.PDU_HEX_OCTET_SIZE);
} else {
Buf.seekIncoming(ADN_MAX_BCD_NUMBER_BYTES * Buf.PDU_HEX_OCTET_SIZE);
}
return number;
},
writeNumberWithLength: function writeNumberWithLength(number) {
if (number) {
let numStart = number[0] == "+" ? 1 : 0;
let numDigits = number.length - numStart;
if (numDigits > ADN_MAX_NUMBER_DIGITS) {
number = number.substring(0, ADN_MAX_NUMBER_DIGITS + numStart);
numDigits = number.length - numStart;
}
// +1 for TON/NPI
let numLen = Math.ceil(numDigits / 2) + 1;
this.writeHexOctet(numLen);
this.writeDiallingNumber(number);
// Write trailing 0xff of Dialling Number.
for (let i = 0; i < ADN_MAX_BCD_NUMBER_BYTES - numLen; i++) {
this.writeHexOctet(0xff);
}
} else {
// +1 for numLen
for (let i = 0; i < ADN_MAX_BCD_NUMBER_BYTES + 1; i++) {
this.writeHexOctet(0xff);
}
}
},
/**
* Read TP-Protocol-Indicator(TP-PID).
*
@ -9590,6 +9190,411 @@ let CdmaPDUHelper = {
}
};
/**
* Helper for processing ICC PDUs.
*/
let ICCPDUHelper = {
/**
* Read GSM 8-bit unpacked octets,
* which are default 7-bit alphabets with bit 8 set to 0.
*
* @param numOctets
* Number of octets to be read.
*/
read8BitUnpackedToString: function read8BitUnpackedToString(numOctets) {
let ret = "";
let escapeFound = false;
let i;
const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
for(i = 0; i < numOctets; i++) {
let octet = GsmPDUHelper.readHexOctet();
if (octet == 0xff) {
i++;
break;
}
if (escapeFound) {
escapeFound = false;
if (octet == PDU_NL_EXTENDED_ESCAPE) {
// According to 3GPP TS 23.038, section 6.2.1.1, NOTE 1, "On
// receipt of this code, a receiving entity shall display a space
// until another extensiion table is defined."
ret += " ";
} else if (octet == PDU_NL_RESERVED_CONTROL) {
// According to 3GPP TS 23.038 B.2, "This code represents a control
// character and therefore must not be used for language specific
// characters."
ret += " ";
} else {
ret += langShiftTable[octet];
}
} else if (octet == PDU_NL_EXTENDED_ESCAPE) {
escapeFound = true;
} else {
ret += langTable[octet];
}
}
Buf.seekIncoming((numOctets - i) * Buf.PDU_HEX_OCTET_SIZE);
return ret;
},
/**
* Write GSM 8-bit unpacked octets.
*
* @param numOctets Number of total octets to be writen, including trailing
* 0xff.
* @param str String to be written. Could be null.
*/
writeStringTo8BitUnpacked: function writeStringTo8BitUnpacked(numOctets, str) {
const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
// If the character is GSM extended alphabet, two octets will be written.
// So we need to keep track of number of octets to be written.
let i, j;
let len = str ? str.length : 0;
for (i = 0, j = 0; i < len && j < numOctets; i++) {
let c = str.charAt(i);
let octet = langTable.indexOf(c);
if (octet == -1) {
// Make sure we still have enough space to write two octets.
if (j + 2 > numOctets) {
break;
}
octet = langShiftTable.indexOf(c);
if (octet == -1) {
// Fallback to ASCII space.
octet = langTable.indexOf(' ');
}
GsmPDUHelper.writeHexOctet(PDU_NL_EXTENDED_ESCAPE);
j++;
}
GsmPDUHelper.writeHexOctet(octet);
j++;
}
// trailing 0xff
while (j++ < numOctets) {
GsmPDUHelper.writeHexOctet(0xff);
}
},
/**
* Read UCS2 String on UICC.
*
* @see TS 101.221, Annex A.
* @param scheme
* Coding scheme for UCS2 on UICC. One of 0x80, 0x81 or 0x82.
* @param numOctets
* Number of octets to be read as UCS2 string.
*/
readICCUCS2String: function readICCUCS2String(scheme, numOctets) {
let str = "";
switch (scheme) {
/**
* +------+---------+---------+---------+---------+------+------+
* | 0x80 | Ch1_msb | Ch1_lsb | Ch2_msb | Ch2_lsb | 0xff | 0xff |
* +------+---------+---------+---------+---------+------+------+
*/
case 0x80:
let isOdd = numOctets % 2;
let i;
for (i = 0; i < numOctets - isOdd; i += 2) {
let code = (GsmPDUHelper.readHexOctet() << 8) | GsmPDUHelper.readHexOctet();
if (code == 0xffff) {
i += 2;
break;
}
str += String.fromCharCode(code);
}
// Skip trailing 0xff
Buf.seekIncoming((numOctets - i) * Buf.PDU_HEX_OCTET_SIZE);
break;
case 0x81: // Fall through
case 0x82:
/**
* +------+-----+--------+-----+-----+-----+--------+------+
* | 0x81 | len | offset | Ch1 | Ch2 | ... | Ch_len | 0xff |
* +------+-----+--------+-----+-----+-----+--------+------+
*
* len : The length of characters.
* offset : 0hhh hhhh h000 0000
* Ch_n: bit 8 = 0
* GSM default alphabets
* bit 8 = 1
* UCS2 character whose char code is (Ch_n & 0x7f) + offset
*
* +------+-----+------------+------------+-----+-----+-----+--------+
* | 0x82 | len | offset_msb | offset_lsb | Ch1 | Ch2 | ... | Ch_len |
* +------+-----+------------+------------+-----+-----+-----+--------+
*
* len : The length of characters.
* offset_msb, offset_lsn: offset
* Ch_n: bit 8 = 0
* GSM default alphabets
* bit 8 = 1
* UCS2 character whose char code is (Ch_n & 0x7f) + offset
*/
let len = GsmPDUHelper.readHexOctet();
let offset, headerLen;
if (scheme == 0x81) {
offset = GsmPDUHelper.readHexOctet() << 7;
headerLen = 2;
} else {
offset = (GsmPDUHelper.readHexOctet() << 8) | GsmPDUHelper.readHexOctet();
headerLen = 3;
}
for (let i = 0; i < len; i++) {
let ch = GsmPDUHelper.readHexOctet();
if (ch & 0x80) {
// UCS2
str += String.fromCharCode((ch & 0x7f) + offset);
} else {
// GSM 8bit
let count = 0, gotUCS2 = 0;
while ((i + count + 1 < len)) {
count++;
if (GsmPDUHelper.readHexOctet() & 0x80) {
gotUCS2 = 1;
break;
}
}
// Unread.
// +1 for the GSM alphabet indexed at i,
Buf.seekIncoming(-1 * (count + 1) * Buf.PDU_HEX_OCTET_SIZE);
str += this.read8BitUnpackedToString(count + 1 - gotUCS2);
i += count - gotUCS2;
}
}
// Skipping trailing 0xff
Buf.seekIncoming((numOctets - len - headerLen) * Buf.PDU_HEX_OCTET_SIZE);
break;
}
return str;
},
/**
* Read Alpha Id and Dialling number from TS TS 151.011 clause 10.5.1
*
* @param recordSize The size of linear fixed record.
*/
readAlphaIdDiallingNumber: function readAlphaIdDiallingNumber(recordSize) {
let length = Buf.readInt32();
let alphaLen = recordSize - ADN_FOOTER_SIZE_BYTES;
let alphaId = this.readAlphaIdentifier(alphaLen);
let number = this.readNumberWithLength();
// Skip 2 unused octets, CCP and EXT1.
Buf.seekIncoming(2 * Buf.PDU_HEX_OCTET_SIZE);
Buf.readStringDelimiter(length);
let contact = null;
if (alphaId || number) {
contact = {alphaId: alphaId,
number: number};
}
return contact;
},
/**
* Write Alpha Identifier and Dialling number from TS 151.011 clause 10.5.1
*
* @param recordSize The size of linear fixed record.
* @param alphaId Alpha Identifier to be written.
* @param number Dialling Number to be written.
*/
writeAlphaIdDiallingNumber: function writeAlphaIdDiallingNumber(recordSize,
alphaId,
number) {
// Write String length
let strLen = recordSize * 2;
Buf.writeInt32(strLen);
let alphaLen = recordSize - ADN_FOOTER_SIZE_BYTES;
this.writeAlphaIdentifier(alphaLen, alphaId);
this.writeNumberWithLength(number);
// Write unused octets 0xff, CCP and EXT1.
GsmPDUHelper.writeHexOctet(0xff);
GsmPDUHelper.writeHexOctet(0xff);
Buf.writeStringDelimiter(strLen);
},
/**
* Read Alpha Identifier.
*
* @see TS 131.102
*
* @param numOctets
* Number of octets to be read.
*
* It uses either
* 1. SMS default 7-bit alphabet with bit 8 set to 0.
* 2. UCS2 string.
*
* Unused bytes should be set to 0xff.
*/
readAlphaIdentifier: function readAlphaIdentifier(numOctets) {
if (numOctets === 0) {
return "";
}
let temp;
// Read the 1st octet to determine the encoding.
if ((temp = GsmPDUHelper.readHexOctet()) == 0x80 ||
temp == 0x81 ||
temp == 0x82) {
numOctets--;
return this.readICCUCS2String(temp, numOctets);
} else {
Buf.seekIncoming(-1 * Buf.PDU_HEX_OCTET_SIZE);
return this.read8BitUnpackedToString(numOctets);
}
},
/**
* Write Alpha Identifier.
*
* @param numOctets
* Total number of octets to be written. This includes the length of
* alphaId and the length of trailing unused octets(0xff).
* @param alphaId
* Alpha Identifier to be written.
*
* Unused octets will be written as 0xff.
*/
writeAlphaIdentifier: function writeAlphaIdentifier(numOctets, alphaId) {
if (numOctets === 0) {
return;
}
// If alphaId is empty or it's of GSM 8 bit.
if (!alphaId || ICCUtilsHelper.isGsm8BitAlphabet(alphaId)) {
this.writeStringTo8BitUnpacked(numOctets, alphaId);
} else {
// Currently only support UCS2 coding scheme 0x80.
GsmPDUHelper.writeHexOctet(0x80);
numOctets--;
// Now the alphaId is UCS2 string, each character will take 2 octets.
if (alphaId.length * 2 > numOctets) {
alphaId = alphaId.substring(0, Math.floor(numOctets / 2));
}
GsmPDUHelper.writeUCS2String(alphaId);
for (let i = alphaId.length * 2; i < numOctets; i++) {
GsmPDUHelper.writeHexOctet(0xff);
}
}
},
/**
* Read Dialling number.
*
* @see TS 131.102
*
* @param len
* The Length of BCD number.
*
* From TS 131.102, in EF_ADN, EF_FDN, the field 'Length of BCD number'
* means the total bytes should be allocated to store the TON/NPI and
* the dialing number.
* For example, if the dialing number is 1234567890,
* and the TON/NPI is 0x81,
* The field 'Length of BCD number' should be 06, which is
* 1 byte to store the TON/NPI, 0x81
* 5 bytes to store the BCD number 2143658709.
*
* Here the definition of the length is different from SMS spec,
* TS 23.040 9.1.2.5, which the length means
* "number of useful semi-octets within the Address-Value field".
*/
readDiallingNumber: function readDiallingNumber(len) {
if (DEBUG) debug("PDU: Going to read Dialling number: " + len);
if (len === 0) {
return "";
}
// TOA = TON + NPI
let toa = GsmPDUHelper.readHexOctet();
let number = GsmPDUHelper.readSwappedNibbleBcdString(len - 1);
if (number.length <= 0) {
if (DEBUG) debug("No number provided");
return "";
}
if ((toa >> 4) == (PDU_TOA_INTERNATIONAL >> 4)) {
number = '+' + number;
}
return number;
},
/**
* Write Dialling Number.
*
* @param number The Dialling number
*/
writeDiallingNumber: function writeDiallingNumber(number) {
let toa = PDU_TOA_ISDN; // 81
if (number[0] == '+') {
toa = PDU_TOA_INTERNATIONAL | PDU_TOA_ISDN; // 91
number = number.substring(1);
}
GsmPDUHelper.writeHexOctet(toa);
GsmPDUHelper.writeSwappedNibbleBCD(number);
},
readNumberWithLength: function readNumberWithLength() {
let number;
let numLen = GsmPDUHelper.readHexOctet();
if (numLen != 0xff) {
if (numLen > ADN_MAX_BCD_NUMBER_BYTES) {
throw new Error("invalid length of BCD number/SSC contents - " + numLen);
}
number = this.readDiallingNumber(numLen);
Buf.seekIncoming((ADN_MAX_BCD_NUMBER_BYTES - numLen) * Buf.PDU_HEX_OCTET_SIZE);
} else {
Buf.seekIncoming(ADN_MAX_BCD_NUMBER_BYTES * Buf.PDU_HEX_OCTET_SIZE);
}
return number;
},
writeNumberWithLength: function writeNumberWithLength(number) {
if (number) {
let numStart = number[0] == "+" ? 1 : 0;
let numDigits = number.length - numStart;
if (numDigits > ADN_MAX_NUMBER_DIGITS) {
number = number.substring(0, ADN_MAX_NUMBER_DIGITS + numStart);
numDigits = number.length - numStart;
}
// +1 for TON/NPI
let numLen = Math.ceil(numDigits / 2) + 1;
GsmPDUHelper.writeHexOctet(numLen);
this.writeDiallingNumber(number);
// Write trailing 0xff of Dialling Number.
for (let i = 0; i < ADN_MAX_BCD_NUMBER_BYTES - numLen; i++) {
GsmPDUHelper.writeHexOctet(0xff);
}
} else {
// +1 for numLen
for (let i = 0; i < ADN_MAX_BCD_NUMBER_BYTES + 1; i++) {
GsmPDUHelper.writeHexOctet(0xff);
}
}
}
};
let StkCommandParamsFactory = {
createParam: function createParam(cmdDetails, ctlvs) {
let method = StkCommandParamsFactory[cmdDetails.typeOfCommand];
@ -10157,7 +10162,7 @@ let StkProactiveCmdHelper = {
*/
retrieveAlphaId: function retrieveAlphaId(length) {
let alphaId = {
identifier: GsmPDUHelper.readAlphaIdentifier(length)
identifier: ICCPDUHelper.readAlphaIdentifier(length)
};
return alphaId;
},
@ -10191,7 +10196,7 @@ let StkProactiveCmdHelper = {
*/
retrieveAddress: function retrieveAddress(length) {
let address = {
number : GsmPDUHelper.readDiallingNumber(length)
number : ICCPDUHelper.readDiallingNumber(length)
};
return address;
},
@ -10222,7 +10227,7 @@ let StkProactiveCmdHelper = {
text.textString = GsmPDUHelper.readSeptetsToString(length * 8 / 7, 0, 0, 0);
break;
case STK_TEXT_CODING_GSM_8BIT:
text.textString = GsmPDUHelper.read8BitUnpackedToString(length);
text.textString = ICCPDUHelper.read8BitUnpackedToString(length);
break;
case STK_TEXT_CODING_UCS2:
text.textString = GsmPDUHelper.readUCS2String(length);
@ -10266,7 +10271,7 @@ let StkProactiveCmdHelper = {
}
let item = {
identifier: GsmPDUHelper.readHexOctet(),
text: GsmPDUHelper.readAlphaIdentifier(length - 1)
text: ICCPDUHelper.readAlphaIdentifier(length - 1)
};
return item;
},
@ -11246,7 +11251,7 @@ let ICCRecordHelper = {
*/
readMSISDN: function readMSISDN() {
function callback(options) {
let contact = GsmPDUHelper.readAlphaIdDiallingNumber(options.recordSize);
let contact = ICCPDUHelper.readAlphaIdDiallingNumber(options.recordSize);
if (!contact ||
(RIL.iccInfo.msisdn !== undefined &&
RIL.iccInfo.msisdn === contact.number)) {
@ -11304,7 +11309,7 @@ let ICCRecordHelper = {
let octetLen = strLen / 2;
let spnDisplayCondition = GsmPDUHelper.readHexOctet();
// Minus 1 because the first octet is used to store display condition.
let spn = GsmPDUHelper.readAlphaIdentifier(octetLen - 1);
let spn = ICCPDUHelper.readAlphaIdentifier(octetLen - 1);
Buf.readStringDelimiter(strLen);
if (DEBUG) {
@ -11416,7 +11421,7 @@ let ICCRecordHelper = {
*/
readADNLike: function readADNLike(fileId, onsuccess, onerror) {
function callback(options) {
let contact = GsmPDUHelper.readAlphaIdDiallingNumber(options.recordSize);
let contact = ICCPDUHelper.readAlphaIdDiallingNumber(options.recordSize);
if (contact) {
contact.recordId = options.p1;
contacts.push(contact);
@ -11453,7 +11458,7 @@ let ICCRecordHelper = {
*/
updateADNLike: function updateADNLike(fileId, contact, pin2, onsuccess, onerror) {
function dataWriter(recordSize) {
GsmPDUHelper.writeAlphaIdDiallingNumber(recordSize,
ICCPDUHelper.writeAlphaIdDiallingNumber(recordSize,
contact.alphaId,
contact.number);
}
@ -11485,7 +11490,7 @@ let ICCRecordHelper = {
*/
readMBDN: function readMBDN() {
function callback(options) {
let contact = GsmPDUHelper.readAlphaIdDiallingNumber(options.recordSize);
let contact = ICCPDUHelper.readAlphaIdDiallingNumber(options.recordSize);
if (!contact ||
(RIL.iccInfoPrivate.mbdn !== undefined &&
RIL.iccInfoPrivate.mbdn === contact.number)) {
@ -11658,9 +11663,9 @@ let ICCRecordHelper = {
// Note: The fields marked as C above are mandatort if the file
// is not type 1 (as specified in EF_PBR)
if (fileType == ICC_USIM_TYPE1_TAG) {
email = GsmPDUHelper.read8BitUnpackedToString(octetLen);
email = ICCPDUHelper.read8BitUnpackedToString(octetLen);
} else {
email = GsmPDUHelper.read8BitUnpackedToString(octetLen - 2);
email = ICCPDUHelper.read8BitUnpackedToString(octetLen - 2);
// Consumes the remaining buffer
Buf.seekIncoming(2 * Buf.PDU_HEX_OCTET_SIZE); // For ADN SFI and Record Identifier
@ -11701,9 +11706,9 @@ let ICCRecordHelper = {
Buf.writeInt32(strLen);
if (fileType == ICC_USIM_TYPE1_TAG) {
GsmPDUHelper.writeStringTo8BitUnpacked(recordSize, email);
ICCPDUHelper.writeStringTo8BitUnpacked(recordSize, email);
} else {
GsmPDUHelper.writeStringTo8BitUnpacked(recordSize - 2, email);
ICCPDUHelper.writeStringTo8BitUnpacked(recordSize - 2, email);
GsmPDUHelper.writeHexOctet(pbr.adn.sfi || 0xff);
GsmPDUHelper.writeHexOctet(adnRecordId);
}
@ -11743,7 +11748,7 @@ let ICCRecordHelper = {
// Skip EF_AAS Record ID.
Buf.seekIncoming(1 * Buf.PDU_HEX_OCTET_SIZE);
number = GsmPDUHelper.readNumberWithLength();
number = ICCPDUHelper.readNumberWithLength();
// Skip 2 unused octets, CCP and EXT1.
Buf.seekIncoming(2 * Buf.PDU_HEX_OCTET_SIZE);
@ -11790,7 +11795,7 @@ let ICCRecordHelper = {
// EF_AAS record Id. Unused for now.
GsmPDUHelper.writeHexOctet(0xff);
GsmPDUHelper.writeNumberWithLength(number);
ICCPDUHelper.writeNumberWithLength(number);
// Write unused octets 0xff, CCP and EXT1.
GsmPDUHelper.writeHexOctet(0xff);