dom/system/gonk/tests/test_ril_worker_icc.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* Any copyright is dedicated to the Public Domain.
michael@0 2 http://creativecommons.org/publicdomain/zero/1.0/ */
michael@0 3
michael@0 4 subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
michael@0 5
michael@0 6 function run_test() {
michael@0 7 run_next_test();
michael@0 8 }
michael@0 9
michael@0 10 /**
michael@0 11 * Helper function.
michael@0 12 */
michael@0 13 function newUint8Worker() {
michael@0 14 let worker = newWorker();
michael@0 15 let index = 0; // index for read
michael@0 16 let buf = [];
michael@0 17
michael@0 18 let context = worker.ContextPool._contexts[0];
michael@0 19 context.Buf.writeUint8 = function(value) {
michael@0 20 buf.push(value);
michael@0 21 };
michael@0 22
michael@0 23 context.Buf.readUint8 = function() {
michael@0 24 return buf[index++];
michael@0 25 };
michael@0 26
michael@0 27 context.Buf.seekIncoming = function(offset) {
michael@0 28 index += offset;
michael@0 29 };
michael@0 30
michael@0 31 context.Buf.getReadAvailable = function() {
michael@0 32 return buf.length - index;
michael@0 33 };
michael@0 34
michael@0 35 worker.debug = do_print;
michael@0 36
michael@0 37 return worker;
michael@0 38 }
michael@0 39
michael@0 40 /**
michael@0 41 * Verify ICCPDUHelper#readICCUCS2String()
michael@0 42 */
michael@0 43 add_test(function test_read_icc_ucs2_string() {
michael@0 44 let worker = newUint8Worker();
michael@0 45 let context = worker.ContextPool._contexts[0];
michael@0 46 let helper = context.GsmPDUHelper;
michael@0 47 let iccHelper = context.ICCPDUHelper;
michael@0 48
michael@0 49 // 0x80
michael@0 50 let text = "TEST";
michael@0 51 helper.writeUCS2String(text);
michael@0 52 // Also write two unused octets.
michael@0 53 let ffLen = 2;
michael@0 54 for (let i = 0; i < ffLen; i++) {
michael@0 55 helper.writeHexOctet(0xff);
michael@0 56 }
michael@0 57 do_check_eq(iccHelper.readICCUCS2String(0x80, (2 * text.length) + ffLen), text);
michael@0 58
michael@0 59 // 0x81
michael@0 60 let array = [0x08, 0xd2, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca,
michael@0 61 0xff, 0xff];
michael@0 62 let len = array.length;
michael@0 63 for (let i = 0; i < len; i++) {
michael@0 64 helper.writeHexOctet(array[i]);
michael@0 65 }
michael@0 66 do_check_eq(iccHelper.readICCUCS2String(0x81, len), "Mozilla\u694a");
michael@0 67
michael@0 68 // 0x82
michael@0 69 let array2 = [0x08, 0x69, 0x00, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61,
michael@0 70 0xca, 0xff, 0xff];
michael@0 71 let len2 = array2.length;
michael@0 72 for (let i = 0; i < len2; i++) {
michael@0 73 helper.writeHexOctet(array2[i]);
michael@0 74 }
michael@0 75 do_check_eq(iccHelper.readICCUCS2String(0x82, len2), "Mozilla\u694a");
michael@0 76
michael@0 77 run_next_test();
michael@0 78 });
michael@0 79
michael@0 80 /**
michael@0 81 * Verify ICCPDUHelper#readDiallingNumber
michael@0 82 */
michael@0 83 add_test(function test_read_dialling_number() {
michael@0 84 let worker = newUint8Worker();
michael@0 85 let context = worker.ContextPool._contexts[0];
michael@0 86 let helper = context.GsmPDUHelper;
michael@0 87 let iccHelper = context.ICCPDUHelper;
michael@0 88 let str = "123456789";
michael@0 89
michael@0 90 helper.readHexOctet = function() {
michael@0 91 return 0x81;
michael@0 92 };
michael@0 93
michael@0 94 helper.readSwappedNibbleBcdString = function(len) {
michael@0 95 return str.substring(0, len);
michael@0 96 };
michael@0 97
michael@0 98 for (let i = 0; i < str.length; i++) {
michael@0 99 do_check_eq(str.substring(0, i - 1), // -1 for the TON
michael@0 100 iccHelper.readDiallingNumber(i));
michael@0 101 }
michael@0 102
michael@0 103 run_next_test();
michael@0 104 });
michael@0 105
michael@0 106 /**
michael@0 107 * Verify ICCPDUHelper#read8BitUnpackedToString
michael@0 108 */
michael@0 109 add_test(function test_read_8bit_unpacked_to_string() {
michael@0 110 let worker = newUint8Worker();
michael@0 111 let context = worker.ContextPool._contexts[0];
michael@0 112 let helper = context.GsmPDUHelper;
michael@0 113 let iccHelper = context.ICCPDUHelper;
michael@0 114 const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
michael@0 115 const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
michael@0 116
michael@0 117 // Test 1: Read GSM alphabets.
michael@0 118 // Write alphabets before ESCAPE.
michael@0 119 for (let i = 0; i < PDU_NL_EXTENDED_ESCAPE; i++) {
michael@0 120 helper.writeHexOctet(i);
michael@0 121 }
michael@0 122
michael@0 123 // Write two ESCAPEs to make it become ' '.
michael@0 124 helper.writeHexOctet(PDU_NL_EXTENDED_ESCAPE);
michael@0 125 helper.writeHexOctet(PDU_NL_EXTENDED_ESCAPE);
michael@0 126
michael@0 127 for (let i = PDU_NL_EXTENDED_ESCAPE + 1; i < langTable.length; i++) {
michael@0 128 helper.writeHexOctet(i);
michael@0 129 }
michael@0 130
michael@0 131 // Also write two unused fields.
michael@0 132 let ffLen = 2;
michael@0 133 for (let i = 0; i < ffLen; i++) {
michael@0 134 helper.writeHexOctet(0xff);
michael@0 135 }
michael@0 136
michael@0 137 do_check_eq(iccHelper.read8BitUnpackedToString(PDU_NL_EXTENDED_ESCAPE),
michael@0 138 langTable.substring(0, PDU_NL_EXTENDED_ESCAPE));
michael@0 139 do_check_eq(iccHelper.read8BitUnpackedToString(2), " ");
michael@0 140 do_check_eq(iccHelper.read8BitUnpackedToString(langTable.length -
michael@0 141 PDU_NL_EXTENDED_ESCAPE - 1 + ffLen),
michael@0 142 langTable.substring(PDU_NL_EXTENDED_ESCAPE + 1));
michael@0 143
michael@0 144 // Test 2: Read GSM extended alphabets.
michael@0 145 for (let i = 0; i < langShiftTable.length; i++) {
michael@0 146 helper.writeHexOctet(PDU_NL_EXTENDED_ESCAPE);
michael@0 147 helper.writeHexOctet(i);
michael@0 148 }
michael@0 149
michael@0 150 // Read string before RESERVED_CONTROL.
michael@0 151 do_check_eq(iccHelper.read8BitUnpackedToString(PDU_NL_RESERVED_CONTROL * 2),
michael@0 152 langShiftTable.substring(0, PDU_NL_RESERVED_CONTROL));
michael@0 153 // ESCAPE + RESERVED_CONTROL will become ' '.
michael@0 154 do_check_eq(iccHelper.read8BitUnpackedToString(2), " ");
michael@0 155 // Read string between RESERVED_CONTROL and EXTENDED_ESCAPE.
michael@0 156 do_check_eq(iccHelper.read8BitUnpackedToString(
michael@0 157 (PDU_NL_EXTENDED_ESCAPE - PDU_NL_RESERVED_CONTROL - 1) * 2),
michael@0 158 langShiftTable.substring(PDU_NL_RESERVED_CONTROL + 1,
michael@0 159 PDU_NL_EXTENDED_ESCAPE));
michael@0 160 // ESCAPE + ESCAPE will become ' '.
michael@0 161 do_check_eq(iccHelper.read8BitUnpackedToString(2), " ");
michael@0 162 // Read remaining string.
michael@0 163 do_check_eq(iccHelper.read8BitUnpackedToString(
michael@0 164 (langShiftTable.length - PDU_NL_EXTENDED_ESCAPE - 1) * 2),
michael@0 165 langShiftTable.substring(PDU_NL_EXTENDED_ESCAPE + 1));
michael@0 166
michael@0 167 run_next_test();
michael@0 168 });
michael@0 169
michael@0 170 /**
michael@0 171 * Verify ICCPDUHelper#writeStringTo8BitUnpacked.
michael@0 172 *
michael@0 173 * Test writing GSM 8 bit alphabets.
michael@0 174 */
michael@0 175 add_test(function test_write_string_to_8bit_unpacked() {
michael@0 176 let worker = newUint8Worker();
michael@0 177 let context = worker.ContextPool._contexts[0];
michael@0 178 let helper = context.GsmPDUHelper;
michael@0 179 let iccHelper = context.ICCPDUHelper;
michael@0 180 const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
michael@0 181 const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
michael@0 182 // Length of trailing 0xff.
michael@0 183 let ffLen = 2;
michael@0 184 let str;
michael@0 185
michael@0 186 // Test 1, write GSM alphabets.
michael@0 187 iccHelper.writeStringTo8BitUnpacked(langTable.length + ffLen, langTable);
michael@0 188
michael@0 189 for (let i = 0; i < langTable.length; i++) {
michael@0 190 do_check_eq(helper.readHexOctet(), i);
michael@0 191 }
michael@0 192
michael@0 193 for (let i = 0; i < ffLen; i++) {
michael@0 194 do_check_eq(helper.readHexOctet(), 0xff);
michael@0 195 }
michael@0 196
michael@0 197 // Test 2, write GSM extended alphabets.
michael@0 198 str = "\u000c\u20ac";
michael@0 199 iccHelper.writeStringTo8BitUnpacked(4, str);
michael@0 200
michael@0 201 do_check_eq(iccHelper.read8BitUnpackedToString(4), str);
michael@0 202
michael@0 203 // Test 3, write GSM and GSM extended alphabets.
michael@0 204 // \u000c, \u20ac are from gsm extended alphabets.
michael@0 205 // \u00a3 is from gsm alphabet.
michael@0 206 str = "\u000c\u20ac\u00a3";
michael@0 207
michael@0 208 // 2 octets * 2 = 4 octets for 2 gsm extended alphabets,
michael@0 209 // 1 octet for 1 gsm alphabet,
michael@0 210 // 2 octes for trailing 0xff.
michael@0 211 // "Totally 7 octets are to be written."
michael@0 212 iccHelper.writeStringTo8BitUnpacked(7, str);
michael@0 213
michael@0 214 do_check_eq(iccHelper.read8BitUnpackedToString(7), str);
michael@0 215
michael@0 216 run_next_test();
michael@0 217 });
michael@0 218
michael@0 219 /**
michael@0 220 * Verify ICCPDUHelper#writeStringTo8BitUnpacked with maximum octets written.
michael@0 221 */
michael@0 222 add_test(function test_write_string_to_8bit_unpacked_with_max_octets_written() {
michael@0 223 let worker = newUint8Worker();
michael@0 224 let context = worker.ContextPool._contexts[0];
michael@0 225 let helper = context.GsmPDUHelper;
michael@0 226 let iccHelper = context.ICCPDUHelper;
michael@0 227 const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
michael@0 228 const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
michael@0 229
michael@0 230 // The maximum of the number of octets that can be written is 3.
michael@0 231 // Only 3 characters shall be written even the length of the string is 4.
michael@0 232 iccHelper.writeStringTo8BitUnpacked(3, langTable.substring(0, 4));
michael@0 233 helper.writeHexOctet(0xff); // dummy octet.
michael@0 234 for (let i = 0; i < 3; i++) {
michael@0 235 do_check_eq(helper.readHexOctet(), i);
michael@0 236 }
michael@0 237 do_check_false(helper.readHexOctet() == 4);
michael@0 238
michael@0 239 // \u000c is GSM extended alphabet, 2 octets.
michael@0 240 // \u00a3 is GSM alphabet, 1 octet.
michael@0 241 let str = "\u000c\u00a3";
michael@0 242 iccHelper.writeStringTo8BitUnpacked(3, str);
michael@0 243 do_check_eq(iccHelper.read8BitUnpackedToString(3), str);
michael@0 244
michael@0 245 str = "\u00a3\u000c";
michael@0 246 iccHelper.writeStringTo8BitUnpacked(3, str);
michael@0 247 do_check_eq(iccHelper.read8BitUnpackedToString(3), str);
michael@0 248
michael@0 249 // 2 GSM extended alphabets cost 4 octets, but maximum is 3, so only the 1st
michael@0 250 // alphabet can be written.
michael@0 251 str = "\u000c\u000c";
michael@0 252 iccHelper.writeStringTo8BitUnpacked(3, str);
michael@0 253 helper.writeHexOctet(0xff); // dummy octet.
michael@0 254 do_check_eq(iccHelper.read8BitUnpackedToString(4), str.substring(0, 1));
michael@0 255
michael@0 256 run_next_test();
michael@0 257 });
michael@0 258
michael@0 259 /**
michael@0 260 * Verify ICCPDUHelper.readAlphaIdentifier
michael@0 261 */
michael@0 262 add_test(function test_read_alpha_identifier() {
michael@0 263 let worker = newUint8Worker();
michael@0 264 let context = worker.ContextPool._contexts[0];
michael@0 265 let helper = context.GsmPDUHelper;
michael@0 266 let iccHelper = context.ICCPDUHelper;
michael@0 267
michael@0 268 // UCS2: 0x80
michael@0 269 let text = "TEST";
michael@0 270 helper.writeHexOctet(0x80);
michael@0 271 helper.writeUCS2String(text);
michael@0 272 // Also write two unused octets.
michael@0 273 let ffLen = 2;
michael@0 274 for (let i = 0; i < ffLen; i++) {
michael@0 275 helper.writeHexOctet(0xff);
michael@0 276 }
michael@0 277 do_check_eq(iccHelper.readAlphaIdentifier(1 + (2 * text.length) + ffLen), text);
michael@0 278
michael@0 279 // UCS2: 0x81
michael@0 280 let array = [0x81, 0x08, 0xd2, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, 0xff, 0xff];
michael@0 281 for (let i = 0; i < array.length; i++) {
michael@0 282 helper.writeHexOctet(array[i]);
michael@0 283 }
michael@0 284 do_check_eq(iccHelper.readAlphaIdentifier(array.length), "Mozilla\u694a");
michael@0 285
michael@0 286 // UCS2: 0x82
michael@0 287 let array2 = [0x82, 0x08, 0x69, 0x00, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, 0xff, 0xff];
michael@0 288 for (let i = 0; i < array2.length; i++) {
michael@0 289 helper.writeHexOctet(array2[i]);
michael@0 290 }
michael@0 291 do_check_eq(iccHelper.readAlphaIdentifier(array2.length), "Mozilla\u694a");
michael@0 292
michael@0 293 // GSM 8 Bit Unpacked
michael@0 294 const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
michael@0 295 for (let i = 0; i < PDU_NL_EXTENDED_ESCAPE; i++) {
michael@0 296 helper.writeHexOctet(i);
michael@0 297 }
michael@0 298 do_check_eq(iccHelper.readAlphaIdentifier(PDU_NL_EXTENDED_ESCAPE),
michael@0 299 langTable.substring(0, PDU_NL_EXTENDED_ESCAPE));
michael@0 300
michael@0 301 run_next_test();
michael@0 302 });
michael@0 303
michael@0 304 /**
michael@0 305 * Verify ICCPDUHelper.writeAlphaIdentifier
michael@0 306 */
michael@0 307 add_test(function test_write_alpha_identifier() {
michael@0 308 let worker = newUint8Worker();
michael@0 309 let context = worker.ContextPool._contexts[0];
michael@0 310 let helper = context.GsmPDUHelper;
michael@0 311 let iccHelper = context.ICCPDUHelper;
michael@0 312 // Length of trailing 0xff.
michael@0 313 let ffLen = 2;
michael@0 314
michael@0 315 // Removal
michael@0 316 iccHelper.writeAlphaIdentifier(10, null);
michael@0 317 do_check_eq(iccHelper.readAlphaIdentifier(10), "");
michael@0 318
michael@0 319 // GSM 8 bit
michael@0 320 let str = "Mozilla";
michael@0 321 iccHelper.writeAlphaIdentifier(str.length + ffLen, str);
michael@0 322 do_check_eq(iccHelper.readAlphaIdentifier(str.length + ffLen), str);
michael@0 323
michael@0 324 // UCS2
michael@0 325 str = "Mozilla\u694a";
michael@0 326 iccHelper.writeAlphaIdentifier(str.length * 2 + ffLen, str);
michael@0 327 // * 2 for each character will be encoded to UCS2 alphabets.
michael@0 328 do_check_eq(iccHelper.readAlphaIdentifier(str.length * 2 + ffLen), str);
michael@0 329
michael@0 330 // Test with maximum octets written.
michael@0 331 // 1 coding scheme (0x80) and 1 UCS2 character, total 3 octets.
michael@0 332 str = "\u694a";
michael@0 333 iccHelper.writeAlphaIdentifier(3, str);
michael@0 334 do_check_eq(iccHelper.readAlphaIdentifier(3), str);
michael@0 335
michael@0 336 // 1 coding scheme (0x80) and 2 UCS2 characters, total 5 octets.
michael@0 337 // numOctets is limited to 4, so only 1 UCS2 character can be written.
michael@0 338 str = "\u694a\u694a";
michael@0 339 iccHelper.writeAlphaIdentifier(4, str);
michael@0 340 helper.writeHexOctet(0xff); // dummy octet.
michael@0 341 do_check_eq(iccHelper.readAlphaIdentifier(5), str.substring(0, 1));
michael@0 342
michael@0 343 // Write 0 octet.
michael@0 344 iccHelper.writeAlphaIdentifier(0, "1");
michael@0 345 helper.writeHexOctet(0xff); // dummy octet.
michael@0 346 do_check_eq(iccHelper.readAlphaIdentifier(1), "");
michael@0 347
michael@0 348 run_next_test();
michael@0 349 });
michael@0 350
michael@0 351 /**
michael@0 352 * Verify ICCPDUHelper.readAlphaIdDiallingNumber
michael@0 353 */
michael@0 354 add_test(function test_read_alpha_id_dialling_number() {
michael@0 355 let worker = newUint8Worker();
michael@0 356 let context = worker.ContextPool._contexts[0];
michael@0 357 let helper = context.GsmPDUHelper;
michael@0 358 let iccHelper = context.ICCPDUHelper;
michael@0 359 let buf = context.Buf;
michael@0 360 const recordSize = 32;
michael@0 361
michael@0 362 function testReadAlphaIdDiallingNumber(contact) {
michael@0 363 iccHelper.readAlphaIdentifier = function() {
michael@0 364 return contact.alphaId;
michael@0 365 };
michael@0 366
michael@0 367 iccHelper.readNumberWithLength = function() {
michael@0 368 return contact.number;
michael@0 369 };
michael@0 370
michael@0 371 let strLen = recordSize * 2;
michael@0 372 buf.writeInt32(strLen); // fake length
michael@0 373 helper.writeHexOctet(0xff); // fake CCP
michael@0 374 helper.writeHexOctet(0xff); // fake EXT1
michael@0 375 buf.writeStringDelimiter(strLen);
michael@0 376
michael@0 377 let contactR = iccHelper.readAlphaIdDiallingNumber(recordSize);
michael@0 378 if (contact.alphaId == "" && contact.number == "") {
michael@0 379 do_check_eq(contactR, null);
michael@0 380 } else {
michael@0 381 do_check_eq(contactR.alphaId, contact.alphaId);
michael@0 382 do_check_eq(contactR.number, contact.number);
michael@0 383 }
michael@0 384 }
michael@0 385
michael@0 386 testReadAlphaIdDiallingNumber({alphaId: "AlphaId", number: "0987654321"});
michael@0 387 testReadAlphaIdDiallingNumber({alphaId: "", number: ""});
michael@0 388
michael@0 389 run_next_test();
michael@0 390 });
michael@0 391
michael@0 392 /**
michael@0 393 * Verify ICCPDUHelper.writeAlphaIdDiallingNumber
michael@0 394 */
michael@0 395 add_test(function test_write_alpha_id_dialling_number() {
michael@0 396 let worker = newUint8Worker();
michael@0 397 let context = worker.ContextPool._contexts[0];
michael@0 398 let helper = context.ICCPDUHelper;
michael@0 399 const recordSize = 32;
michael@0 400
michael@0 401 // Write a normal contact.
michael@0 402 let contactW = {
michael@0 403 alphaId: "Mozilla",
michael@0 404 number: "1234567890"
michael@0 405 };
michael@0 406 helper.writeAlphaIdDiallingNumber(recordSize, contactW.alphaId,
michael@0 407 contactW.number);
michael@0 408
michael@0 409 let contactR = helper.readAlphaIdDiallingNumber(recordSize);
michael@0 410 do_check_eq(contactW.alphaId, contactR.alphaId);
michael@0 411 do_check_eq(contactW.number, contactR.number);
michael@0 412
michael@0 413 // Write a contact with alphaId encoded in UCS2 and number has '+'.
michael@0 414 let contactUCS2 = {
michael@0 415 alphaId: "火狐",
michael@0 416 number: "+1234567890"
michael@0 417 };
michael@0 418 helper.writeAlphaIdDiallingNumber(recordSize, contactUCS2.alphaId,
michael@0 419 contactUCS2.number);
michael@0 420 contactR = helper.readAlphaIdDiallingNumber(recordSize);
michael@0 421 do_check_eq(contactUCS2.alphaId, contactR.alphaId);
michael@0 422 do_check_eq(contactUCS2.number, contactR.number);
michael@0 423
michael@0 424 // Write a null contact (Removal).
michael@0 425 helper.writeAlphaIdDiallingNumber(recordSize);
michael@0 426 contactR = helper.readAlphaIdDiallingNumber(recordSize);
michael@0 427 do_check_eq(contactR, null);
michael@0 428
michael@0 429 // Write a longer alphaId/dialling number
michael@0 430 // Dialling Number : Maximum 20 digits(10 octets).
michael@0 431 // Alpha Identifier: 32(recordSize) - 14 (10 octets for Dialling Number, 1
michael@0 432 // octet for TON/NPI, 1 for number length octet, and 2 for
michael@0 433 // Ext) = Maximum 18 octets.
michael@0 434 let longContact = {
michael@0 435 alphaId: "AAAAAAAAABBBBBBBBBCCCCCCCCC",
michael@0 436 number: "123456789012345678901234567890",
michael@0 437 };
michael@0 438 helper.writeAlphaIdDiallingNumber(recordSize, longContact.alphaId,
michael@0 439 longContact.number);
michael@0 440 contactR = helper.readAlphaIdDiallingNumber(recordSize);
michael@0 441 do_check_eq(contactR.alphaId, "AAAAAAAAABBBBBBBBB");
michael@0 442 do_check_eq(contactR.number, "12345678901234567890");
michael@0 443
michael@0 444 // Add '+' to number and test again.
michael@0 445 longContact.number = "+123456789012345678901234567890";
michael@0 446 helper.writeAlphaIdDiallingNumber(recordSize, longContact.alphaId,
michael@0 447 longContact.number);
michael@0 448 contactR = helper.readAlphaIdDiallingNumber(recordSize);
michael@0 449 do_check_eq(contactR.alphaId, "AAAAAAAAABBBBBBBBB");
michael@0 450 do_check_eq(contactR.number, "+12345678901234567890");
michael@0 451
michael@0 452 run_next_test();
michael@0 453 });
michael@0 454
michael@0 455 /**
michael@0 456 * Verify ICCPDUHelper.writeDiallingNumber
michael@0 457 */
michael@0 458 add_test(function test_write_dialling_number() {
michael@0 459 let worker = newUint8Worker();
michael@0 460 let context = worker.ContextPool._contexts[0];
michael@0 461 let helper = context.ICCPDUHelper;
michael@0 462
michael@0 463 // with +
michael@0 464 let number = "+123456";
michael@0 465 let len = 4;
michael@0 466 helper.writeDiallingNumber(number);
michael@0 467 do_check_eq(helper.readDiallingNumber(len), number);
michael@0 468
michael@0 469 // without +
michael@0 470 number = "987654";
michael@0 471 len = 4;
michael@0 472 helper.writeDiallingNumber(number);
michael@0 473 do_check_eq(helper.readDiallingNumber(len), number);
michael@0 474
michael@0 475 number = "9876543";
michael@0 476 len = 5;
michael@0 477 helper.writeDiallingNumber(number);
michael@0 478 do_check_eq(helper.readDiallingNumber(len), number);
michael@0 479
michael@0 480 run_next_test();
michael@0 481 });
michael@0 482
michael@0 483 /**
michael@0 484 * Verify ICCPDUHelper.readNumberWithLength
michael@0 485 */
michael@0 486 add_test(function test_read_number_with_length() {
michael@0 487 let worker = newUint8Worker();
michael@0 488 let context = worker.ContextPool._contexts[0];
michael@0 489 let helper = context.GsmPDUHelper;
michael@0 490 let iccHelper = context.ICCPDUHelper;
michael@0 491 let number = "123456789";
michael@0 492
michael@0 493 iccHelper.readDiallingNumber = function(numLen) {
michael@0 494 return number.substring(0, numLen);
michael@0 495 };
michael@0 496
michael@0 497 helper.writeHexOctet(number.length + 1);
michael@0 498 helper.writeHexOctet(PDU_TOA_ISDN);
michael@0 499 do_check_eq(iccHelper.readNumberWithLength(), number);
michael@0 500
michael@0 501 helper.writeHexOctet(0xff);
michael@0 502 do_check_eq(iccHelper.readNumberWithLength(), null);
michael@0 503
michael@0 504 run_next_test();
michael@0 505 });
michael@0 506
michael@0 507 /**
michael@0 508 * Verify ICCPDUHelper.writeNumberWithLength
michael@0 509 */
michael@0 510 add_test(function test_write_number_with_length() {
michael@0 511 let worker = newUint8Worker();
michael@0 512 let context = worker.ContextPool._contexts[0];
michael@0 513 let helper = context.GsmPDUHelper;
michael@0 514 let iccHelper = context.ICCPDUHelper;
michael@0 515
michael@0 516 function test(number, expectedNumber) {
michael@0 517 expectedNumber = expectedNumber || number;
michael@0 518 iccHelper.writeNumberWithLength(number);
michael@0 519 let numLen = helper.readHexOctet();
michael@0 520 do_check_eq(expectedNumber, iccHelper.readDiallingNumber(numLen));
michael@0 521 for (let i = 0; i < (ADN_MAX_BCD_NUMBER_BYTES - numLen); i++) {
michael@0 522 do_check_eq(0xff, helper.readHexOctet());
michael@0 523 }
michael@0 524 }
michael@0 525
michael@0 526 // without +
michael@0 527 test("123456789");
michael@0 528
michael@0 529 // with +
michael@0 530 test("+987654321");
michael@0 531
michael@0 532 // extended BCD coding
michael@0 533 test("1*2#3,4*5#6,");
michael@0 534
michael@0 535 // with + and extended BCD coding
michael@0 536 test("+1*2#3,4*5#6,");
michael@0 537
michael@0 538 // non-supported characters should not be written.
michael@0 539 test("(1)23-456+789", "123456789");
michael@0 540
michael@0 541 test("++(01)2*3-4#5,6+7(8)9*0#1,", "+012*34#5,6789*0#1,");
michael@0 542
michael@0 543 // null
michael@0 544 iccHelper.writeNumberWithLength(null);
michael@0 545 for (let i = 0; i < (ADN_MAX_BCD_NUMBER_BYTES + 1); i++) {
michael@0 546 do_check_eq(0xff, helper.readHexOctet());
michael@0 547 }
michael@0 548
michael@0 549 run_next_test();
michael@0 550 });
michael@0 551
michael@0 552 /**
michael@0 553 * Verify GsmPDUHelper.writeTimestamp
michael@0 554 */
michael@0 555 add_test(function test_write_timestamp() {
michael@0 556 let worker = newUint8Worker();
michael@0 557 let context = worker.ContextPool._contexts[0];
michael@0 558 let helper = context.GsmPDUHelper;
michael@0 559
michael@0 560 // current date
michael@0 561 let dateInput = new Date();
michael@0 562 let dateOutput = new Date();
michael@0 563 helper.writeTimestamp(dateInput);
michael@0 564 dateOutput.setTime(helper.readTimestamp());
michael@0 565
michael@0 566 do_check_eq(dateInput.getFullYear(), dateOutput.getFullYear());
michael@0 567 do_check_eq(dateInput.getMonth(), dateOutput.getMonth());
michael@0 568 do_check_eq(dateInput.getDate(), dateOutput.getDate());
michael@0 569 do_check_eq(dateInput.getHours(), dateOutput.getHours());
michael@0 570 do_check_eq(dateInput.getMinutes(), dateOutput.getMinutes());
michael@0 571 do_check_eq(dateInput.getSeconds(), dateOutput.getSeconds());
michael@0 572 do_check_eq(dateInput.getTimezoneOffset(), dateOutput.getTimezoneOffset());
michael@0 573
michael@0 574 // 2034-01-23 12:34:56 -0800 GMT
michael@0 575 let time = Date.UTC(2034, 1, 23, 12, 34, 56);
michael@0 576 time = time - (8 * 60 * 60 * 1000);
michael@0 577 dateInput.setTime(time);
michael@0 578 helper.writeTimestamp(dateInput);
michael@0 579 dateOutput.setTime(helper.readTimestamp());
michael@0 580
michael@0 581 do_check_eq(dateInput.getFullYear(), dateOutput.getFullYear());
michael@0 582 do_check_eq(dateInput.getMonth(), dateOutput.getMonth());
michael@0 583 do_check_eq(dateInput.getDate(), dateOutput.getDate());
michael@0 584 do_check_eq(dateInput.getHours(), dateOutput.getHours());
michael@0 585 do_check_eq(dateInput.getMinutes(), dateOutput.getMinutes());
michael@0 586 do_check_eq(dateInput.getSeconds(), dateOutput.getSeconds());
michael@0 587 do_check_eq(dateInput.getTimezoneOffset(), dateOutput.getTimezoneOffset());
michael@0 588
michael@0 589 run_next_test();
michael@0 590 });
michael@0 591
michael@0 592 /**
michael@0 593 * Verify GsmPDUHelper.octectToBCD and GsmPDUHelper.BCDToOctet
michael@0 594 */
michael@0 595 add_test(function test_octect_BCD() {
michael@0 596 let worker = newUint8Worker();
michael@0 597 let context = worker.ContextPool._contexts[0];
michael@0 598 let helper = context.GsmPDUHelper;
michael@0 599
michael@0 600 // 23
michael@0 601 let number = 23;
michael@0 602 let octet = helper.BCDToOctet(number);
michael@0 603 do_check_eq(helper.octetToBCD(octet), number);
michael@0 604
michael@0 605 // 56
michael@0 606 number = 56;
michael@0 607 octet = helper.BCDToOctet(number);
michael@0 608 do_check_eq(helper.octetToBCD(octet), number);
michael@0 609
michael@0 610 // 0x23
michael@0 611 octet = 0x23;
michael@0 612 number = helper.octetToBCD(octet);
michael@0 613 do_check_eq(helper.BCDToOctet(number), octet);
michael@0 614
michael@0 615 // 0x56
michael@0 616 octet = 0x56;
michael@0 617 number = helper.octetToBCD(octet);
michael@0 618 do_check_eq(helper.BCDToOctet(number), octet);
michael@0 619
michael@0 620 run_next_test();
michael@0 621 });
michael@0 622
michael@0 623 /**
michael@0 624 * Verify ICCUtilsHelper.isICCServiceAvailable.
michael@0 625 */
michael@0 626 add_test(function test_is_icc_service_available() {
michael@0 627 let worker = newUint8Worker();
michael@0 628 let context = worker.ContextPool._contexts[0];
michael@0 629 let ICCUtilsHelper = context.ICCUtilsHelper;
michael@0 630 let RIL = context.RIL;
michael@0 631
michael@0 632 function test_table(sst, geckoService, simEnabled, usimEnabled) {
michael@0 633 RIL.iccInfoPrivate.sst = sst;
michael@0 634 RIL.appType = CARD_APPTYPE_SIM;
michael@0 635 do_check_eq(ICCUtilsHelper.isICCServiceAvailable(geckoService), simEnabled);
michael@0 636 RIL.appType = CARD_APPTYPE_USIM;
michael@0 637 do_check_eq(ICCUtilsHelper.isICCServiceAvailable(geckoService), usimEnabled);
michael@0 638 }
michael@0 639
michael@0 640 test_table([0x08], "ADN", true, false);
michael@0 641 test_table([0x08], "FDN", false, false);
michael@0 642 test_table([0x08], "SDN", false, true);
michael@0 643
michael@0 644 run_next_test();
michael@0 645 });
michael@0 646
michael@0 647 /**
michael@0 648 * Verify ICCUtilsHelper.isGsm8BitAlphabet
michael@0 649 */
michael@0 650 add_test(function test_is_gsm_8bit_alphabet() {
michael@0 651 let worker = newUint8Worker();
michael@0 652 let context = worker.ContextPool._contexts[0];
michael@0 653 let ICCUtilsHelper = context.ICCUtilsHelper;
michael@0 654 const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
michael@0 655 const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
michael@0 656
michael@0 657 do_check_eq(ICCUtilsHelper.isGsm8BitAlphabet(langTable), true);
michael@0 658 do_check_eq(ICCUtilsHelper.isGsm8BitAlphabet(langShiftTable), true);
michael@0 659 do_check_eq(ICCUtilsHelper.isGsm8BitAlphabet("\uaaaa"), false);
michael@0 660
michael@0 661 run_next_test();
michael@0 662 });
michael@0 663
michael@0 664 /**
michael@0 665 * Verify RIL.iccGetCardLockState("fdn")
michael@0 666 */
michael@0 667 add_test(function test_icc_get_card_lock_state_fdn() {
michael@0 668 let worker = newUint8Worker();
michael@0 669 let context = worker.ContextPool._contexts[0];
michael@0 670 let ril = context.RIL;
michael@0 671 let buf = context.Buf;
michael@0 672
michael@0 673 buf.sendParcel = function() {
michael@0 674 // Request Type.
michael@0 675 do_check_eq(this.readInt32(), REQUEST_QUERY_FACILITY_LOCK)
michael@0 676
michael@0 677 // Token : we don't care.
michael@0 678 this.readInt32();
michael@0 679
michael@0 680 // String Array Length.
michael@0 681 do_check_eq(this.readInt32(), ril.v5Legacy ? 3 : 4);
michael@0 682
michael@0 683 // Facility.
michael@0 684 do_check_eq(this.readString(), ICC_CB_FACILITY_FDN);
michael@0 685
michael@0 686 // Password.
michael@0 687 do_check_eq(this.readString(), "");
michael@0 688
michael@0 689 // Service class.
michael@0 690 do_check_eq(this.readString(), (ICC_SERVICE_CLASS_VOICE |
michael@0 691 ICC_SERVICE_CLASS_DATA |
michael@0 692 ICC_SERVICE_CLASS_FAX).toString());
michael@0 693
michael@0 694 if (!ril.v5Legacy) {
michael@0 695 // AID. Ignore because it's from modem.
michael@0 696 this.readInt32();
michael@0 697 }
michael@0 698
michael@0 699 run_next_test();
michael@0 700 };
michael@0 701
michael@0 702 ril.iccGetCardLockState({lockType: "fdn"});
michael@0 703 });
michael@0 704
michael@0 705 add_test(function test_get_network_name_from_icc() {
michael@0 706 let worker = newUint8Worker();
michael@0 707 let context = worker.ContextPool._contexts[0];
michael@0 708 let RIL = context.RIL;
michael@0 709 let ICCUtilsHelper = context.ICCUtilsHelper;
michael@0 710
michael@0 711 function testGetNetworkNameFromICC(operatorData, expectedResult) {
michael@0 712 let result = ICCUtilsHelper.getNetworkNameFromICC(operatorData.mcc,
michael@0 713 operatorData.mnc,
michael@0 714 operatorData.lac);
michael@0 715
michael@0 716 if (expectedResult == null) {
michael@0 717 do_check_eq(result, expectedResult);
michael@0 718 } else {
michael@0 719 do_check_eq(result.fullName, expectedResult.longName);
michael@0 720 do_check_eq(result.shortName, expectedResult.shortName);
michael@0 721 }
michael@0 722 }
michael@0 723
michael@0 724 // Before EF_OPL and EF_PNN have been loaded.
michael@0 725 testGetNetworkNameFromICC({mcc: 123, mnc: 456, lac: 0x1000}, null);
michael@0 726 testGetNetworkNameFromICC({mcc: 321, mnc: 654, lac: 0x2000}, null);
michael@0 727
michael@0 728 // Set HPLMN
michael@0 729 RIL.iccInfo.mcc = 123;
michael@0 730 RIL.iccInfo.mnc = 456;
michael@0 731
michael@0 732 RIL.voiceRegistrationState = {
michael@0 733 cell: {
michael@0 734 gsmLocationAreaCode: 0x1000
michael@0 735 }
michael@0 736 };
michael@0 737 RIL.operator = {};
michael@0 738
michael@0 739 // Set EF_PNN
michael@0 740 RIL.iccInfoPrivate = {
michael@0 741 PNN: [
michael@0 742 {"fullName": "PNN1Long", "shortName": "PNN1Short"},
michael@0 743 {"fullName": "PNN2Long", "shortName": "PNN2Short"},
michael@0 744 {"fullName": "PNN3Long", "shortName": "PNN3Short"},
michael@0 745 {"fullName": "PNN4Long", "shortName": "PNN4Short"}
michael@0 746 ]
michael@0 747 };
michael@0 748
michael@0 749 // EF_OPL isn't available and current isn't in HPLMN,
michael@0 750 testGetNetworkNameFromICC({mcc: 321, mnc: 654, lac: 0x1000}, null);
michael@0 751
michael@0 752 // EF_OPL isn't available and current is in HPLMN,
michael@0 753 // the first record of PNN should be returned.
michael@0 754 testGetNetworkNameFromICC({mcc: 123, mnc: 456, lac: 0x1000},
michael@0 755 {longName: "PNN1Long", shortName: "PNN1Short"});
michael@0 756
michael@0 757 // Set EF_OPL
michael@0 758 RIL.iccInfoPrivate.OPL = [
michael@0 759 {
michael@0 760 "mcc": 123,
michael@0 761 "mnc": 456,
michael@0 762 "lacTacStart": 0,
michael@0 763 "lacTacEnd": 0xFFFE,
michael@0 764 "pnnRecordId": 4
michael@0 765 },
michael@0 766 {
michael@0 767 "mcc": 321,
michael@0 768 "mnc": 654,
michael@0 769 "lacTacStart": 0,
michael@0 770 "lacTacEnd": 0x0010,
michael@0 771 "pnnRecordId": 3
michael@0 772 },
michael@0 773 {
michael@0 774 "mcc": 321,
michael@0 775 "mnc": 654,
michael@0 776 "lacTacStart": 0x0100,
michael@0 777 "lacTacEnd": 0x1010,
michael@0 778 "pnnRecordId": 2
michael@0 779 }
michael@0 780 ];
michael@0 781
michael@0 782 // Both EF_PNN and EF_OPL are presented, and current PLMN is HPLMN,
michael@0 783 testGetNetworkNameFromICC({mcc: 123, mnc: 456, lac: 0x1000},
michael@0 784 {longName: "PNN4Long", shortName: "PNN4Short"});
michael@0 785
michael@0 786 // Current PLMN is not HPLMN, and according to LAC, we should get
michael@0 787 // the second PNN record.
michael@0 788 testGetNetworkNameFromICC({mcc: 321, mnc: 654, lac: 0x1000},
michael@0 789 {longName: "PNN2Long", shortName: "PNN2Short"});
michael@0 790
michael@0 791 // Current PLMN is not HPLMN, and according to LAC, we should get
michael@0 792 // the thrid PNN record.
michael@0 793 testGetNetworkNameFromICC({mcc: 321, mnc: 654, lac: 0x0001},
michael@0 794 {longName: "PNN3Long", shortName: "PNN3Short"});
michael@0 795
michael@0 796 run_next_test();
michael@0 797 });
michael@0 798
michael@0 799 add_test(function test_path_id_for_spid_and_spn() {
michael@0 800 let worker = newWorker({
michael@0 801 postRILMessage: function(data) {
michael@0 802 // Do nothing
michael@0 803 },
michael@0 804 postMessage: function(message) {
michael@0 805 // Do nothing
michael@0 806 }});
michael@0 807 let context = worker.ContextPool._contexts[0];
michael@0 808 let RIL = context.RIL;
michael@0 809 let ICCFileHelper = context.ICCFileHelper;
michael@0 810
michael@0 811 // Test SIM
michael@0 812 RIL.appType = CARD_APPTYPE_SIM;
michael@0 813 do_check_eq(ICCFileHelper.getEFPath(ICC_EF_SPDI),
michael@0 814 EF_PATH_MF_SIM + EF_PATH_DF_GSM);
michael@0 815 do_check_eq(ICCFileHelper.getEFPath(ICC_EF_SPN),
michael@0 816 EF_PATH_MF_SIM + EF_PATH_DF_GSM);
michael@0 817
michael@0 818 // Test USIM
michael@0 819 RIL.appType = CARD_APPTYPE_USIM;
michael@0 820 do_check_eq(ICCFileHelper.getEFPath(ICC_EF_SPDI),
michael@0 821 EF_PATH_MF_SIM + EF_PATH_ADF_USIM);
michael@0 822 do_check_eq(ICCFileHelper.getEFPath(ICC_EF_SPDI),
michael@0 823 EF_PATH_MF_SIM + EF_PATH_ADF_USIM);
michael@0 824 run_next_test();
michael@0 825 });
michael@0 826
michael@0 827 /**
michael@0 828 * Verify ICCUtilsHelper.parsePbrTlvs
michael@0 829 */
michael@0 830 add_test(function test_parse_pbr_tlvs() {
michael@0 831 let worker = newUint8Worker();
michael@0 832 let context = worker.ContextPool._contexts[0];
michael@0 833 let buf = context.Buf;
michael@0 834
michael@0 835 let pbrTlvs = [
michael@0 836 {tag: ICC_USIM_TYPE1_TAG,
michael@0 837 length: 0x0F,
michael@0 838 value: [{tag: ICC_USIM_EFADN_TAG,
michael@0 839 length: 0x03,
michael@0 840 value: [0x4F, 0x3A, 0x02]},
michael@0 841 {tag: ICC_USIM_EFIAP_TAG,
michael@0 842 length: 0x03,
michael@0 843 value: [0x4F, 0x25, 0x01]},
michael@0 844 {tag: ICC_USIM_EFPBC_TAG,
michael@0 845 length: 0x03,
michael@0 846 value: [0x4F, 0x09, 0x04]}]
michael@0 847 },
michael@0 848 {tag: ICC_USIM_TYPE2_TAG,
michael@0 849 length: 0x05,
michael@0 850 value: [{tag: ICC_USIM_EFEMAIL_TAG,
michael@0 851 length: 0x03,
michael@0 852 value: [0x4F, 0x50, 0x0B]},
michael@0 853 {tag: ICC_USIM_EFANR_TAG,
michael@0 854 length: 0x03,
michael@0 855 value: [0x4F, 0x11, 0x02]},
michael@0 856 {tag: ICC_USIM_EFANR_TAG,
michael@0 857 length: 0x03,
michael@0 858 value: [0x4F, 0x12, 0x03]}]
michael@0 859 },
michael@0 860 {tag: ICC_USIM_TYPE3_TAG,
michael@0 861 length: 0x0A,
michael@0 862 value: [{tag: ICC_USIM_EFCCP1_TAG,
michael@0 863 length: 0x03,
michael@0 864 value: [0x4F, 0x3D, 0x0A]},
michael@0 865 {tag: ICC_USIM_EFEXT1_TAG,
michael@0 866 length: 0x03,
michael@0 867 value: [0x4F, 0x4A, 0x03]}]
michael@0 868 },
michael@0 869 ];
michael@0 870
michael@0 871 let pbr = context.ICCUtilsHelper.parsePbrTlvs(pbrTlvs);
michael@0 872 do_check_eq(pbr.adn.fileId, 0x4F3a);
michael@0 873 do_check_eq(pbr.iap.fileId, 0x4F25);
michael@0 874 do_check_eq(pbr.pbc.fileId, 0x4F09);
michael@0 875 do_check_eq(pbr.email.fileId, 0x4F50);
michael@0 876 do_check_eq(pbr.anr0.fileId, 0x4f11);
michael@0 877 do_check_eq(pbr.anr1.fileId, 0x4f12);
michael@0 878 do_check_eq(pbr.ccp1.fileId, 0x4F3D);
michael@0 879 do_check_eq(pbr.ext1.fileId, 0x4F4A);
michael@0 880
michael@0 881 run_next_test();
michael@0 882 });
michael@0 883
michael@0 884 /**
michael@0 885 * Verify ICCIOHelper.loadLinearFixedEF with recordSize.
michael@0 886 */
michael@0 887 add_test(function test_load_linear_fixed_ef() {
michael@0 888 let worker = newUint8Worker();
michael@0 889 let context = worker.ContextPool._contexts[0];
michael@0 890 let ril = context.RIL;
michael@0 891 let io = context.ICCIOHelper;
michael@0 892
michael@0 893 io.getResponse = function fakeGetResponse(options) {
michael@0 894 // When recordSize is provided, loadLinearFixedEF should call iccIO directly.
michael@0 895 do_check_true(false);
michael@0 896 run_next_test();
michael@0 897 };
michael@0 898
michael@0 899 ril.iccIO = function fakeIccIO(options) {
michael@0 900 do_check_true(true);
michael@0 901 run_next_test();
michael@0 902 };
michael@0 903
michael@0 904 io.loadLinearFixedEF({recordSize: 0x20});
michael@0 905 });
michael@0 906
michael@0 907 /**
michael@0 908 * Verify ICCIOHelper.loadLinearFixedEF without recordSize.
michael@0 909 */
michael@0 910 add_test(function test_load_linear_fixed_ef() {
michael@0 911 let worker = newUint8Worker();
michael@0 912 let context = worker.ContextPool._contexts[0];
michael@0 913 let ril = context.RIL;
michael@0 914 let io = context.ICCIOHelper;
michael@0 915
michael@0 916 io.getResponse = function fakeGetResponse(options) {
michael@0 917 do_check_true(true);
michael@0 918 run_next_test();
michael@0 919 };
michael@0 920
michael@0 921 ril.iccIO = function fakeIccIO(options) {
michael@0 922 // When recordSize is not provided, loadLinearFixedEF should call getResponse.
michael@0 923 do_check_true(false);
michael@0 924 run_next_test();
michael@0 925 };
michael@0 926
michael@0 927 io.loadLinearFixedEF({});
michael@0 928 });
michael@0 929
michael@0 930 /**
michael@0 931 * Verify ICCRecordHelper.readPBR
michael@0 932 */
michael@0 933 add_test(function test_read_pbr() {
michael@0 934 let worker = newUint8Worker();
michael@0 935 let context = worker.ContextPool._contexts[0];
michael@0 936 let helper = context.GsmPDUHelper;
michael@0 937 let record = context.ICCRecordHelper;
michael@0 938 let buf = context.Buf;
michael@0 939 let io = context.ICCIOHelper;
michael@0 940
michael@0 941 io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
michael@0 942 let pbr_1 = [
michael@0 943 0xa8, 0x05, 0xc0, 0x03, 0x4f, 0x3a, 0x01
michael@0 944 ];
michael@0 945
michael@0 946 // Write data size
michael@0 947 buf.writeInt32(pbr_1.length * 2);
michael@0 948
michael@0 949 // Write pbr
michael@0 950 for (let i = 0; i < pbr_1.length; i++) {
michael@0 951 helper.writeHexOctet(pbr_1[i]);
michael@0 952 }
michael@0 953
michael@0 954 // Write string delimiter
michael@0 955 buf.writeStringDelimiter(pbr_1.length * 2);
michael@0 956
michael@0 957 options.totalRecords = 2;
michael@0 958 if (options.callback) {
michael@0 959 options.callback(options);
michael@0 960 }
michael@0 961 };
michael@0 962
michael@0 963 io.loadNextRecord = function fakeLoadNextRecord(options) {
michael@0 964 let pbr_2 = [
michael@0 965 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
michael@0 966 ];
michael@0 967
michael@0 968 options.p1++;
michael@0 969 if (options.callback) {
michael@0 970 options.callback(options);
michael@0 971 }
michael@0 972 };
michael@0 973
michael@0 974 let successCb = function successCb(pbrs) {
michael@0 975 do_check_eq(pbrs[0].adn.fileId, 0x4f3a);
michael@0 976 do_check_eq(pbrs.length, 1);
michael@0 977 };
michael@0 978
michael@0 979 let errorCb = function errorCb(errorMsg) {
michael@0 980 do_print("Reading EF_PBR failed, msg = " + errorMsg);
michael@0 981 do_check_true(false);
michael@0 982 };
michael@0 983
michael@0 984 record.readPBR(successCb, errorCb);
michael@0 985
michael@0 986 // Check cache pbrs when 2nd call
michael@0 987 let ifLoadEF = false;
michael@0 988 io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
michael@0 989 ifLoadEF = true;
michael@0 990 }
michael@0 991 record.readPBR(successCb, errorCb);
michael@0 992 do_check_false(ifLoadEF);
michael@0 993
michael@0 994 run_next_test();
michael@0 995 });
michael@0 996
michael@0 997 /**
michael@0 998 * Verify ICCRecordHelper.readEmail
michael@0 999 */
michael@0 1000 add_test(function test_read_email() {
michael@0 1001 let worker = newUint8Worker();
michael@0 1002 let context = worker.ContextPool._contexts[0];
michael@0 1003 let helper = context.GsmPDUHelper;
michael@0 1004 let record = context.ICCRecordHelper;
michael@0 1005 let buf = context.Buf;
michael@0 1006 let io = context.ICCIOHelper;
michael@0 1007 let recordSize;
michael@0 1008
michael@0 1009 io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
michael@0 1010 let email_1 = [
michael@0 1011 0x65, 0x6D, 0x61, 0x69, 0x6C,
michael@0 1012 0x00, 0x6D, 0x6F, 0x7A, 0x69,
michael@0 1013 0x6C, 0x6C, 0x61, 0x2E, 0x63,
michael@0 1014 0x6F, 0x6D, 0x02, 0x23];
michael@0 1015
michael@0 1016 // Write data size
michael@0 1017 buf.writeInt32(email_1.length * 2);
michael@0 1018
michael@0 1019 // Write email
michael@0 1020 for (let i = 0; i < email_1.length; i++) {
michael@0 1021 helper.writeHexOctet(email_1[i]);
michael@0 1022 }
michael@0 1023
michael@0 1024 // Write string delimiter
michael@0 1025 buf.writeStringDelimiter(email_1.length * 2);
michael@0 1026
michael@0 1027 recordSize = email_1.length;
michael@0 1028 options.recordSize = recordSize;
michael@0 1029 if (options.callback) {
michael@0 1030 options.callback(options);
michael@0 1031 }
michael@0 1032 };
michael@0 1033
michael@0 1034 function doTestReadEmail(type, expectedResult) {
michael@0 1035 let fileId = 0x6a75;
michael@0 1036 let recordNumber = 1;
michael@0 1037
michael@0 1038 // fileId and recordNumber are dummy arguments.
michael@0 1039 record.readEmail(fileId, type, recordNumber, function(email) {
michael@0 1040 do_check_eq(email, expectedResult);
michael@0 1041 });
michael@0 1042 };
michael@0 1043
michael@0 1044 doTestReadEmail(ICC_USIM_TYPE1_TAG, "email@mozilla.com$#");
michael@0 1045 doTestReadEmail(ICC_USIM_TYPE2_TAG, "email@mozilla.com");
michael@0 1046 do_check_eq(record._emailRecordSize, recordSize);
michael@0 1047
michael@0 1048 run_next_test();
michael@0 1049 });
michael@0 1050
michael@0 1051 /**
michael@0 1052 * Verify ICCRecordHelper.updateEmail
michael@0 1053 */
michael@0 1054 add_test(function test_update_email() {
michael@0 1055 const recordSize = 0x20;
michael@0 1056 const recordNumber = 1;
michael@0 1057 const fileId = 0x4f50;
michael@0 1058 const NUM_TESTS = 2;
michael@0 1059 let worker = newUint8Worker();
michael@0 1060 let context = worker.ContextPool._contexts[0];
michael@0 1061 let pduHelper = context.GsmPDUHelper;
michael@0 1062 let iccHelper = context.ICCPDUHelper;
michael@0 1063 let ril = context.RIL;
michael@0 1064 ril.appType = CARD_APPTYPE_USIM;
michael@0 1065 let recordHelper = context.ICCRecordHelper;
michael@0 1066 let buf = context.Buf;
michael@0 1067 let ioHelper = context.ICCIOHelper;
michael@0 1068 let pbr = {email: {fileId: fileId, fileType: ICC_USIM_TYPE1_TAG},
michael@0 1069 adn: {sfi: 1}};
michael@0 1070 let count = 0;
michael@0 1071
michael@0 1072 // Override.
michael@0 1073 ioHelper.updateLinearFixedEF = function(options) {
michael@0 1074 options.pathId = context.ICCFileHelper.getEFPath(options.fileId);
michael@0 1075 options.command = ICC_COMMAND_UPDATE_RECORD;
michael@0 1076 options.p1 = options.recordNumber;
michael@0 1077 options.p2 = READ_RECORD_ABSOLUTE_MODE;
michael@0 1078 options.p3 = recordSize;
michael@0 1079 ril.iccIO(options);
michael@0 1080 };
michael@0 1081
michael@0 1082 function do_test(pbr, expectedEmail, expectedAdnRecordId) {
michael@0 1083 buf.sendParcel = function() {
michael@0 1084 count++;
michael@0 1085
michael@0 1086 // Request Type.
michael@0 1087 do_check_eq(this.readInt32(), REQUEST_SIM_IO);
michael@0 1088
michael@0 1089 // Token : we don't care
michael@0 1090 this.readInt32();
michael@0 1091
michael@0 1092 // command.
michael@0 1093 do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
michael@0 1094
michael@0 1095 // fileId.
michael@0 1096 do_check_eq(this.readInt32(), fileId);
michael@0 1097
michael@0 1098 // pathId.
michael@0 1099 do_check_eq(this.readString(),
michael@0 1100 EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK);
michael@0 1101
michael@0 1102 // p1.
michael@0 1103 do_check_eq(this.readInt32(), recordNumber);
michael@0 1104
michael@0 1105 // p2.
michael@0 1106 do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
michael@0 1107
michael@0 1108 // p3.
michael@0 1109 do_check_eq(this.readInt32(), recordSize);
michael@0 1110
michael@0 1111 // data.
michael@0 1112 let strLen = this.readInt32();
michael@0 1113 let email;
michael@0 1114 if (pbr.email.fileType === ICC_USIM_TYPE1_TAG) {
michael@0 1115 email = iccHelper.read8BitUnpackedToString(recordSize);
michael@0 1116 } else {
michael@0 1117 email = iccHelper.read8BitUnpackedToString(recordSize - 2);
michael@0 1118 do_check_eq(pduHelper.readHexOctet(), pbr.adn.sfi);
michael@0 1119 do_check_eq(pduHelper.readHexOctet(), expectedAdnRecordId);
michael@0 1120 }
michael@0 1121 this.readStringDelimiter(strLen);
michael@0 1122 do_check_eq(email, expectedEmail);
michael@0 1123
michael@0 1124 // pin2.
michael@0 1125 do_check_eq(this.readString(), null);
michael@0 1126
michael@0 1127 if (!ril.v5Legacy) {
michael@0 1128 // AID. Ignore because it's from modem.
michael@0 1129 this.readInt32();
michael@0 1130 }
michael@0 1131
michael@0 1132 if (count == NUM_TESTS) {
michael@0 1133 run_next_test();
michael@0 1134 }
michael@0 1135 };
michael@0 1136 recordHelper.updateEmail(pbr, recordNumber, expectedEmail, expectedAdnRecordId);
michael@0 1137 }
michael@0 1138
michael@0 1139 do_test(pbr, "test@mail.com");
michael@0 1140 pbr.email.fileType = ICC_USIM_TYPE2_TAG;
michael@0 1141 do_test(pbr, "test@mail.com", 1);
michael@0 1142 });
michael@0 1143
michael@0 1144 /**
michael@0 1145 * Verify ICCRecordHelper.readANR
michael@0 1146 */
michael@0 1147 add_test(function test_read_anr() {
michael@0 1148 let worker = newUint8Worker();
michael@0 1149 let context = worker.ContextPool._contexts[0];
michael@0 1150 let helper = context.GsmPDUHelper;
michael@0 1151 let record = context.ICCRecordHelper;
michael@0 1152 let buf = context.Buf;
michael@0 1153 let io = context.ICCIOHelper;
michael@0 1154 let recordSize;
michael@0 1155
michael@0 1156 io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
michael@0 1157 let anr_1 = [
michael@0 1158 0x01, 0x05, 0x81, 0x10, 0x32,
michael@0 1159 0x54, 0xF6, 0xFF, 0xFF];
michael@0 1160
michael@0 1161 // Write data size
michael@0 1162 buf.writeInt32(anr_1.length * 2);
michael@0 1163
michael@0 1164 // Write anr
michael@0 1165 for (let i = 0; i < anr_1.length; i++) {
michael@0 1166 helper.writeHexOctet(anr_1[i]);
michael@0 1167 }
michael@0 1168
michael@0 1169 // Write string delimiter
michael@0 1170 buf.writeStringDelimiter(anr_1.length * 2);
michael@0 1171
michael@0 1172 recordSize = anr_1.length;
michael@0 1173 options.recordSize = recordSize;
michael@0 1174 if (options.callback) {
michael@0 1175 options.callback(options);
michael@0 1176 }
michael@0 1177 };
michael@0 1178
michael@0 1179 function doTestReadAnr(fileType, expectedResult) {
michael@0 1180 let fileId = 0x4f11;
michael@0 1181 let recordNumber = 1;
michael@0 1182
michael@0 1183 // fileId and recordNumber are dummy arguments.
michael@0 1184 record.readANR(fileId, fileType, recordNumber, function(anr) {
michael@0 1185 do_check_eq(anr, expectedResult);
michael@0 1186 });
michael@0 1187 };
michael@0 1188
michael@0 1189 doTestReadAnr(ICC_USIM_TYPE1_TAG, "0123456");
michael@0 1190 do_check_eq(record._anrRecordSize, recordSize);
michael@0 1191
michael@0 1192 run_next_test();
michael@0 1193 });
michael@0 1194
michael@0 1195 /**
michael@0 1196 * Verify ICCRecordHelper.updateANR
michael@0 1197 */
michael@0 1198 add_test(function test_update_anr() {
michael@0 1199 const recordSize = 0x20;
michael@0 1200 const recordNumber = 1;
michael@0 1201 const fileId = 0x4f11;
michael@0 1202 const NUM_TESTS = 2;
michael@0 1203 let worker = newUint8Worker();
michael@0 1204 let context = worker.ContextPool._contexts[0];
michael@0 1205 let pduHelper = context.GsmPDUHelper;
michael@0 1206 let iccHelper = context.ICCPDUHelper;
michael@0 1207 let ril = context.RIL;
michael@0 1208 ril.appType = CARD_APPTYPE_USIM;
michael@0 1209 let recordHelper = context.ICCRecordHelper;
michael@0 1210 let buf = context.Buf;
michael@0 1211 let ioHelper = context.ICCIOHelper;
michael@0 1212 let pbr = {anr0: {fileId: fileId, fileType: ICC_USIM_TYPE1_TAG},
michael@0 1213 adn: {sfi: 1}};
michael@0 1214 let count = 0;
michael@0 1215
michael@0 1216 // Override.
michael@0 1217 ioHelper.updateLinearFixedEF = function(options) {
michael@0 1218 options.pathId = context.ICCFileHelper.getEFPath(options.fileId);
michael@0 1219 options.command = ICC_COMMAND_UPDATE_RECORD;
michael@0 1220 options.p1 = options.recordNumber;
michael@0 1221 options.p2 = READ_RECORD_ABSOLUTE_MODE;
michael@0 1222 options.p3 = recordSize;
michael@0 1223 ril.iccIO(options);
michael@0 1224 };
michael@0 1225
michael@0 1226 function do_test(pbr, expectedANR, expectedAdnRecordId) {
michael@0 1227 buf.sendParcel = function() {
michael@0 1228 count++;
michael@0 1229
michael@0 1230 // Request Type.
michael@0 1231 do_check_eq(this.readInt32(), REQUEST_SIM_IO);
michael@0 1232
michael@0 1233 // Token : we don't care
michael@0 1234 this.readInt32();
michael@0 1235
michael@0 1236 // command.
michael@0 1237 do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
michael@0 1238
michael@0 1239 // fileId.
michael@0 1240 do_check_eq(this.readInt32(), fileId);
michael@0 1241
michael@0 1242 // pathId.
michael@0 1243 do_check_eq(this.readString(),
michael@0 1244 EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK);
michael@0 1245
michael@0 1246 // p1.
michael@0 1247 do_check_eq(this.readInt32(), recordNumber);
michael@0 1248
michael@0 1249 // p2.
michael@0 1250 do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
michael@0 1251
michael@0 1252 // p3.
michael@0 1253 do_check_eq(this.readInt32(), recordSize);
michael@0 1254
michael@0 1255 // data.
michael@0 1256 let strLen = this.readInt32();
michael@0 1257 // EF_AAS, ignore.
michael@0 1258 pduHelper.readHexOctet();
michael@0 1259 do_check_eq(iccHelper.readNumberWithLength(), expectedANR);
michael@0 1260 // EF_CCP, ignore.
michael@0 1261 pduHelper.readHexOctet();
michael@0 1262 // EF_EXT1, ignore.
michael@0 1263 pduHelper.readHexOctet();
michael@0 1264 if (pbr.anr0.fileType === ICC_USIM_TYPE2_TAG) {
michael@0 1265 do_check_eq(pduHelper.readHexOctet(), pbr.adn.sfi);
michael@0 1266 do_check_eq(pduHelper.readHexOctet(), expectedAdnRecordId);
michael@0 1267 }
michael@0 1268 this.readStringDelimiter(strLen);
michael@0 1269
michael@0 1270 // pin2.
michael@0 1271 do_check_eq(this.readString(), null);
michael@0 1272
michael@0 1273 if (!ril.v5Legacy) {
michael@0 1274 // AID. Ignore because it's from modem.
michael@0 1275 this.readInt32();
michael@0 1276 }
michael@0 1277
michael@0 1278 if (count == NUM_TESTS) {
michael@0 1279 run_next_test();
michael@0 1280 }
michael@0 1281 };
michael@0 1282 recordHelper.updateANR(pbr, recordNumber, expectedANR, expectedAdnRecordId);
michael@0 1283 }
michael@0 1284
michael@0 1285 do_test(pbr, "+123456789");
michael@0 1286 pbr.anr0.fileType = ICC_USIM_TYPE2_TAG;
michael@0 1287 do_test(pbr, "123456789", 1);
michael@0 1288 });
michael@0 1289
michael@0 1290 /**
michael@0 1291 * Verify ICCRecordHelper.readIAP
michael@0 1292 */
michael@0 1293 add_test(function test_read_iap() {
michael@0 1294 let worker = newUint8Worker();
michael@0 1295 let context = worker.ContextPool._contexts[0];
michael@0 1296 let helper = context.GsmPDUHelper;
michael@0 1297 let record = context.ICCRecordHelper;
michael@0 1298 let buf = context.Buf;
michael@0 1299 let io = context.ICCIOHelper;
michael@0 1300 let recordSize;
michael@0 1301
michael@0 1302 io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
michael@0 1303 let iap_1 = [0x01, 0x02];
michael@0 1304
michael@0 1305 // Write data size/
michael@0 1306 buf.writeInt32(iap_1.length * 2);
michael@0 1307
michael@0 1308 // Write iap.
michael@0 1309 for (let i = 0; i < iap_1.length; i++) {
michael@0 1310 helper.writeHexOctet(iap_1[i]);
michael@0 1311 }
michael@0 1312
michael@0 1313 // Write string delimiter.
michael@0 1314 buf.writeStringDelimiter(iap_1.length * 2);
michael@0 1315
michael@0 1316 recordSize = iap_1.length;
michael@0 1317 options.recordSize = recordSize;
michael@0 1318 if (options.callback) {
michael@0 1319 options.callback(options);
michael@0 1320 }
michael@0 1321 };
michael@0 1322
michael@0 1323 function doTestReadIAP(expectedIAP) {
michael@0 1324 const fileId = 0x4f17;
michael@0 1325 const recordNumber = 1;
michael@0 1326
michael@0 1327 let successCb = function successCb(iap) {
michael@0 1328 for (let i = 0; i < iap.length; i++) {
michael@0 1329 do_check_eq(expectedIAP[i], iap[i]);
michael@0 1330 }
michael@0 1331 run_next_test();
michael@0 1332 }.bind(this);
michael@0 1333
michael@0 1334 let errorCb = function errorCb(errorMsg) {
michael@0 1335 do_print(errorMsg);
michael@0 1336 do_check_true(false);
michael@0 1337 run_next_test();
michael@0 1338 }.bind(this);
michael@0 1339
michael@0 1340 record.readIAP(fileId, recordNumber, successCb, errorCb);
michael@0 1341 };
michael@0 1342
michael@0 1343 doTestReadIAP([1, 2]);
michael@0 1344 });
michael@0 1345
michael@0 1346 /**
michael@0 1347 * Verify ICCRecordHelper.updateIAP
michael@0 1348 */
michael@0 1349 add_test(function test_update_iap() {
michael@0 1350 const recordSize = 2;
michael@0 1351 const recordNumber = 1;
michael@0 1352 const fileId = 0x4f17;
michael@0 1353 let worker = newUint8Worker();
michael@0 1354 let context = worker.ContextPool._contexts[0];
michael@0 1355 let pduHelper = context.GsmPDUHelper;
michael@0 1356 let ril = context.RIL;
michael@0 1357 ril.appType = CARD_APPTYPE_USIM;
michael@0 1358 let recordHelper = context.ICCRecordHelper;
michael@0 1359 let buf = context.Buf;
michael@0 1360 let ioHelper = context.ICCIOHelper;
michael@0 1361 let count = 0;
michael@0 1362
michael@0 1363 // Override.
michael@0 1364 ioHelper.updateLinearFixedEF = function(options) {
michael@0 1365 options.pathId = context.ICCFileHelper.getEFPath(options.fileId);
michael@0 1366 options.command = ICC_COMMAND_UPDATE_RECORD;
michael@0 1367 options.p1 = options.recordNumber;
michael@0 1368 options.p2 = READ_RECORD_ABSOLUTE_MODE;
michael@0 1369 options.p3 = recordSize;
michael@0 1370 ril.iccIO(options);
michael@0 1371 };
michael@0 1372
michael@0 1373 function do_test(expectedIAP) {
michael@0 1374 buf.sendParcel = function() {
michael@0 1375 // Request Type.
michael@0 1376 do_check_eq(this.readInt32(), REQUEST_SIM_IO);
michael@0 1377
michael@0 1378 // Token : we don't care
michael@0 1379 this.readInt32();
michael@0 1380
michael@0 1381 // command.
michael@0 1382 do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
michael@0 1383
michael@0 1384 // fileId.
michael@0 1385 do_check_eq(this.readInt32(), fileId);
michael@0 1386
michael@0 1387 // pathId.
michael@0 1388 do_check_eq(this.readString(),
michael@0 1389 EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK);
michael@0 1390
michael@0 1391 // p1.
michael@0 1392 do_check_eq(this.readInt32(), recordNumber);
michael@0 1393
michael@0 1394 // p2.
michael@0 1395 do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
michael@0 1396
michael@0 1397 // p3.
michael@0 1398 do_check_eq(this.readInt32(), recordSize);
michael@0 1399
michael@0 1400 // data.
michael@0 1401 let strLen = this.readInt32();
michael@0 1402 for (let i = 0; i < recordSize; i++) {
michael@0 1403 do_check_eq(expectedIAP[i], pduHelper.readHexOctet());
michael@0 1404 }
michael@0 1405 this.readStringDelimiter(strLen);
michael@0 1406
michael@0 1407 // pin2.
michael@0 1408 do_check_eq(this.readString(), null);
michael@0 1409
michael@0 1410 if (!ril.v5Legacy) {
michael@0 1411 // AID. Ignore because it's from modem.
michael@0 1412 this.readInt32();
michael@0 1413 }
michael@0 1414
michael@0 1415 run_next_test();
michael@0 1416 };
michael@0 1417 recordHelper.updateIAP(fileId, recordNumber, expectedIAP);
michael@0 1418 }
michael@0 1419
michael@0 1420 do_test([1, 2]);
michael@0 1421 });
michael@0 1422
michael@0 1423 /**
michael@0 1424 * Verify ICCRecordHelper.updateADNLike.
michael@0 1425 */
michael@0 1426 add_test(function test_update_adn_like() {
michael@0 1427 let worker = newUint8Worker();
michael@0 1428 let context = worker.ContextPool._contexts[0];
michael@0 1429 let ril = context.RIL;
michael@0 1430 let record = context.ICCRecordHelper;
michael@0 1431 let io = context.ICCIOHelper;
michael@0 1432 let pdu = context.ICCPDUHelper;
michael@0 1433 let buf = context.Buf;
michael@0 1434
michael@0 1435 ril.appType = CARD_APPTYPE_SIM;
michael@0 1436 const recordSize = 0x20;
michael@0 1437 let fileId;
michael@0 1438
michael@0 1439 // Override.
michael@0 1440 io.updateLinearFixedEF = function(options) {
michael@0 1441 options.pathId = context.ICCFileHelper.getEFPath(options.fileId);
michael@0 1442 options.command = ICC_COMMAND_UPDATE_RECORD;
michael@0 1443 options.p1 = options.recordNumber;
michael@0 1444 options.p2 = READ_RECORD_ABSOLUTE_MODE;
michael@0 1445 options.p3 = recordSize;
michael@0 1446 ril.iccIO(options);
michael@0 1447 };
michael@0 1448
michael@0 1449 buf.sendParcel = function() {
michael@0 1450 // Request Type.
michael@0 1451 do_check_eq(this.readInt32(), REQUEST_SIM_IO);
michael@0 1452
michael@0 1453 // Token : we don't care
michael@0 1454 this.readInt32();
michael@0 1455
michael@0 1456 // command.
michael@0 1457 do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
michael@0 1458
michael@0 1459 // fileId.
michael@0 1460 do_check_eq(this.readInt32(), fileId);
michael@0 1461
michael@0 1462 // pathId.
michael@0 1463 do_check_eq(this.readString(), EF_PATH_MF_SIM + EF_PATH_DF_TELECOM);
michael@0 1464
michael@0 1465 // p1.
michael@0 1466 do_check_eq(this.readInt32(), 1);
michael@0 1467
michael@0 1468 // p2.
michael@0 1469 do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
michael@0 1470
michael@0 1471 // p3.
michael@0 1472 do_check_eq(this.readInt32(), 0x20);
michael@0 1473
michael@0 1474 // data.
michael@0 1475 let contact = pdu.readAlphaIdDiallingNumber(0x20);
michael@0 1476 do_check_eq(contact.alphaId, "test");
michael@0 1477 do_check_eq(contact.number, "123456");
michael@0 1478
michael@0 1479 // pin2.
michael@0 1480 if (fileId == ICC_EF_ADN) {
michael@0 1481 do_check_eq(this.readString(), null);
michael@0 1482 } else {
michael@0 1483 do_check_eq(this.readString(), "1111");
michael@0 1484 }
michael@0 1485
michael@0 1486 if (!ril.v5Legacy) {
michael@0 1487 // AID. Ignore because it's from modem.
michael@0 1488 this.readInt32();
michael@0 1489 }
michael@0 1490
michael@0 1491 if (fileId == ICC_EF_FDN) {
michael@0 1492 run_next_test();
michael@0 1493 }
michael@0 1494 };
michael@0 1495
michael@0 1496 fileId = ICC_EF_ADN;
michael@0 1497 record.updateADNLike(fileId,
michael@0 1498 {recordId: 1, alphaId: "test", number: "123456"});
michael@0 1499
michael@0 1500 fileId = ICC_EF_FDN;
michael@0 1501 record.updateADNLike(fileId,
michael@0 1502 {recordId: 1, alphaId: "test", number: "123456"},
michael@0 1503 "1111");
michael@0 1504 });
michael@0 1505
michael@0 1506 /**
michael@0 1507 * Verify ICCRecordHelper.findFreeRecordId.
michael@0 1508 */
michael@0 1509 add_test(function test_find_free_record_id() {
michael@0 1510 let worker = newUint8Worker();
michael@0 1511 let context = worker.ContextPool._contexts[0];
michael@0 1512 let pduHelper = context.GsmPDUHelper;
michael@0 1513 let recordHelper = context.ICCRecordHelper;
michael@0 1514 let buf = context.Buf;
michael@0 1515 let io = context.ICCIOHelper;
michael@0 1516
michael@0 1517 function writeRecord (record) {
michael@0 1518 // Write data size
michael@0 1519 buf.writeInt32(record.length * 2);
michael@0 1520
michael@0 1521 for (let i = 0; i < record.length; i++) {
michael@0 1522 pduHelper.writeHexOctet(record[i]);
michael@0 1523 }
michael@0 1524
michael@0 1525 // Write string delimiter
michael@0 1526 buf.writeStringDelimiter(record.length * 2);
michael@0 1527 }
michael@0 1528
michael@0 1529 io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
michael@0 1530 // Some random data.
michael@0 1531 let record = [0x12, 0x34, 0x56, 0x78, 0x90];
michael@0 1532 options.p1 = 1;
michael@0 1533 options.totalRecords = 2;
michael@0 1534 writeRecord(record);
michael@0 1535 if (options.callback) {
michael@0 1536 options.callback(options);
michael@0 1537 }
michael@0 1538 };
michael@0 1539
michael@0 1540 io.loadNextRecord = function fakeLoadNextRecord(options) {
michael@0 1541 // Unused bytes.
michael@0 1542 let record = [0xff, 0xff, 0xff, 0xff, 0xff];
michael@0 1543 options.p1++;
michael@0 1544 writeRecord(record);
michael@0 1545 if (options.callback) {
michael@0 1546 options.callback(options);
michael@0 1547 }
michael@0 1548 };
michael@0 1549
michael@0 1550 let fileId = 0x0000; // Dummy.
michael@0 1551 recordHelper.findFreeRecordId(
michael@0 1552 fileId,
michael@0 1553 function(recordId) {
michael@0 1554 do_check_eq(recordId, 2);
michael@0 1555 run_next_test();
michael@0 1556 }.bind(this),
michael@0 1557 function(errorMsg) {
michael@0 1558 do_print(errorMsg);
michael@0 1559 do_check_true(false);
michael@0 1560 run_next_test();
michael@0 1561 }.bind(this));
michael@0 1562 });
michael@0 1563
michael@0 1564 /**
michael@0 1565 * Verify ICCContactHelper.readICCContacts
michael@0 1566 */
michael@0 1567 add_test(function test_read_icc_contacts() {
michael@0 1568 let worker = newUint8Worker();
michael@0 1569 let context = worker.ContextPool._contexts[0];
michael@0 1570 let record = context.ICCRecordHelper;
michael@0 1571 let contactHelper = context.ICCContactHelper;
michael@0 1572 let ril = context.RIL;
michael@0 1573
michael@0 1574 function do_test(aSimType, aContactType, aExpectedContact, aEnhancedPhoneBook) {
michael@0 1575 ril.appType = aSimType;
michael@0 1576 ril._isCdma = (aSimType === CARD_APPTYPE_RUIM);
michael@0 1577 ril.iccInfoPrivate.cst = (aEnhancedPhoneBook) ?
michael@0 1578 [0x0, 0x0C, 0x0, 0x0, 0x0]:
michael@0 1579 [0x0, 0x00, 0x0, 0x0, 0x0];
michael@0 1580
michael@0 1581 // Override some functions to test.
michael@0 1582 contactHelper.getContactFieldRecordId = function(pbr, contact, field, onsuccess, onerror) {
michael@0 1583 onsuccess(1);
michael@0 1584 };
michael@0 1585
michael@0 1586 record.readPBR = function readPBR(onsuccess, onerror) {
michael@0 1587 onsuccess([{adn:{fileId: 0x6f3a}, email: {}, anr0: {}}]);
michael@0 1588 };
michael@0 1589
michael@0 1590 record.readADNLike = function readADNLike(fileId, onsuccess, onerror) {
michael@0 1591 onsuccess([{recordId: 1, alphaId: "name", number: "111111"}])
michael@0 1592 };
michael@0 1593
michael@0 1594 record.readEmail = function readEmail(fileId, fileType, recordNumber, onsuccess, onerror) {
michael@0 1595 onsuccess("hello@mail.com");
michael@0 1596 };
michael@0 1597
michael@0 1598 record.readANR = function readANR(fileId, fileType, recordNumber, onsuccess, onerror) {
michael@0 1599 onsuccess("123456");
michael@0 1600 };
michael@0 1601
michael@0 1602 let onsuccess = function onsuccess(contacts) {
michael@0 1603 let contact = contacts[0];
michael@0 1604 for (let key in contact) {
michael@0 1605 do_print("check " + key);
michael@0 1606 if (Array.isArray(contact[key])) {
michael@0 1607 do_check_eq(contact[key][0], aExpectedContact[key]);
michael@0 1608 } else {
michael@0 1609 do_check_eq(contact[key], aExpectedContact[key]);
michael@0 1610 }
michael@0 1611 }
michael@0 1612 };
michael@0 1613
michael@0 1614 let onerror = function onerror(errorMsg) {
michael@0 1615 do_print("readICCContacts failed: " + errorMsg);
michael@0 1616 do_check_true(false);
michael@0 1617 };
michael@0 1618
michael@0 1619 contactHelper.readICCContacts(aSimType, aContactType, onsuccess, onerror);
michael@0 1620 }
michael@0 1621
michael@0 1622 let expectedContact1 = {
michael@0 1623 pbrIndex: 0,
michael@0 1624 recordId: 1,
michael@0 1625 alphaId: "name",
michael@0 1626 number: "111111"
michael@0 1627 };
michael@0 1628
michael@0 1629 let expectedContact2 = {
michael@0 1630 pbrIndex: 0,
michael@0 1631 recordId: 1,
michael@0 1632 alphaId: "name",
michael@0 1633 number: "111111",
michael@0 1634 email: "hello@mail.com",
michael@0 1635 anr: "123456"
michael@0 1636 };
michael@0 1637
michael@0 1638 // SIM
michael@0 1639 do_print("Test read SIM adn contacts");
michael@0 1640 do_test(CARD_APPTYPE_SIM, "adn", expectedContact1);
michael@0 1641
michael@0 1642 do_print("Test read SIM fdn contacts");
michael@0 1643 do_test(CARD_APPTYPE_SIM, "fdn", expectedContact1);
michael@0 1644
michael@0 1645 // USIM
michael@0 1646 do_print("Test read USIM adn contacts");
michael@0 1647 do_test(CARD_APPTYPE_USIM, "adn", expectedContact2);
michael@0 1648
michael@0 1649 do_print("Test read USIM fdn contacts");
michael@0 1650 do_test(CARD_APPTYPE_USIM, "fdn", expectedContact1);
michael@0 1651
michael@0 1652 // RUIM
michael@0 1653 do_print("Test read RUIM adn contacts");
michael@0 1654 do_test(CARD_APPTYPE_RUIM, "adn", expectedContact1);
michael@0 1655
michael@0 1656 do_print("Test read RUIM fdn contacts");
michael@0 1657 do_test(CARD_APPTYPE_RUIM, "fdn", expectedContact1);
michael@0 1658
michael@0 1659 // RUIM with enhanced phone book
michael@0 1660 do_print("Test read RUIM adn contacts with enhanced phone book");
michael@0 1661 do_test(CARD_APPTYPE_RUIM, "adn", expectedContact2, true);
michael@0 1662
michael@0 1663 do_print("Test read RUIM fdn contacts with enhanced phone book");
michael@0 1664 do_test(CARD_APPTYPE_RUIM, "fdn", expectedContact1, true);
michael@0 1665
michael@0 1666 run_next_test();
michael@0 1667 });
michael@0 1668
michael@0 1669 /**
michael@0 1670 * Verify ICCContactHelper.updateICCContact with appType is CARD_APPTYPE_USIM.
michael@0 1671 */
michael@0 1672 add_test(function test_update_icc_contact() {
michael@0 1673 const ADN_RECORD_ID = 100;
michael@0 1674 const ADN_SFI = 1;
michael@0 1675 const IAP_FILE_ID = 0x4f17;
michael@0 1676 const EMAIL_FILE_ID = 0x4f50;
michael@0 1677 const EMAIL_RECORD_ID = 20;
michael@0 1678 const ANR0_FILE_ID = 0x4f11;
michael@0 1679 const ANR0_RECORD_ID = 30;
michael@0 1680
michael@0 1681 let worker = newUint8Worker();
michael@0 1682 let context = worker.ContextPool._contexts[0];
michael@0 1683 let recordHelper = context.ICCRecordHelper;
michael@0 1684 let contactHelper = context.ICCContactHelper;
michael@0 1685 let ril = context.RIL;
michael@0 1686
michael@0 1687 function do_test(aSimType, aContactType, aContact, aPin2, aFileType, aHaveIapIndex, aEnhancedPhoneBook) {
michael@0 1688 ril.appType = aSimType;
michael@0 1689 ril._isCdma = (aSimType === CARD_APPTYPE_RUIM);
michael@0 1690 ril.iccInfoPrivate.cst = (aEnhancedPhoneBook) ? [0x0, 0x0C, 0x0, 0x0, 0x0]
michael@0 1691 : [0x0, 0x00, 0x0, 0x0, 0x0];
michael@0 1692
michael@0 1693 recordHelper.readPBR = function(onsuccess, onerror) {
michael@0 1694 if (aFileType === ICC_USIM_TYPE1_TAG) {
michael@0 1695 onsuccess([{
michael@0 1696 adn: {fileId: ICC_EF_ADN},
michael@0 1697 email: {fileId: EMAIL_FILE_ID,
michael@0 1698 fileType: ICC_USIM_TYPE1_TAG},
michael@0 1699 anr0: {fileId: ANR0_FILE_ID,
michael@0 1700 fileType: ICC_USIM_TYPE1_TAG}
michael@0 1701 }]);
michael@0 1702 } else if (aFileType === ICC_USIM_TYPE2_TAG) {
michael@0 1703 onsuccess([{
michael@0 1704 adn: {fileId: ICC_EF_ADN,
michael@0 1705 sfi: ADN_SFI},
michael@0 1706 iap: {fileId: IAP_FILE_ID},
michael@0 1707 email: {fileId: EMAIL_FILE_ID,
michael@0 1708 fileType: ICC_USIM_TYPE2_TAG,
michael@0 1709 indexInIAP: 0},
michael@0 1710 anr0: {fileId: ANR0_FILE_ID,
michael@0 1711 fileType: ICC_USIM_TYPE2_TAG,
michael@0 1712 indexInIAP: 1}
michael@0 1713 }]);
michael@0 1714 }
michael@0 1715 };
michael@0 1716
michael@0 1717 recordHelper.updateADNLike = function(fileId, contact, pin2, onsuccess, onerror) {
michael@0 1718 if (aContactType === "fdn") {
michael@0 1719 do_check_eq(fileId, ICC_EF_FDN);
michael@0 1720 } else if (aContactType === "adn") {
michael@0 1721 do_check_eq(fileId, ICC_EF_ADN);
michael@0 1722 }
michael@0 1723 do_check_eq(pin2, aPin2);
michael@0 1724 do_check_eq(contact.alphaId, aContact.alphaId);
michael@0 1725 do_check_eq(contact.number, aContact.number);
michael@0 1726 onsuccess();
michael@0 1727 };
michael@0 1728
michael@0 1729 recordHelper.readIAP = function(fileId, recordNumber, onsuccess, onerror) {
michael@0 1730 do_check_eq(fileId, IAP_FILE_ID);
michael@0 1731 do_check_eq(recordNumber, ADN_RECORD_ID);
michael@0 1732 onsuccess((aHaveIapIndex) ? [EMAIL_RECORD_ID, ANR0_RECORD_ID]
michael@0 1733 : [0xff, 0xff]);
michael@0 1734 };
michael@0 1735
michael@0 1736 recordHelper.updateIAP = function(fileId, recordNumber, iap, onsuccess, onerror) {
michael@0 1737 do_check_eq(fileId, IAP_FILE_ID);
michael@0 1738 do_check_eq(recordNumber, ADN_RECORD_ID);
michael@0 1739 onsuccess();
michael@0 1740 };
michael@0 1741
michael@0 1742 recordHelper.updateEmail = function(pbr, recordNumber, email, adnRecordId, onsuccess, onerror) {
michael@0 1743 do_check_eq(pbr.email.fileId, EMAIL_FILE_ID);
michael@0 1744 if (pbr.email.fileType === ICC_USIM_TYPE1_TAG) {
michael@0 1745 do_check_eq(recordNumber, ADN_RECORD_ID);
michael@0 1746 } else if (pbr.email.fileType === ICC_USIM_TYPE2_TAG) {
michael@0 1747 do_check_eq(recordNumber, EMAIL_RECORD_ID);
michael@0 1748 }
michael@0 1749 do_check_eq(email, aContact.email);
michael@0 1750 onsuccess();
michael@0 1751 };
michael@0 1752
michael@0 1753 recordHelper.updateANR = function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) {
michael@0 1754 do_check_eq(pbr.anr0.fileId, ANR0_FILE_ID);
michael@0 1755 if (pbr.anr0.fileType === ICC_USIM_TYPE1_TAG) {
michael@0 1756 do_check_eq(recordNumber, ADN_RECORD_ID);
michael@0 1757 } else if (pbr.anr0.fileType === ICC_USIM_TYPE2_TAG) {
michael@0 1758 do_check_eq(recordNumber, ANR0_RECORD_ID);
michael@0 1759 }
michael@0 1760 if (Array.isArray(aContact.anr)) {
michael@0 1761 do_check_eq(number, aContact.anr[0]);
michael@0 1762 }
michael@0 1763 onsuccess();
michael@0 1764 };
michael@0 1765
michael@0 1766 recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) {
michael@0 1767 let recordId = 0;
michael@0 1768 if (fileId === EMAIL_FILE_ID) {
michael@0 1769 recordId = EMAIL_RECORD_ID;
michael@0 1770 } else if (fileId === ANR0_FILE_ID) {
michael@0 1771 recordId = ANR0_RECORD_ID;
michael@0 1772 }
michael@0 1773 onsuccess(recordId);
michael@0 1774 };
michael@0 1775
michael@0 1776 let isSuccess = false;
michael@0 1777 let onsuccess = function onsuccess() {
michael@0 1778 do_print("updateICCContact success");
michael@0 1779 isSuccess = true;
michael@0 1780 };
michael@0 1781
michael@0 1782 let onerror = function onerror(errorMsg) {
michael@0 1783 do_print("updateICCContact failed: " + errorMsg);
michael@0 1784 };
michael@0 1785
michael@0 1786 contactHelper.updateICCContact(aSimType, aContactType, aContact, aPin2, onsuccess, onerror);
michael@0 1787 do_check_true(isSuccess);
michael@0 1788 }
michael@0 1789
michael@0 1790 let contacts = [
michael@0 1791 {
michael@0 1792 pbrIndex: 0,
michael@0 1793 recordId: ADN_RECORD_ID,
michael@0 1794 alphaId: "test",
michael@0 1795 number: "123456",
michael@0 1796 email: "test@mail.com",
michael@0 1797 anr: ["+654321"]
michael@0 1798 },
michael@0 1799 // a contact without email and anr.
michael@0 1800 {
michael@0 1801 pbrIndex: 0,
michael@0 1802 recordId: ADN_RECORD_ID,
michael@0 1803 alphaId: "test2",
michael@0 1804 number: "123456",
michael@0 1805 },
michael@0 1806 // a contact with email but no anr.
michael@0 1807 {
michael@0 1808 pbrIndex: 0,
michael@0 1809 recordId: ADN_RECORD_ID,
michael@0 1810 alphaId: "test3",
michael@0 1811 number: "123456",
michael@0 1812 email: "test@mail.com"
michael@0 1813 },
michael@0 1814 // a contact with anr but no email.
michael@0 1815 {
michael@0 1816 pbrIndex: 0,
michael@0 1817 recordId: ADN_RECORD_ID,
michael@0 1818 alphaId: "test4",
michael@0 1819 number: "123456",
michael@0 1820 anr: ["+654321"]
michael@0 1821 }];
michael@0 1822
michael@0 1823 for (let i = 0; i < contacts.length; i++) {
michael@0 1824 let contact = contacts[i];
michael@0 1825 // SIM
michael@0 1826 do_print("Test update SIM adn contacts");
michael@0 1827 do_test(CARD_APPTYPE_SIM, "adn", contact);
michael@0 1828
michael@0 1829 do_print("Test update SIM fdn contacts");
michael@0 1830 do_test(CARD_APPTYPE_SIM, "fdn", contact, "1234");
michael@0 1831
michael@0 1832 // USIM
michael@0 1833 do_print("Test update USIM adn contacts");
michael@0 1834 do_test(CARD_APPTYPE_USIM, "adn", contact, null, ICC_USIM_TYPE1_TAG);
michael@0 1835 do_test(CARD_APPTYPE_USIM, "adn", contact, null, ICC_USIM_TYPE2_TAG, true);
michael@0 1836 do_test(CARD_APPTYPE_USIM, "adn", contact, null, ICC_USIM_TYPE2_TAG, false);
michael@0 1837
michael@0 1838 do_print("Test update USIM fdn contacts");
michael@0 1839 do_test(CARD_APPTYPE_USIM, "fdn", contact, "1234");
michael@0 1840
michael@0 1841 // RUIM
michael@0 1842 do_print("Test update RUIM adn contacts");
michael@0 1843 do_test(CARD_APPTYPE_RUIM, "adn", contact);
michael@0 1844
michael@0 1845 do_print("Test update RUIM fdn contacts");
michael@0 1846 do_test(CARD_APPTYPE_RUIM, "fdn", contact, "1234");
michael@0 1847
michael@0 1848 // RUIM with enhanced phone book
michael@0 1849 do_print("Test update RUIM adn contacts with enhanced phone book");
michael@0 1850 do_test(CARD_APPTYPE_RUIM, "adn", contact, null, ICC_USIM_TYPE1_TAG, null, true);
michael@0 1851 do_test(CARD_APPTYPE_RUIM, "adn", contact, null, ICC_USIM_TYPE2_TAG, true, true);
michael@0 1852 do_test(CARD_APPTYPE_RUIM, "adn", contact, null, ICC_USIM_TYPE2_TAG, false, true);
michael@0 1853
michael@0 1854 do_print("Test update RUIM fdn contacts with enhanced phone book");
michael@0 1855 do_test(CARD_APPTYPE_RUIM, "fdn", contact, "1234", null, true);
michael@0 1856 }
michael@0 1857
michael@0 1858 run_next_test();
michael@0 1859 });
michael@0 1860
michael@0 1861 /**
michael@0 1862 * Verify updateICCContact with removal of anr and email with File Type 1.
michael@0 1863 */
michael@0 1864 add_test(function test_update_icc_contact_with_remove_type1_attr() {
michael@0 1865 const ADN_RECORD_ID = 100;
michael@0 1866 const IAP_FILE_ID = 0x4f17;
michael@0 1867 const EMAIL_FILE_ID = 0x4f50;
michael@0 1868 const EMAIL_RECORD_ID = 20;
michael@0 1869 const ANR0_FILE_ID = 0x4f11;
michael@0 1870 const ANR0_RECORD_ID = 30;
michael@0 1871
michael@0 1872 let worker = newUint8Worker();
michael@0 1873 let context = worker.ContextPool._contexts[0];
michael@0 1874 let recordHelper = context.ICCRecordHelper;
michael@0 1875 let contactHelper = context.ICCContactHelper;
michael@0 1876
michael@0 1877 recordHelper.updateADNLike = function(fileId, contact, pin2, onsuccess, onerror) {
michael@0 1878 onsuccess();
michael@0 1879 };
michael@0 1880
michael@0 1881 let contact = {
michael@0 1882 pbrIndex: 0,
michael@0 1883 recordId: ADN_RECORD_ID,
michael@0 1884 alphaId: "test2",
michael@0 1885 number: "123456",
michael@0 1886 };
michael@0 1887
michael@0 1888 recordHelper.readIAP = function(fileId, recordNumber, onsuccess, onerror) {
michael@0 1889 onsuccess([EMAIL_RECORD_ID, ANR0_RECORD_ID]);
michael@0 1890 };
michael@0 1891
michael@0 1892 recordHelper.updateEmail = function(pbr, recordNumber, email, adnRecordId, onsuccess, onerror) {
michael@0 1893 do_check_true(email == null);
michael@0 1894 onsuccess();
michael@0 1895 };
michael@0 1896
michael@0 1897 recordHelper.updateANR = function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) {
michael@0 1898 do_check_true(number == null);
michael@0 1899 onsuccess();
michael@0 1900 };
michael@0 1901
michael@0 1902 function do_test(type) {
michael@0 1903 recordHelper.readPBR = function(onsuccess, onerror) {
michael@0 1904 if (type == ICC_USIM_TYPE1_TAG) {
michael@0 1905 onsuccess([{
michael@0 1906 adn: {fileId: ICC_EF_ADN},
michael@0 1907 email: {fileId: EMAIL_FILE_ID,
michael@0 1908 fileType: ICC_USIM_TYPE1_TAG},
michael@0 1909 anr0: {fileId: ANR0_FILE_ID,
michael@0 1910 fileType: ICC_USIM_TYPE1_TAG}}]);
michael@0 1911 } else {
michael@0 1912 onsuccess([{
michael@0 1913 adn: {fileId: ICC_EF_ADN},
michael@0 1914 iap: {fileId: IAP_FILE_ID},
michael@0 1915 email: {fileId: EMAIL_FILE_ID,
michael@0 1916 fileType: ICC_USIM_TYPE2_TAG,
michael@0 1917 indexInIAP: 0},
michael@0 1918 anr0: {fileId: ANR0_FILE_ID,
michael@0 1919 fileType: ICC_USIM_TYPE2_TAG,
michael@0 1920 indexInIAP: 1}}]);
michael@0 1921 }
michael@0 1922 };
michael@0 1923
michael@0 1924 let successCb = function() {
michael@0 1925 do_check_true(true);
michael@0 1926 };
michael@0 1927
michael@0 1928 let errorCb = function(errorMsg) {
michael@0 1929 do_print(errorMsg);
michael@0 1930 do_check_true(false);
michael@0 1931 };
michael@0 1932
michael@0 1933 contactHelper.updateICCContact(CARD_APPTYPE_USIM, "adn", contact, null, successCb, errorCb);
michael@0 1934 }
michael@0 1935
michael@0 1936 do_test(ICC_USIM_TYPE1_TAG);
michael@0 1937 do_test(ICC_USIM_TYPE2_TAG);
michael@0 1938
michael@0 1939 run_next_test();
michael@0 1940 });
michael@0 1941
michael@0 1942 /**
michael@0 1943 * Verify ICCContactHelper.findFreeICCContact in SIM
michael@0 1944 */
michael@0 1945 add_test(function test_find_free_icc_contact_sim() {
michael@0 1946 let worker = newUint8Worker();
michael@0 1947 let context = worker.ContextPool._contexts[0];
michael@0 1948 let recordHelper = context.ICCRecordHelper;
michael@0 1949 let contactHelper = context.ICCContactHelper;
michael@0 1950 // Correct record Id starts with 1, so put a null element at index 0.
michael@0 1951 let records = [null];
michael@0 1952 const MAX_RECORDS = 3;
michael@0 1953 const PBR_INDEX = 0;
michael@0 1954
michael@0 1955 recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) {
michael@0 1956 if (records.length > MAX_RECORDS) {
michael@0 1957 onerror("No free record found.");
michael@0 1958 return;
michael@0 1959 }
michael@0 1960
michael@0 1961 onsuccess(records.length);
michael@0 1962 };
michael@0 1963
michael@0 1964 let successCb = function(pbrIndex, recordId) {
michael@0 1965 do_check_eq(pbrIndex, PBR_INDEX);
michael@0 1966 records[recordId] = {};
michael@0 1967 };
michael@0 1968
michael@0 1969 let errorCb = function(errorMsg) {
michael@0 1970 do_print(errorMsg);
michael@0 1971 do_check_true(false);
michael@0 1972 };
michael@0 1973
michael@0 1974 for (let i = 0; i < MAX_RECORDS; i++) {
michael@0 1975 contactHelper.findFreeICCContact(CARD_APPTYPE_SIM, "adn", successCb, errorCb);
michael@0 1976 }
michael@0 1977 // The 1st element, records[0], is null.
michael@0 1978 do_check_eq(records.length - 1, MAX_RECORDS);
michael@0 1979
michael@0 1980 // Now the EF is full, so finding a free one should result failure.
michael@0 1981 successCb = function(pbrIndex, recordId) {
michael@0 1982 do_check_true(false);
michael@0 1983 };
michael@0 1984
michael@0 1985 errorCb = function(errorMsg) {
michael@0 1986 do_check_true(errorMsg === "No free record found.");
michael@0 1987 };
michael@0 1988 contactHelper.findFreeICCContact(CARD_APPTYPE_SIM, "adn", successCb, errorCb);
michael@0 1989
michael@0 1990 run_next_test();
michael@0 1991 });
michael@0 1992
michael@0 1993 /**
michael@0 1994 * Verify ICCContactHelper.findFreeICCContact in USIM
michael@0 1995 */
michael@0 1996 add_test(function test_find_free_icc_contact_usim() {
michael@0 1997 let worker = newUint8Worker();
michael@0 1998 let context = worker.ContextPool._contexts[0];
michael@0 1999 let recordHelper = context.ICCRecordHelper;
michael@0 2000 let contactHelper = context.ICCContactHelper;
michael@0 2001 const ADN1_FILE_ID = 0x6f3a;
michael@0 2002 const ADN2_FILE_ID = 0x6f3b;
michael@0 2003 const MAX_RECORDS = 3;
michael@0 2004
michael@0 2005 // The adn in the first phonebook set has already two records, which means
michael@0 2006 // only 1 free record remained.
michael@0 2007 let pbrs = [{adn: {fileId: ADN1_FILE_ID, records: [null, {}, {}]}},
michael@0 2008 {adn: {fileId: ADN2_FILE_ID, records: [null]}}];
michael@0 2009
michael@0 2010 recordHelper.readPBR = function readPBR(onsuccess, onerror) {
michael@0 2011 onsuccess(pbrs);
michael@0 2012 };
michael@0 2013
michael@0 2014 recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) {
michael@0 2015 let pbr = (fileId == ADN1_FILE_ID ? pbrs[0]: pbrs[1]);
michael@0 2016 if (pbr.adn.records.length > MAX_RECORDS) {
michael@0 2017 onerror("No free record found.");
michael@0 2018 return;
michael@0 2019 }
michael@0 2020
michael@0 2021 onsuccess(pbr.adn.records.length);
michael@0 2022 };
michael@0 2023
michael@0 2024 let successCb = function(pbrIndex, recordId) {
michael@0 2025 do_check_eq(pbrIndex, 0);
michael@0 2026 pbrs[pbrIndex].adn.records[recordId] = {};
michael@0 2027 };
michael@0 2028
michael@0 2029 let errorCb = function(errorMsg) {
michael@0 2030 do_check_true(false);
michael@0 2031 };
michael@0 2032
michael@0 2033 contactHelper.findFreeICCContact(CARD_APPTYPE_USIM, "adn", successCb, errorCb);
michael@0 2034
michael@0 2035 // Now the EF_ADN in the 1st phonebook set is full, so the next free contact
michael@0 2036 // will come from the 2nd phonebook set.
michael@0 2037 successCb = function(pbrIndex, recordId) {
michael@0 2038 do_check_eq(pbrIndex, 1);
michael@0 2039 do_check_eq(recordId, 1);
michael@0 2040 }
michael@0 2041 contactHelper.findFreeICCContact(CARD_APPTYPE_USIM, "adn", successCb, errorCb);
michael@0 2042
michael@0 2043 run_next_test();
michael@0 2044 });
michael@0 2045
michael@0 2046 /**
michael@0 2047 * Test error message returned in onerror for readICCContacts.
michael@0 2048 */
michael@0 2049 add_test(function test_error_message_read_icc_contact () {
michael@0 2050 let worker = newUint8Worker();
michael@0 2051 let context = worker.ContextPool._contexts[0];
michael@0 2052 let ril = context.RIL;
michael@0 2053
michael@0 2054 function do_test(options, expectedErrorMsg) {
michael@0 2055 ril.sendChromeMessage = function(message) {
michael@0 2056 do_check_eq(message.errorMsg, expectedErrorMsg);
michael@0 2057 }
michael@0 2058 ril.readICCContacts(options);
michael@0 2059 }
michael@0 2060
michael@0 2061 // Error 1, didn't specify correct contactType.
michael@0 2062 do_test({}, CONTACT_ERR_REQUEST_NOT_SUPPORTED);
michael@0 2063
michael@0 2064 // Error 2, specifying a non-supported contactType.
michael@0 2065 ril.appType = CARD_APPTYPE_USIM;
michael@0 2066 do_test({contactType: "sdn"}, CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
michael@0 2067
michael@0 2068 // Error 3, suppose we update the supported PBR fields in USIM_PBR_FIELDS,
michael@0 2069 // but forget to add implemenetations for it.
michael@0 2070 USIM_PBR_FIELDS.push("pbc");
michael@0 2071 do_test({contactType: "adn"}, CONTACT_ERR_FIELD_NOT_SUPPORTED);
michael@0 2072
michael@0 2073 run_next_test();
michael@0 2074 });
michael@0 2075
michael@0 2076 /**
michael@0 2077 * Test error message returned in onerror for updateICCContact.
michael@0 2078 */
michael@0 2079 add_test(function test_error_message_update_icc_contact() {
michael@0 2080 let worker = newUint8Worker();
michael@0 2081 let context = worker.ContextPool._contexts[0];
michael@0 2082 let ril = context.RIL;
michael@0 2083
michael@0 2084 const ICCID = "123456789";
michael@0 2085 ril.iccInfo.iccid = ICCID;
michael@0 2086
michael@0 2087 function do_test(options, expectedErrorMsg) {
michael@0 2088 ril.sendChromeMessage = function(message) {
michael@0 2089 do_check_eq(message.errorMsg, expectedErrorMsg);
michael@0 2090 }
michael@0 2091 ril.updateICCContact(options);
michael@0 2092 }
michael@0 2093
michael@0 2094 // Error 1, didn't specify correct contactType.
michael@0 2095 do_test({}, CONTACT_ERR_REQUEST_NOT_SUPPORTED);
michael@0 2096
michael@0 2097 // Error 2, specifying a correct contactType, but without providing 'contact'.
michael@0 2098 do_test({contactType: "adn"}, CONTACT_ERR_REQUEST_NOT_SUPPORTED);
michael@0 2099
michael@0 2100 // Error 3, specifying a non-supported contactType.
michael@0 2101 ril.appType = CARD_APPTYPE_USIM;
michael@0 2102 do_test({contactType: "sdn", contact: {}}, CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
michael@0 2103
michael@0 2104 // Error 4, without supplying pin2.
michael@0 2105 do_test({contactType: "fdn", contact: {contactId: ICCID + "1"}}, GECKO_ERROR_SIM_PIN2);
michael@0 2106
michael@0 2107 // Error 5, No free record found in EF_ADN.
michael@0 2108 let record = context.ICCRecordHelper;
michael@0 2109 record.readPBR = function(onsuccess, onerror) {
michael@0 2110 onsuccess([{adn: {fileId: 0x4f3a}}]);
michael@0 2111 };
michael@0 2112
michael@0 2113 let io = context.ICCIOHelper;
michael@0 2114 io.loadLinearFixedEF = function(options) {
michael@0 2115 options.totalRecords = 1;
michael@0 2116 options.p1 = 1;
michael@0 2117 options.callback(options);
michael@0 2118 };
michael@0 2119
michael@0 2120 do_test({contactType: "adn", contact: {}}, CONTACT_ERR_NO_FREE_RECORD_FOUND);
michael@0 2121
michael@0 2122 // Error 6, ICC IO Error.
michael@0 2123 io.loadLinearFixedEF = function(options) {
michael@0 2124 ril[REQUEST_SIM_IO](0, {rilRequestError: ERROR_GENERIC_FAILURE});
michael@0 2125 };
michael@0 2126 do_test({contactType: "adn", contact: {contactId: ICCID + "1"}},
michael@0 2127 GECKO_ERROR_GENERIC_FAILURE);
michael@0 2128
michael@0 2129 // Error 7, suppose we update the supported PBR fields in USIM_PBR_FIELDS,
michael@0 2130 // but forget to add implemenetations for it.
michael@0 2131 USIM_PBR_FIELDS.push("pbc");
michael@0 2132 do_test({contactType: "adn", contact: {contactId: ICCID + "1"}},
michael@0 2133 CONTACT_ERR_FIELD_NOT_SUPPORTED);
michael@0 2134
michael@0 2135 // Error 8, EF_PBR doesn't exist.
michael@0 2136 record.readPBR = function(onsuccess, onerror) {
michael@0 2137 onsuccess([]);
michael@0 2138 };
michael@0 2139
michael@0 2140 do_test({contactType: "adn", contact: {contactId: ICCID + "1"}},
michael@0 2141 CONTACT_ERR_CANNOT_ACCESS_PHONEBOOK);
michael@0 2142
michael@0 2143 run_next_test();
michael@0 2144 });
michael@0 2145
michael@0 2146 add_test(function test_process_icc_io_error() {
michael@0 2147 let worker = newUint8Worker();
michael@0 2148 let context = worker.ContextPool._contexts[0];
michael@0 2149 let ioHelper = context.ICCIOHelper;
michael@0 2150
michael@0 2151 function do_test(errorCode, expectedErrorMsg) {
michael@0 2152 let called = false;
michael@0 2153 function errorCb(errorMsg) {
michael@0 2154 called = true;
michael@0 2155 do_check_eq(errorMsg, expectedErrorMsg);
michael@0 2156 }
michael@0 2157
michael@0 2158 ioHelper.processICCIOError({rilRequestError: errorCode,
michael@0 2159 fileId: 0xffff,
michael@0 2160 command: 0xff,
michael@0 2161 sw1: 0xff,
michael@0 2162 sw2: 0xff,
michael@0 2163 onerror: errorCb});
michael@0 2164 do_check_true(called);
michael@0 2165 }
michael@0 2166
michael@0 2167 for (let i = 0; i < ERROR_REJECTED_BY_REMOTE + 1; i++) {
michael@0 2168 do_test(i, RIL_ERROR_TO_GECKO_ERROR[i]);
michael@0 2169 }
michael@0 2170
michael@0 2171 run_next_test();
michael@0 2172 });
michael@0 2173
michael@0 2174 add_test(function test_personalization_state() {
michael@0 2175 let worker = newUint8Worker();
michael@0 2176 let context = worker.ContextPool._contexts[0];
michael@0 2177 let ril = context.RIL;
michael@0 2178
michael@0 2179 context.ICCRecordHelper.readICCID = function fakeReadICCID() {};
michael@0 2180
michael@0 2181 function testPersonalization(isCdma, cardPersoState, geckoCardState) {
michael@0 2182 let iccStatus = {
michael@0 2183 cardState: CARD_STATE_PRESENT,
michael@0 2184 gsmUmtsSubscriptionAppIndex: (!isCdma) ? 0 : -1,
michael@0 2185 cdmaSubscriptionAppIndex: (isCdma) ? 0 : -1,
michael@0 2186 apps: [
michael@0 2187 {
michael@0 2188 app_state: CARD_APPSTATE_SUBSCRIPTION_PERSO,
michael@0 2189 perso_substate: cardPersoState
michael@0 2190 }],
michael@0 2191 };
michael@0 2192
michael@0 2193 ril._isCdma = isCdma;
michael@0 2194 ril._processICCStatus(iccStatus);
michael@0 2195 do_check_eq(ril.cardState, geckoCardState);
michael@0 2196 }
michael@0 2197
michael@0 2198 // Test GSM personalization state.
michael@0 2199 testPersonalization(false, CARD_PERSOSUBSTATE_SIM_NETWORK,
michael@0 2200 GECKO_CARDSTATE_NETWORK_LOCKED);
michael@0 2201 testPersonalization(false, CARD_PERSOSUBSTATE_SIM_CORPORATE,
michael@0 2202 GECKO_CARDSTATE_CORPORATE_LOCKED);
michael@0 2203 testPersonalization(false, CARD_PERSOSUBSTATE_SIM_SERVICE_PROVIDER,
michael@0 2204 GECKO_CARDSTATE_SERVICE_PROVIDER_LOCKED);
michael@0 2205 testPersonalization(false, CARD_PERSOSUBSTATE_SIM_NETWORK_PUK,
michael@0 2206 GECKO_CARDSTATE_NETWORK_PUK_REQUIRED);
michael@0 2207 testPersonalization(false, CARD_PERSOSUBSTATE_SIM_CORPORATE_PUK,
michael@0 2208 GECKO_CARDSTATE_CORPORATE_PUK_REQUIRED);
michael@0 2209 testPersonalization(false, CARD_PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK,
michael@0 2210 GECKO_CARDSTATE_SERVICE_PROVIDER_PUK_REQUIRED);
michael@0 2211 testPersonalization(false, CARD_PERSOSUBSTATE_READY,
michael@0 2212 GECKO_CARDSTATE_PERSONALIZATION_READY);
michael@0 2213
michael@0 2214 // Test CDMA personalization state.
michael@0 2215 testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK1,
michael@0 2216 GECKO_CARDSTATE_NETWORK1_LOCKED);
michael@0 2217 testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK2,
michael@0 2218 GECKO_CARDSTATE_NETWORK2_LOCKED);
michael@0 2219 testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_HRPD,
michael@0 2220 GECKO_CARDSTATE_HRPD_NETWORK_LOCKED);
michael@0 2221 testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_CORPORATE,
michael@0 2222 GECKO_CARDSTATE_RUIM_CORPORATE_LOCKED);
michael@0 2223 testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER,
michael@0 2224 GECKO_CARDSTATE_RUIM_SERVICE_PROVIDER_LOCKED);
michael@0 2225 testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_RUIM,
michael@0 2226 GECKO_CARDSTATE_RUIM_LOCKED);
michael@0 2227 testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK1_PUK,
michael@0 2228 GECKO_CARDSTATE_NETWORK1_PUK_REQUIRED);
michael@0 2229 testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK2_PUK,
michael@0 2230 GECKO_CARDSTATE_NETWORK2_PUK_REQUIRED);
michael@0 2231 testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_HRPD_PUK,
michael@0 2232 GECKO_CARDSTATE_HRPD_NETWORK_PUK_REQUIRED);
michael@0 2233 testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_CORPORATE_PUK,
michael@0 2234 GECKO_CARDSTATE_RUIM_CORPORATE_PUK_REQUIRED);
michael@0 2235 testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK,
michael@0 2236 GECKO_CARDSTATE_RUIM_SERVICE_PROVIDER_PUK_REQUIRED);
michael@0 2237 testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_RUIM_PUK,
michael@0 2238 GECKO_CARDSTATE_RUIM_PUK_REQUIRED);
michael@0 2239
michael@0 2240 run_next_test();
michael@0 2241 });
michael@0 2242
michael@0 2243 /**
michael@0 2244 * Verify SIM app_state in _processICCStatus
michael@0 2245 */
michael@0 2246 add_test(function test_card_app_state() {
michael@0 2247 let worker = newUint8Worker();
michael@0 2248 let context = worker.ContextPool._contexts[0];
michael@0 2249 let ril = context.RIL;
michael@0 2250
michael@0 2251 context.ICCRecordHelper.readICCID = function fakeReadICCID() {};
michael@0 2252
michael@0 2253 function testCardAppState(cardAppState, geckoCardState) {
michael@0 2254 let iccStatus = {
michael@0 2255 cardState: CARD_STATE_PRESENT,
michael@0 2256 gsmUmtsSubscriptionAppIndex: 0,
michael@0 2257 apps: [
michael@0 2258 {
michael@0 2259 app_state: cardAppState
michael@0 2260 }],
michael@0 2261 };
michael@0 2262
michael@0 2263 ril._processICCStatus(iccStatus);
michael@0 2264 do_check_eq(ril.cardState, geckoCardState);
michael@0 2265 }
michael@0 2266
michael@0 2267 testCardAppState(CARD_APPSTATE_ILLEGAL,
michael@0 2268 GECKO_CARDSTATE_ILLEGAL);
michael@0 2269 testCardAppState(CARD_APPSTATE_PIN,
michael@0 2270 GECKO_CARDSTATE_PIN_REQUIRED);
michael@0 2271 testCardAppState(CARD_APPSTATE_PUK,
michael@0 2272 GECKO_CARDSTATE_PUK_REQUIRED);
michael@0 2273 testCardAppState(CARD_APPSTATE_READY,
michael@0 2274 GECKO_CARDSTATE_READY);
michael@0 2275 testCardAppState(CARD_APPSTATE_UNKNOWN,
michael@0 2276 GECKO_CARDSTATE_UNKNOWN);
michael@0 2277 testCardAppState(CARD_APPSTATE_DETECTED,
michael@0 2278 GECKO_CARDSTATE_UNKNOWN);
michael@0 2279
michael@0 2280 run_next_test();
michael@0 2281 });
michael@0 2282
michael@0 2283 /**
michael@0 2284 * Verify permanent blocked for ICC.
michael@0 2285 */
michael@0 2286 add_test(function test_icc_permanent_blocked() {
michael@0 2287 let worker = newUint8Worker();
michael@0 2288 let context = worker.ContextPool._contexts[0];
michael@0 2289 let ril = context.RIL;
michael@0 2290
michael@0 2291 context.ICCRecordHelper.readICCID = function fakeReadICCID() {};
michael@0 2292
michael@0 2293 function testPermanentBlocked(pin1_replaced, universalPINState, pin1) {
michael@0 2294 let iccStatus = {
michael@0 2295 cardState: CARD_STATE_PRESENT,
michael@0 2296 gsmUmtsSubscriptionAppIndex: 0,
michael@0 2297 universalPINState: universalPINState,
michael@0 2298 apps: [
michael@0 2299 {
michael@0 2300 pin1_replaced: pin1_replaced,
michael@0 2301 pin1: pin1
michael@0 2302 }]
michael@0 2303 };
michael@0 2304
michael@0 2305 ril._processICCStatus(iccStatus);
michael@0 2306 do_check_eq(ril.cardState, GECKO_CARDSTATE_PERMANENT_BLOCKED);
michael@0 2307 }
michael@0 2308
michael@0 2309 testPermanentBlocked(1,
michael@0 2310 CARD_PINSTATE_ENABLED_PERM_BLOCKED,
michael@0 2311 CARD_PINSTATE_UNKNOWN);
michael@0 2312 testPermanentBlocked(1,
michael@0 2313 CARD_PINSTATE_ENABLED_PERM_BLOCKED,
michael@0 2314 CARD_PINSTATE_ENABLED_PERM_BLOCKED);
michael@0 2315 testPermanentBlocked(0,
michael@0 2316 CARD_PINSTATE_UNKNOWN,
michael@0 2317 CARD_PINSTATE_ENABLED_PERM_BLOCKED);
michael@0 2318
michael@0 2319 run_next_test();
michael@0 2320 });
michael@0 2321
michael@0 2322 /**
michael@0 2323 * Verify iccSetCardLock - Facility Lock.
michael@0 2324 */
michael@0 2325 add_test(function test_set_icc_card_lock_facility_lock() {
michael@0 2326 let worker = newUint8Worker();
michael@0 2327 let context = worker.ContextPool._contexts[0];
michael@0 2328 let aid = "123456789";
michael@0 2329 let ril = context.RIL;
michael@0 2330 ril.aid = aid;
michael@0 2331 ril.v5Legacy = false;
michael@0 2332 let buf = context.Buf;
michael@0 2333
michael@0 2334 let GECKO_CARDLOCK_TO_FACILITIY_LOCK = {};
michael@0 2335 GECKO_CARDLOCK_TO_FACILITIY_LOCK[GECKO_CARDLOCK_PIN] = ICC_CB_FACILITY_SIM;
michael@0 2336 GECKO_CARDLOCK_TO_FACILITIY_LOCK[GECKO_CARDLOCK_FDN] = ICC_CB_FACILITY_FDN;
michael@0 2337
michael@0 2338 let GECKO_CARDLOCK_TO_PASSWORD_TYPE = {};
michael@0 2339 GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_PIN] = "pin";
michael@0 2340 GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_FDN] = "pin2";
michael@0 2341
michael@0 2342 const pin = "1234";
michael@0 2343 const pin2 = "4321";
michael@0 2344 let GECKO_CARDLOCK_TO_PASSWORD = {};
michael@0 2345 GECKO_CARDLOCK_TO_PASSWORD[GECKO_CARDLOCK_PIN] = pin;
michael@0 2346 GECKO_CARDLOCK_TO_PASSWORD[GECKO_CARDLOCK_FDN] = pin2;
michael@0 2347
michael@0 2348 const serviceClass = ICC_SERVICE_CLASS_VOICE |
michael@0 2349 ICC_SERVICE_CLASS_DATA |
michael@0 2350 ICC_SERVICE_CLASS_FAX;
michael@0 2351
michael@0 2352 function do_test(aLock, aPassword, aEnabled) {
michael@0 2353 buf.sendParcel = function fakeSendParcel () {
michael@0 2354 // Request Type.
michael@0 2355 do_check_eq(this.readInt32(), REQUEST_SET_FACILITY_LOCK);
michael@0 2356
michael@0 2357 // Token : we don't care
michael@0 2358 this.readInt32();
michael@0 2359
michael@0 2360 let parcel = this.readStringList();
michael@0 2361 do_check_eq(parcel.length, 5);
michael@0 2362 do_check_eq(parcel[0], GECKO_CARDLOCK_TO_FACILITIY_LOCK[aLock]);
michael@0 2363 do_check_eq(parcel[1], aEnabled ? "1" : "0");
michael@0 2364 do_check_eq(parcel[2], GECKO_CARDLOCK_TO_PASSWORD[aLock]);
michael@0 2365 do_check_eq(parcel[3], serviceClass.toString());
michael@0 2366 do_check_eq(parcel[4], aid);
michael@0 2367 };
michael@0 2368
michael@0 2369 let lock = {lockType: aLock,
michael@0 2370 enabled: aEnabled};
michael@0 2371 lock[GECKO_CARDLOCK_TO_PASSWORD_TYPE[aLock]] = aPassword;
michael@0 2372
michael@0 2373 ril.iccSetCardLock(lock);
michael@0 2374 }
michael@0 2375
michael@0 2376 do_test(GECKO_CARDLOCK_PIN, pin, true);
michael@0 2377 do_test(GECKO_CARDLOCK_PIN, pin, false);
michael@0 2378 do_test(GECKO_CARDLOCK_FDN, pin2, true);
michael@0 2379 do_test(GECKO_CARDLOCK_FDN, pin2, false);
michael@0 2380
michael@0 2381 run_next_test();
michael@0 2382 });
michael@0 2383
michael@0 2384 /**
michael@0 2385 * Verify iccUnlockCardLock.
michael@0 2386 */
michael@0 2387 add_test(function test_unlock_card_lock_corporateLocked() {
michael@0 2388 let worker = newUint8Worker();
michael@0 2389 let context = worker.ContextPool._contexts[0];
michael@0 2390 let ril = context.RIL;
michael@0 2391 let buf = context.Buf;
michael@0 2392 const pin = "12345678";
michael@0 2393 const puk = "12345678";
michael@0 2394
michael@0 2395 let GECKO_CARDLOCK_TO_PASSWORD_TYPE = {};
michael@0 2396 GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_NCK] = "pin";
michael@0 2397 GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_NCK1] = "pin";
michael@0 2398 GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_NCK2] = "pin";
michael@0 2399 GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_HNCK] = "pin";
michael@0 2400 GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_CCK] = "pin";
michael@0 2401 GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_SPCK] = "pin";
michael@0 2402 GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_RCCK] = "pin";
michael@0 2403 GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_RSPCK] = "pin";
michael@0 2404 GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_NCK_PUK] = "puk";
michael@0 2405 GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_NCK1_PUK] = "puk";
michael@0 2406 GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_NCK2_PUK] = "puk";
michael@0 2407 GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_HNCK_PUK] = "puk";
michael@0 2408 GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_CCK_PUK] = "puk";
michael@0 2409 GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_SPCK_PUK] = "puk";
michael@0 2410 GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_RCCK_PUK] = "puk";
michael@0 2411 GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_RSPCK_PUK] = "puk";
michael@0 2412
michael@0 2413 function do_test(aLock, aPassword) {
michael@0 2414 buf.sendParcel = function fakeSendParcel () {
michael@0 2415 // Request Type.
michael@0 2416 do_check_eq(this.readInt32(), REQUEST_ENTER_NETWORK_DEPERSONALIZATION_CODE);
michael@0 2417
michael@0 2418 // Token : we don't care
michael@0 2419 this.readInt32();
michael@0 2420
michael@0 2421 let lockType = GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[aLock];
michael@0 2422 // Lock Type
michael@0 2423 do_check_eq(this.readInt32(), lockType);
michael@0 2424
michael@0 2425 // Pin/Puk.
michael@0 2426 do_check_eq(this.readString(), aPassword);
michael@0 2427 };
michael@0 2428
michael@0 2429 let lock = {lockType: aLock};
michael@0 2430 lock[GECKO_CARDLOCK_TO_PASSWORD_TYPE[aLock]] = aPassword;
michael@0 2431 ril.iccUnlockCardLock(lock);
michael@0 2432 }
michael@0 2433
michael@0 2434 do_test(GECKO_CARDLOCK_NCK, pin);
michael@0 2435 do_test(GECKO_CARDLOCK_NCK1, pin);
michael@0 2436 do_test(GECKO_CARDLOCK_NCK2, pin);
michael@0 2437 do_test(GECKO_CARDLOCK_HNCK, pin);
michael@0 2438 do_test(GECKO_CARDLOCK_CCK, pin);
michael@0 2439 do_test(GECKO_CARDLOCK_SPCK, pin);
michael@0 2440 do_test(GECKO_CARDLOCK_RCCK, pin);
michael@0 2441 do_test(GECKO_CARDLOCK_RSPCK, pin);
michael@0 2442 do_test(GECKO_CARDLOCK_NCK_PUK, puk);
michael@0 2443 do_test(GECKO_CARDLOCK_NCK1_PUK, puk);
michael@0 2444 do_test(GECKO_CARDLOCK_NCK2_PUK, puk);
michael@0 2445 do_test(GECKO_CARDLOCK_HNCK_PUK, puk);
michael@0 2446 do_test(GECKO_CARDLOCK_CCK_PUK, puk);
michael@0 2447 do_test(GECKO_CARDLOCK_SPCK_PUK, puk);
michael@0 2448 do_test(GECKO_CARDLOCK_RCCK_PUK, puk);
michael@0 2449 do_test(GECKO_CARDLOCK_RSPCK_PUK, puk);
michael@0 2450
michael@0 2451 run_next_test();
michael@0 2452 });
michael@0 2453
michael@0 2454 /**
michael@0 2455 * Verify MCC and MNC parsing
michael@0 2456 */
michael@0 2457 add_test(function test_mcc_mnc_parsing() {
michael@0 2458 let worker = newUint8Worker();
michael@0 2459 let context = worker.ContextPool._contexts[0];
michael@0 2460 let helper = context.ICCUtilsHelper;
michael@0 2461
michael@0 2462 function do_test(imsi, mncLength, expectedMcc, expectedMnc) {
michael@0 2463 let result = helper.parseMccMncFromImsi(imsi, mncLength);
michael@0 2464
michael@0 2465 if (!imsi) {
michael@0 2466 do_check_eq(result, null);
michael@0 2467 return;
michael@0 2468 }
michael@0 2469
michael@0 2470 do_check_eq(result.mcc, expectedMcc);
michael@0 2471 do_check_eq(result.mnc, expectedMnc);
michael@0 2472 }
michael@0 2473
michael@0 2474 // Test the imsi is null.
michael@0 2475 do_test(null, null, null, null);
michael@0 2476
michael@0 2477 // Test MCC is Taiwan
michael@0 2478 do_test("466923202422409", 0x02, "466", "92");
michael@0 2479 do_test("466923202422409", 0x03, "466", "923");
michael@0 2480 do_test("466923202422409", null, "466", "92");
michael@0 2481
michael@0 2482 // Test MCC is US
michael@0 2483 do_test("310260542718417", 0x02, "310", "26");
michael@0 2484 do_test("310260542718417", 0x03, "310", "260");
michael@0 2485 do_test("310260542718417", null, "310", "260");
michael@0 2486
michael@0 2487 run_next_test();
michael@0 2488 });
michael@0 2489
michael@0 2490 /**
michael@0 2491 * Verify reading EF_AD and parsing MCC/MNC
michael@0 2492 */
michael@0 2493 add_test(function test_reading_ad_and_parsing_mcc_mnc() {
michael@0 2494 let worker = newUint8Worker();
michael@0 2495 let context = worker.ContextPool._contexts[0];
michael@0 2496 let record = context.SimRecordHelper;
michael@0 2497 let helper = context.GsmPDUHelper;
michael@0 2498 let ril = context.RIL;
michael@0 2499 let buf = context.Buf;
michael@0 2500 let io = context.ICCIOHelper;
michael@0 2501
michael@0 2502 function do_test(mncLengthInEf, imsi, expectedMcc, expectedMnc) {
michael@0 2503 ril.iccInfoPrivate.imsi = imsi;
michael@0 2504
michael@0 2505 io.loadTransparentEF = function fakeLoadTransparentEF(options) {
michael@0 2506 let ad = [0x00, 0x00, 0x00];
michael@0 2507 if (mncLengthInEf) {
michael@0 2508 ad.push(mncLengthInEf);
michael@0 2509 }
michael@0 2510
michael@0 2511 // Write data size
michael@0 2512 buf.writeInt32(ad.length * 2);
michael@0 2513
michael@0 2514 // Write data
michael@0 2515 for (let i = 0; i < ad.length; i++) {
michael@0 2516 helper.writeHexOctet(ad[i]);
michael@0 2517 }
michael@0 2518
michael@0 2519 // Write string delimiter
michael@0 2520 buf.writeStringDelimiter(ad.length * 2);
michael@0 2521
michael@0 2522 if (options.callback) {
michael@0 2523 options.callback(options);
michael@0 2524 }
michael@0 2525 };
michael@0 2526
michael@0 2527 record.readAD();
michael@0 2528
michael@0 2529 do_check_eq(ril.iccInfo.mcc, expectedMcc);
michael@0 2530 do_check_eq(ril.iccInfo.mnc, expectedMnc);
michael@0 2531 }
michael@0 2532
michael@0 2533 do_test(undefined, "466923202422409", "466", "92" );
michael@0 2534 do_test(0x03, "466923202422409", "466", "923");
michael@0 2535 do_test(undefined, "310260542718417", "310", "260");
michael@0 2536 do_test(0x02, "310260542718417", "310", "26" );
michael@0 2537
michael@0 2538 run_next_test();
michael@0 2539 });
michael@0 2540
michael@0 2541 add_test(function test_reading_optional_efs() {
michael@0 2542 let worker = newUint8Worker();
michael@0 2543 let context = worker.ContextPool._contexts[0];
michael@0 2544 let record = context.SimRecordHelper;
michael@0 2545 let gsmPdu = context.GsmPDUHelper;
michael@0 2546 let ril = context.RIL;
michael@0 2547 let buf = context.Buf;
michael@0 2548 let io = context.ICCIOHelper;
michael@0 2549
michael@0 2550 function buildSST(supportedEf) {
michael@0 2551 let sst = [];
michael@0 2552 let len = supportedEf.length;
michael@0 2553 for (let i = 0; i < len; i++) {
michael@0 2554 let index, bitmask, iccService;
michael@0 2555 if (ril.appType === CARD_APPTYPE_SIM) {
michael@0 2556 iccService = GECKO_ICC_SERVICES.sim[supportedEf[i]];
michael@0 2557 iccService -= 1;
michael@0 2558 index = Math.floor(iccService / 4);
michael@0 2559 bitmask = 2 << ((iccService % 4) << 1);
michael@0 2560 } else if (ril.appType === CARD_APPTYPE_USIM){
michael@0 2561 iccService = GECKO_ICC_SERVICES.usim[supportedEf[i]];
michael@0 2562 iccService -= 1;
michael@0 2563 index = Math.floor(iccService / 8);
michael@0 2564 bitmask = 1 << ((iccService % 8) << 0);
michael@0 2565 }
michael@0 2566
michael@0 2567 if (sst) {
michael@0 2568 sst[index] |= bitmask;
michael@0 2569 }
michael@0 2570 }
michael@0 2571 return sst;
michael@0 2572 }
michael@0 2573
michael@0 2574 ril.updateCellBroadcastConfig = function fakeUpdateCellBroadcastConfig() {
michael@0 2575 // Ignore updateCellBroadcastConfig after reading SST
michael@0 2576 };
michael@0 2577
michael@0 2578 function do_test(sst, supportedEf) {
michael@0 2579 // Clone supportedEf to local array for testing
michael@0 2580 let testEf = supportedEf.slice(0);
michael@0 2581
michael@0 2582 record.readMSISDN = function fakeReadMSISDN() {
michael@0 2583 testEf.splice(testEf.indexOf("MSISDN"), 1);
michael@0 2584 };
michael@0 2585
michael@0 2586 record.readMBDN = function fakeReadMBDN() {
michael@0 2587 testEf.splice(testEf.indexOf("MDN"), 1);
michael@0 2588 };
michael@0 2589
michael@0 2590 record.readMWIS = function fakeReadMWIS() {
michael@0 2591 testEf.splice(testEf.indexOf("MWIS"), 1);
michael@0 2592 };
michael@0 2593
michael@0 2594 io.loadTransparentEF = function fakeLoadTransparentEF(options) {
michael@0 2595 // Write data size
michael@0 2596 buf.writeInt32(sst.length * 2);
michael@0 2597
michael@0 2598 // Write data
michael@0 2599 for (let i = 0; i < sst.length; i++) {
michael@0 2600 gsmPdu.writeHexOctet(sst[i] || 0);
michael@0 2601 }
michael@0 2602
michael@0 2603 // Write string delimiter
michael@0 2604 buf.writeStringDelimiter(sst.length * 2);
michael@0 2605
michael@0 2606 if (options.callback) {
michael@0 2607 options.callback(options);
michael@0 2608 }
michael@0 2609
michael@0 2610 if (testEf.length !== 0) {
michael@0 2611 do_print("Un-handled EF: " + JSON.stringify(testEf));
michael@0 2612 do_check_true(false);
michael@0 2613 }
michael@0 2614 };
michael@0 2615
michael@0 2616 record.readSST();
michael@0 2617 }
michael@0 2618
michael@0 2619 // TODO: Add all necessary optional EFs eventually
michael@0 2620 let supportedEf = ["MSISDN", "MDN", "MWIS"];
michael@0 2621 ril.appType = CARD_APPTYPE_SIM;
michael@0 2622 do_test(buildSST(supportedEf), supportedEf);
michael@0 2623 ril.appType = CARD_APPTYPE_USIM;
michael@0 2624 do_test(buildSST(supportedEf), supportedEf);
michael@0 2625
michael@0 2626 run_next_test();
michael@0 2627 });
michael@0 2628
michael@0 2629 /**
michael@0 2630 * Verify fetchSimRecords.
michael@0 2631 */
michael@0 2632 add_test(function test_fetch_sim_recodes() {
michael@0 2633 let worker = newWorker();
michael@0 2634 let context = worker.ContextPool._contexts[0];
michael@0 2635 let RIL = context.RIL;
michael@0 2636 let iccRecord = context.ICCRecordHelper;
michael@0 2637 let simRecord = context.SimRecordHelper;
michael@0 2638
michael@0 2639 function testFetchSimRecordes(expectCalled) {
michael@0 2640 let ifCalled = [];
michael@0 2641
michael@0 2642 RIL.getIMSI = function() {
michael@0 2643 ifCalled.push("getIMSI");
michael@0 2644 };
michael@0 2645
michael@0 2646 simRecord.readAD = function() {
michael@0 2647 ifCalled.push("readAD");
michael@0 2648 };
michael@0 2649
michael@0 2650 simRecord.readSST = function() {
michael@0 2651 ifCalled.push("readSST");
michael@0 2652 };
michael@0 2653
michael@0 2654 simRecord.fetchSimRecords();
michael@0 2655
michael@0 2656 for (let i = 0; i < expectCalled.length; i++ ) {
michael@0 2657 if (ifCalled[i] != expectCalled[i]) {
michael@0 2658 do_print(expectCalled[i] + " is not called.");
michael@0 2659 do_check_true(false);
michael@0 2660 }
michael@0 2661 }
michael@0 2662 }
michael@0 2663
michael@0 2664 let expectCalled = ["getIMSI", "readAD", "readSST"];
michael@0 2665 testFetchSimRecordes(expectCalled);
michael@0 2666
michael@0 2667 run_next_test();
michael@0 2668 });
michael@0 2669
michael@0 2670 add_test(function test_fetch_icc_recodes() {
michael@0 2671 let worker = newWorker();
michael@0 2672 let context = worker.ContextPool._contexts[0];
michael@0 2673 let RIL = context.RIL;
michael@0 2674 let iccRecord = context.ICCRecordHelper;
michael@0 2675 let simRecord = context.SimRecordHelper;
michael@0 2676 let ruimRecord = context.RuimRecordHelper;
michael@0 2677 let fetchTag = 0x00;
michael@0 2678
michael@0 2679 simRecord.fetchSimRecords = function() {
michael@0 2680 fetchTag = 0x01;
michael@0 2681 };
michael@0 2682
michael@0 2683 ruimRecord.fetchRuimRecords = function() {
michael@0 2684 fetchTag = 0x02;
michael@0 2685 };
michael@0 2686
michael@0 2687 RIL.appType = CARD_APPTYPE_SIM;
michael@0 2688 iccRecord.fetchICCRecords();
michael@0 2689 do_check_eq(fetchTag, 0x01);
michael@0 2690
michael@0 2691 RIL.appType = CARD_APPTYPE_RUIM;
michael@0 2692 iccRecord.fetchICCRecords();
michael@0 2693 do_check_eq(fetchTag, 0x02);
michael@0 2694
michael@0 2695 RIL.appType = CARD_APPTYPE_USIM;
michael@0 2696 iccRecord.fetchICCRecords();
michael@0 2697 do_check_eq(fetchTag, 0x01);
michael@0 2698
michael@0 2699 run_next_test();
michael@0 2700 });
michael@0 2701
michael@0 2702 /**
michael@0 2703 * Verify SimRecordHelper.readMWIS
michael@0 2704 */
michael@0 2705 add_test(function test_read_mwis() {
michael@0 2706 let worker = newUint8Worker();
michael@0 2707 let context = worker.ContextPool._contexts[0];
michael@0 2708 let helper = context.GsmPDUHelper;
michael@0 2709 let recordHelper = context.SimRecordHelper;
michael@0 2710 let buf = context.Buf;
michael@0 2711 let io = context.ICCIOHelper;
michael@0 2712 let mwisData;
michael@0 2713 let postedMessage;
michael@0 2714
michael@0 2715 worker.postMessage = function fakePostMessage(message) {
michael@0 2716 postedMessage = message;
michael@0 2717 };
michael@0 2718
michael@0 2719 io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
michael@0 2720 if (mwisData) {
michael@0 2721 // Write data size
michael@0 2722 buf.writeInt32(mwisData.length * 2);
michael@0 2723
michael@0 2724 // Write MWIS
michael@0 2725 for (let i = 0; i < mwisData.length; i++) {
michael@0 2726 helper.writeHexOctet(mwisData[i]);
michael@0 2727 }
michael@0 2728
michael@0 2729 // Write string delimiter
michael@0 2730 buf.writeStringDelimiter(mwisData.length * 2);
michael@0 2731
michael@0 2732 options.recordSize = mwisData.length;
michael@0 2733 if (options.callback) {
michael@0 2734 options.callback(options);
michael@0 2735 }
michael@0 2736 } else {
michael@0 2737 do_print("mwisData[] is not set.");
michael@0 2738 }
michael@0 2739 };
michael@0 2740
michael@0 2741 function buildMwisData(isActive, msgCount) {
michael@0 2742 if (msgCount < 0 || msgCount === GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN) {
michael@0 2743 msgCount = 0;
michael@0 2744 } else if (msgCount > 255) {
michael@0 2745 msgCount = 255;
michael@0 2746 }
michael@0 2747
michael@0 2748 mwisData = [ (isActive) ? 0x01 : 0x00,
michael@0 2749 msgCount,
michael@0 2750 0xFF, 0xFF, 0xFF ];
michael@0 2751 }
michael@0 2752
michael@0 2753 function do_test(isActive, msgCount) {
michael@0 2754 buildMwisData(isActive, msgCount);
michael@0 2755 recordHelper.readMWIS();
michael@0 2756
michael@0 2757 do_check_eq("iccmwis", postedMessage.rilMessageType);
michael@0 2758 do_check_eq(isActive, postedMessage.mwi.active);
michael@0 2759 do_check_eq((isActive) ? msgCount : 0, postedMessage.mwi.msgCount);
michael@0 2760 }
michael@0 2761
michael@0 2762 do_test(true, GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN);
michael@0 2763 do_test(true, 1);
michael@0 2764 do_test(true, 255);
michael@0 2765
michael@0 2766 do_test(false, 0);
michael@0 2767 do_test(false, 255); // Test the corner case when mwi is disable with incorrect msgCount.
michael@0 2768
michael@0 2769 run_next_test();
michael@0 2770 });
michael@0 2771
michael@0 2772 /**
michael@0 2773 * Verify SimRecordHelper.updateMWIS
michael@0 2774 */
michael@0 2775 add_test(function test_update_mwis() {
michael@0 2776 let worker = newUint8Worker();
michael@0 2777 let context = worker.ContextPool._contexts[0];
michael@0 2778 let pduHelper = context.GsmPDUHelper;
michael@0 2779 let ril = context.RIL;
michael@0 2780 ril.appType = CARD_APPTYPE_USIM;
michael@0 2781 ril.iccInfoPrivate.mwis = [0x00, 0x00, 0x00, 0x00, 0x00];
michael@0 2782 let recordHelper = context.SimRecordHelper;
michael@0 2783 let buf = context.Buf;
michael@0 2784 let ioHelper = context.ICCIOHelper;
michael@0 2785 let recordSize = ril.iccInfoPrivate.mwis.length;
michael@0 2786 let recordNum = 1;
michael@0 2787
michael@0 2788 ioHelper.updateLinearFixedEF = function(options) {
michael@0 2789 options.pathId = context.ICCFileHelper.getEFPath(options.fileId);
michael@0 2790 options.command = ICC_COMMAND_UPDATE_RECORD;
michael@0 2791 options.p1 = options.recordNumber;
michael@0 2792 options.p2 = READ_RECORD_ABSOLUTE_MODE;
michael@0 2793 options.p3 = recordSize;
michael@0 2794 ril.iccIO(options);
michael@0 2795 };
michael@0 2796
michael@0 2797 function do_test(isActive, count) {
michael@0 2798 let mwis = ril.iccInfoPrivate.mwis;
michael@0 2799 let isUpdated = false;
michael@0 2800
michael@0 2801 function buildMwisData() {
michael@0 2802 let result = mwis.slice(0);
michael@0 2803 result[0] = isActive? (mwis[0] | 0x01) : (mwis[0] & 0xFE);
michael@0 2804 result[1] = (count === GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN) ? 0 : count;
michael@0 2805
michael@0 2806 return result;
michael@0 2807 }
michael@0 2808
michael@0 2809 buf.sendParcel = function() {
michael@0 2810 isUpdated = true;
michael@0 2811
michael@0 2812 // Request Type.
michael@0 2813 do_check_eq(this.readInt32(), REQUEST_SIM_IO);
michael@0 2814
michael@0 2815 // Token : we don't care
michael@0 2816 this.readInt32();
michael@0 2817
michael@0 2818 // command.
michael@0 2819 do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
michael@0 2820
michael@0 2821 // fileId.
michael@0 2822 do_check_eq(this.readInt32(), ICC_EF_MWIS);
michael@0 2823
michael@0 2824 // pathId.
michael@0 2825 do_check_eq(this.readString(),
michael@0 2826 EF_PATH_MF_SIM + ((ril.appType === CARD_APPTYPE_USIM) ? EF_PATH_ADF_USIM : EF_PATH_DF_GSM));
michael@0 2827
michael@0 2828 // p1.
michael@0 2829 do_check_eq(this.readInt32(), recordNum);
michael@0 2830
michael@0 2831 // p2.
michael@0 2832 do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
michael@0 2833
michael@0 2834 // p3.
michael@0 2835 do_check_eq(this.readInt32(), recordSize);
michael@0 2836
michael@0 2837 // data.
michael@0 2838 let strLen = this.readInt32();
michael@0 2839 do_check_eq(recordSize * 2, strLen);
michael@0 2840 let expectedMwis = buildMwisData();
michael@0 2841 for (let i = 0; i < recordSize; i++) {
michael@0 2842 do_check_eq(expectedMwis[i], pduHelper.readHexOctet());
michael@0 2843 }
michael@0 2844 this.readStringDelimiter(strLen);
michael@0 2845
michael@0 2846 // pin2.
michael@0 2847 do_check_eq(this.readString(), null);
michael@0 2848
michael@0 2849 if (!ril.v5Legacy) {
michael@0 2850 // AID. Ignore because it's from modem.
michael@0 2851 this.readInt32();
michael@0 2852 }
michael@0 2853 };
michael@0 2854
michael@0 2855 do_check_false(isUpdated);
michael@0 2856
michael@0 2857 recordHelper.updateMWIS({ active: isActive,
michael@0 2858 msgCount: count });
michael@0 2859
michael@0 2860 do_check_true((ril.iccInfoPrivate.mwis) ? isUpdated : !isUpdated);
michael@0 2861 }
michael@0 2862
michael@0 2863 do_test(true, GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN);
michael@0 2864 do_test(true, 1);
michael@0 2865 do_test(true, 255);
michael@0 2866
michael@0 2867 do_test(false, 0);
michael@0 2868
michael@0 2869 // Test if Path ID is correct for SIM.
michael@0 2870 ril.appType = CARD_APPTYPE_SIM;
michael@0 2871 do_test(false, 0);
michael@0 2872
michael@0 2873 // Test if loadLinearFixedEF() is not invoked in updateMWIS() when
michael@0 2874 // EF_MWIS is not loaded/available.
michael@0 2875 delete ril.iccInfoPrivate.mwis;
michael@0 2876 do_test(false, 0);
michael@0 2877
michael@0 2878 run_next_test();
michael@0 2879 });
michael@0 2880
michael@0 2881 /**
michael@0 2882 * Verify the call flow of receiving Class 2 SMS stored in SIM:
michael@0 2883 * 1. UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM.
michael@0 2884 * 2. SimRecordHelper.readSMS().
michael@0 2885 * 3. sendChromeMessage() with rilMessageType == "sms-received".
michael@0 2886 */
michael@0 2887 add_test(function test_read_new_sms_on_sim() {
michael@0 2888 // Instead of reusing newUint8Worker defined in this file,
michael@0 2889 // we define our own worker to fake the methods in WorkerBuffer dynamically.
michael@0 2890 function newSmsOnSimWorkerHelper() {
michael@0 2891 let _postedMessage;
michael@0 2892 let _worker = newWorker({
michael@0 2893 postRILMessage: function(data) {
michael@0 2894 },
michael@0 2895 postMessage: function(message) {
michael@0 2896 _postedMessage = message;
michael@0 2897 }
michael@0 2898 });
michael@0 2899
michael@0 2900 _worker.debug = do_print;
michael@0 2901
michael@0 2902 return {
michael@0 2903 get postedMessage() {
michael@0 2904 return _postedMessage;
michael@0 2905 },
michael@0 2906 get worker() {
michael@0 2907 return _worker;
michael@0 2908 },
michael@0 2909 fakeWokerBuffer: function() {
michael@0 2910 let context = _worker.ContextPool._contexts[0];
michael@0 2911 let index = 0; // index for read
michael@0 2912 let buf = [];
michael@0 2913 context.Buf.writeUint8 = function(value) {
michael@0 2914 buf.push(value);
michael@0 2915 };
michael@0 2916 context.Buf.readUint8 = function() {
michael@0 2917 return buf[index++];
michael@0 2918 };
michael@0 2919 context.Buf.seekIncoming = function(offset) {
michael@0 2920 index += offset;
michael@0 2921 };
michael@0 2922 context.Buf.getReadAvailable = function() {
michael@0 2923 return buf.length - index;
michael@0 2924 };
michael@0 2925 }
michael@0 2926 };
michael@0 2927 }
michael@0 2928
michael@0 2929 let workerHelper = newSmsOnSimWorkerHelper();
michael@0 2930 let worker = workerHelper.worker;
michael@0 2931 let context = worker.ContextPool._contexts[0];
michael@0 2932
michael@0 2933 context.ICCIOHelper.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
michael@0 2934 // SimStatus: Unread, SMSC:+0123456789, Sender: +9876543210, Text: How are you?
michael@0 2935 let SimSmsPduHex = "0306911032547698040A9189674523010000208062917314080CC8F71D14969741F977FD07"
michael@0 2936 // In 4.2.25 EF_SMS Short Messages of 3GPP TS 31.102:
michael@0 2937 // 1. Record length == 176 bytes.
michael@0 2938 // 2. Any bytes in the record following the TPDU shall be filled with 'FF'.
michael@0 2939 + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
michael@0 2940 + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
michael@0 2941 + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
michael@0 2942 + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF";
michael@0 2943
michael@0 2944 workerHelper.fakeWokerBuffer();
michael@0 2945
michael@0 2946 context.Buf.writeString(SimSmsPduHex);
michael@0 2947
michael@0 2948 options.recordSize = 176; // Record length is fixed to 176 bytes.
michael@0 2949 if (options.callback) {
michael@0 2950 options.callback(options);
michael@0 2951 }
michael@0 2952 };
michael@0 2953
michael@0 2954 function newSmsOnSimParcel() {
michael@0 2955 let data = new Uint8Array(4 + 4); // Int32List with 1 element.
michael@0 2956 let offset = 0;
michael@0 2957
michael@0 2958 function writeInt(value) {
michael@0 2959 data[offset++] = value & 0xFF;
michael@0 2960 data[offset++] = (value >> 8) & 0xFF;
michael@0 2961 data[offset++] = (value >> 16) & 0xFF;
michael@0 2962 data[offset++] = (value >> 24) & 0xFF;
michael@0 2963 }
michael@0 2964
michael@0 2965 writeInt(1); // Length of Int32List
michael@0 2966 writeInt(1); // RecordNum = 1.
michael@0 2967
michael@0 2968 return newIncomingParcel(-1,
michael@0 2969 RESPONSE_TYPE_UNSOLICITED,
michael@0 2970 UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM,
michael@0 2971 data);
michael@0 2972 }
michael@0 2973
michael@0 2974 function do_test() {
michael@0 2975 worker.onRILMessage(0, newSmsOnSimParcel());
michael@0 2976
michael@0 2977 let postedMessage = workerHelper.postedMessage;
michael@0 2978
michael@0 2979 do_check_eq("sms-received", postedMessage.rilMessageType);
michael@0 2980 do_check_eq("+0123456789", postedMessage.SMSC);
michael@0 2981 do_check_eq("+9876543210", postedMessage.sender);
michael@0 2982 do_check_eq("How are you?", postedMessage.body);
michael@0 2983 }
michael@0 2984
michael@0 2985 do_test();
michael@0 2986
michael@0 2987 run_next_test();
michael@0 2988 });
michael@0 2989
michael@0 2990 // Test ICC_COMMAND_GET_RESPONSE with FCP template format.
michael@0 2991 /**
michael@0 2992 * Verify transparent structure with FCP template format.
michael@0 2993 */
michael@0 2994 add_test(function test_fcp_template_for_transparent_structure() {
michael@0 2995 let worker = newUint8Worker();
michael@0 2996 let context = worker.ContextPool._contexts[0];
michael@0 2997 let pduHelper = context.GsmPDUHelper;
michael@0 2998 let berHelper = context.BerTlvHelper;
michael@0 2999
michael@0 3000 let tag_test = [
michael@0 3001 0x62,
michael@0 3002 0x22,
michael@0 3003 0x82, 0x02, 0x41, 0x21,
michael@0 3004 0x83, 0x02, 0x2F, 0xE2,
michael@0 3005 0xA5, 0x09, 0xC1, 0x04, 0x40, 0x0F, 0xF5, 0x55, 0x92, 0x01, 0x00,
michael@0 3006 0x8A, 0x01, 0x05,
michael@0 3007 0x8B, 0x03, 0x2F, 0x06, 0x0B,
michael@0 3008 0x80, 0x02, 0x00, 0x0A,
michael@0 3009 0x88, 0x01, 0x10];
michael@0 3010
michael@0 3011 for (let i = 0; i < tag_test.length; i++) {
michael@0 3012 pduHelper.writeHexOctet(tag_test[i]);
michael@0 3013 }
michael@0 3014
michael@0 3015 let berTlv = berHelper.decode(tag_test.length);
michael@0 3016 let iter = Iterator(berTlv.value);
michael@0 3017 let tlv = berHelper.searchForNextTag(BER_FCP_FILE_DESCRIPTOR_TAG, iter);
michael@0 3018 do_check_eq(tlv.value.fileStructure, UICC_EF_STRUCTURE[EF_TYPE_TRANSPARENT]);
michael@0 3019
michael@0 3020 tlv = berHelper.searchForNextTag(BER_FCP_FILE_IDENTIFIER_TAG, iter);
michael@0 3021 do_check_eq(tlv.value.fileId, 0x2FE2);
michael@0 3022
michael@0 3023 tlv = berHelper.searchForNextTag(BER_FCP_FILE_SIZE_DATA_TAG, iter);
michael@0 3024 do_check_eq(tlv.value.fileSizeData, 0x0A);
michael@0 3025
michael@0 3026 run_next_test();
michael@0 3027 });
michael@0 3028
michael@0 3029 /**
michael@0 3030 * Verify linear fixed structure with FCP template format.
michael@0 3031 */
michael@0 3032 add_test(function test_fcp_template_for_linear_fixed_structure() {
michael@0 3033 let worker = newUint8Worker();
michael@0 3034 let context = worker.ContextPool._contexts[0];
michael@0 3035 let pduHelper = context.GsmPDUHelper;
michael@0 3036 let berHelper = context.BerTlvHelper;
michael@0 3037
michael@0 3038 let tag_test = [
michael@0 3039 0x62,
michael@0 3040 0x1E,
michael@0 3041 0x82, 0x05, 0x42, 0x21, 0x00, 0x1A, 0x01,
michael@0 3042 0x83, 0x02, 0x6F, 0x40,
michael@0 3043 0xA5, 0x03, 0x92, 0x01, 0x00,
michael@0 3044 0x8A, 0x01, 0x07,
michael@0 3045 0x8B, 0x03, 0x6F, 0x06, 0x02,
michael@0 3046 0x80, 0x02, 0x00, 0x1A,
michael@0 3047 0x88, 0x00];
michael@0 3048
michael@0 3049 for (let i = 0; i < tag_test.length; i++) {
michael@0 3050 pduHelper.writeHexOctet(tag_test[i]);
michael@0 3051 }
michael@0 3052
michael@0 3053 let berTlv = berHelper.decode(tag_test.length);
michael@0 3054 let iter = Iterator(berTlv.value);
michael@0 3055 let tlv = berHelper.searchForNextTag(BER_FCP_FILE_DESCRIPTOR_TAG, iter);
michael@0 3056 do_check_eq(tlv.value.fileStructure, UICC_EF_STRUCTURE[EF_TYPE_LINEAR_FIXED]);
michael@0 3057 do_check_eq(tlv.value.recordLength, 0x1A);
michael@0 3058 do_check_eq(tlv.value.numOfRecords, 0x01);
michael@0 3059
michael@0 3060 tlv = berHelper.searchForNextTag(BER_FCP_FILE_IDENTIFIER_TAG, iter);
michael@0 3061 do_check_eq(tlv.value.fileId, 0x6F40);
michael@0 3062
michael@0 3063 tlv = berHelper.searchForNextTag(BER_FCP_FILE_SIZE_DATA_TAG, iter);
michael@0 3064 do_check_eq(tlv.value.fileSizeData, 0x1A);
michael@0 3065
michael@0 3066 run_next_test();
michael@0 3067 });
michael@0 3068
michael@0 3069 add_test(function test_icc_io_get_response_for_transparent_structure() {
michael@0 3070 let worker = newUint8Worker();
michael@0 3071 let context = worker.ContextPool._contexts[0];
michael@0 3072 let buf = context.Buf;
michael@0 3073 let iccioHelper = context.ICCIOHelper;
michael@0 3074 let pduHelper = context.GsmPDUHelper;
michael@0 3075
michael@0 3076 let responseArray = [
michael@0 3077 // SIM response.
michael@0 3078 [0x00, 0x00, 0x00, 0x0A, 0x2F, 0xE2, 0x04, 0x00, 0x0A, 0xA0, 0xAA, 0x00,
michael@0 3079 0x02, 0x00, 0x00],
michael@0 3080 // USIM response.
michael@0 3081 [0x62, 0x22, 0x82, 0x02, 0x41, 0x21, 0x83, 0x02, 0x2F, 0xE2, 0xA5, 0x09,
michael@0 3082 0xC1, 0x04, 0x40, 0x0F, 0xF5, 0x55, 0x92, 0x01, 0x00, 0x8A, 0x01, 0x05,
michael@0 3083 0x8B, 0x03, 0x2F, 0x06, 0x0B, 0x80, 0x02, 0x00, 0x0A, 0x88, 0x01, 0x10]
michael@0 3084 ];
michael@0 3085
michael@0 3086 for (let i = 0; i < responseArray.length; i++) {
michael@0 3087 let strLen = responseArray[i].length * 2;
michael@0 3088 buf.writeInt32(strLen);
michael@0 3089 for (let j = 0; j < responseArray[i].length; j++) {
michael@0 3090 pduHelper.writeHexOctet(responseArray[i][j]);
michael@0 3091 }
michael@0 3092 buf.writeStringDelimiter(strLen);
michael@0 3093
michael@0 3094 let options = {fileId: ICC_EF_ICCID,
michael@0 3095 type: EF_TYPE_TRANSPARENT};
michael@0 3096 iccioHelper.processICCIOGetResponse(options);
michael@0 3097
michael@0 3098 do_check_eq(options.fileSize, 0x0A);
michael@0 3099 }
michael@0 3100
michael@0 3101 run_next_test();
michael@0 3102 });
michael@0 3103
michael@0 3104 add_test(function test_icc_io_get_response_for_linear_fixed_structure() {
michael@0 3105 let worker = newUint8Worker();
michael@0 3106 let context = worker.ContextPool._contexts[0];
michael@0 3107 let buf = context.Buf;
michael@0 3108 let iccioHelper = context.ICCIOHelper;
michael@0 3109 let pduHelper = context.GsmPDUHelper;
michael@0 3110
michael@0 3111 let responseArray = [
michael@0 3112 // SIM response.
michael@0 3113 [0x00, 0x00, 0x00, 0x1A, 0x6F, 0x40, 0x04, 0x00, 0x11, 0xA0, 0xAA, 0x00,
michael@0 3114 0x02, 0x01, 0x1A],
michael@0 3115 // USIM response.
michael@0 3116 [0x62, 0x1E, 0x82, 0x05, 0x42, 0x21, 0x00, 0x1A, 0x01, 0x83, 0x02, 0x6F,
michael@0 3117 0x40, 0xA5, 0x03, 0x92, 0x01, 0x00, 0x8A, 0x01, 0x07, 0x8B, 0x03, 0x6F,
michael@0 3118 0x06, 0x02, 0x80, 0x02, 0x00, 0x1A, 0x88, 0x00]
michael@0 3119 ];
michael@0 3120
michael@0 3121 for (let i = 0; i < responseArray.length; i++) {
michael@0 3122 let strLen = responseArray[i].length * 2;
michael@0 3123 buf.writeInt32(strLen);
michael@0 3124 for (let j = 0; j < responseArray[i].length; j++) {
michael@0 3125 pduHelper.writeHexOctet(responseArray[i][j]);
michael@0 3126 }
michael@0 3127 buf.writeStringDelimiter(strLen);
michael@0 3128
michael@0 3129 let options = {fileId: ICC_EF_MSISDN,
michael@0 3130 type: EF_TYPE_LINEAR_FIXED};
michael@0 3131 iccioHelper.processICCIOGetResponse(options);
michael@0 3132
michael@0 3133 do_check_eq(options.fileSize, 0x1A);
michael@0 3134 do_check_eq(options.recordSize, 0x1A);
michael@0 3135 do_check_eq(options.totalRecords, 0x01);
michael@0 3136 }
michael@0 3137
michael@0 3138 run_next_test();
michael@0 3139 });
michael@0 3140
michael@0 3141 /**
michael@0 3142 * Verify reading EF_ICCID.
michael@0 3143 */
michael@0 3144 add_test(function test_handling_iccid() {
michael@0 3145 let worker = newUint8Worker();
michael@0 3146 let context = worker.ContextPool._contexts[0];
michael@0 3147 let record = context.ICCRecordHelper;
michael@0 3148 let helper = context.GsmPDUHelper;
michael@0 3149 let ril = context.RIL;
michael@0 3150 let buf = context.Buf;
michael@0 3151 let io = context.ICCIOHelper;
michael@0 3152
michael@0 3153 ril.reportStkServiceIsRunning = function fakeReportStkServiceIsRunning() {
michael@0 3154 };
michael@0 3155
michael@0 3156 function do_test(rawICCID, expectedICCID) {
michael@0 3157 io.loadTransparentEF = function fakeLoadTransparentEF(options) {
michael@0 3158 // Write data size
michael@0 3159 buf.writeInt32(rawICCID.length);
michael@0 3160
michael@0 3161 // Write data
michael@0 3162 for (let i = 0; i < rawICCID.length; i += 2) {
michael@0 3163 helper.writeHexOctet(parseInt(rawICCID.substr(i, 2), 16));
michael@0 3164 }
michael@0 3165
michael@0 3166 // Write string delimiter
michael@0 3167 buf.writeStringDelimiter(rawICCID.length);
michael@0 3168
michael@0 3169 if (options.callback) {
michael@0 3170 options.callback(options);
michael@0 3171 }
michael@0 3172 };
michael@0 3173
michael@0 3174 record.readICCID();
michael@0 3175
michael@0 3176 do_check_eq(ril.iccInfo.iccid, expectedICCID);
michael@0 3177 }
michael@0 3178
michael@0 3179 // Invalid char at high nibbile + low nibbile contains 0xF.
michael@0 3180 do_test("9868002E90909F001519", "89860020909");
michael@0 3181 // Invalid char at low nibbile.
michael@0 3182 do_test("986800E2909090001519", "8986002090909005191");
michael@0 3183 // Valid ICCID.
michael@0 3184 do_test("98101430121181157002", "89014103211118510720");
michael@0 3185
michael@0 3186 run_next_test();
michael@0 3187 });

mercurial