dom/system/gonk/tests/test_ril_worker_icc.js

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

mercurial