dom/system/gonk/tests/test_ril_worker_icc.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* Any copyright is dedicated to the Public Domain.
     2    http://creativecommons.org/publicdomain/zero/1.0/ */
     4 subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
     6 function run_test() {
     7   run_next_test();
     8 }
    10 /**
    11  * Helper function.
    12  */
    13 function newUint8Worker() {
    14   let worker = newWorker();
    15   let index = 0; // index for read
    16   let buf = [];
    18   let context = worker.ContextPool._contexts[0];
    19   context.Buf.writeUint8 = function(value) {
    20     buf.push(value);
    21   };
    23   context.Buf.readUint8 = function() {
    24     return buf[index++];
    25   };
    27   context.Buf.seekIncoming = function(offset) {
    28     index += offset;
    29   };
    31   context.Buf.getReadAvailable = function() {
    32     return buf.length - index;
    33   };
    35   worker.debug = do_print;
    37   return worker;
    38 }
    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;
    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);
    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");
    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");
    77   run_next_test();
    78 });
    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";
    90   helper.readHexOctet = function() {
    91     return 0x81;
    92   };
    94   helper.readSwappedNibbleBcdString = function(len) {
    95     return str.substring(0, len);
    96   };
    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   }
   103   run_next_test();
   104 });
   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];
   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   }
   123   // Write two ESCAPEs to make it become ' '.
   124   helper.writeHexOctet(PDU_NL_EXTENDED_ESCAPE);
   125   helper.writeHexOctet(PDU_NL_EXTENDED_ESCAPE);
   127   for (let i = PDU_NL_EXTENDED_ESCAPE + 1; i < langTable.length; i++) {
   128     helper.writeHexOctet(i);
   129   }
   131   // Also write two unused fields.
   132   let ffLen = 2;
   133   for (let i = 0; i < ffLen; i++) {
   134     helper.writeHexOctet(0xff);
   135   }
   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));
   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   }
   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));
   167   run_next_test();
   168 });
   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;
   186   // Test 1, write GSM alphabets.
   187   iccHelper.writeStringTo8BitUnpacked(langTable.length + ffLen, langTable);
   189   for (let i = 0; i < langTable.length; i++) {
   190     do_check_eq(helper.readHexOctet(), i);
   191   }
   193   for (let i = 0; i < ffLen; i++) {
   194     do_check_eq(helper.readHexOctet(), 0xff);
   195   }
   197   // Test 2, write GSM extended alphabets.
   198   str = "\u000c\u20ac";
   199   iccHelper.writeStringTo8BitUnpacked(4, str);
   201   do_check_eq(iccHelper.read8BitUnpackedToString(4), str);
   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";
   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);
   214   do_check_eq(iccHelper.read8BitUnpackedToString(7), str);
   216   run_next_test();
   217 });
   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];
   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);
   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);
   245   str = "\u00a3\u000c";
   246   iccHelper.writeStringTo8BitUnpacked(3, str);
   247   do_check_eq(iccHelper.read8BitUnpackedToString(3), str);
   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));
   256   run_next_test();
   257 });
   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;
   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);
   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");
   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");
   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));
   301   run_next_test();
   302 });
   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;
   315   // Removal
   316   iccHelper.writeAlphaIdentifier(10, null);
   317   do_check_eq(iccHelper.readAlphaIdentifier(10), "");
   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);
   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);
   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);
   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));
   343   // Write 0 octet.
   344   iccHelper.writeAlphaIdentifier(0, "1");
   345   helper.writeHexOctet(0xff); // dummy octet.
   346   do_check_eq(iccHelper.readAlphaIdentifier(1), "");
   348   run_next_test();
   349 });
   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;
   362   function testReadAlphaIdDiallingNumber(contact) {
   363     iccHelper.readAlphaIdentifier = function() {
   364       return contact.alphaId;
   365     };
   367     iccHelper.readNumberWithLength = function() {
   368       return contact.number;
   369     };
   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);
   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   }
   386   testReadAlphaIdDiallingNumber({alphaId: "AlphaId", number: "0987654321"});
   387   testReadAlphaIdDiallingNumber({alphaId: "", number: ""});
   389   run_next_test();
   390 });
   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;
   401   // Write a normal contact.
   402   let contactW = {
   403     alphaId: "Mozilla",
   404     number: "1234567890"
   405   };
   406   helper.writeAlphaIdDiallingNumber(recordSize, contactW.alphaId,
   407                                     contactW.number);
   409   let contactR = helper.readAlphaIdDiallingNumber(recordSize);
   410   do_check_eq(contactW.alphaId, contactR.alphaId);
   411   do_check_eq(contactW.number, contactR.number);
   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);
   424   // Write a null contact (Removal).
   425   helper.writeAlphaIdDiallingNumber(recordSize);
   426   contactR = helper.readAlphaIdDiallingNumber(recordSize);
   427   do_check_eq(contactR, null);
   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");
   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");
   452   run_next_test();
   453 });
   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;
   463   // with +
   464   let number = "+123456";
   465   let len = 4;
   466   helper.writeDiallingNumber(number);
   467   do_check_eq(helper.readDiallingNumber(len), number);
   469   // without +
   470   number = "987654";
   471   len = 4;
   472   helper.writeDiallingNumber(number);
   473   do_check_eq(helper.readDiallingNumber(len), number);
   475   number = "9876543";
   476   len = 5;
   477   helper.writeDiallingNumber(number);
   478   do_check_eq(helper.readDiallingNumber(len), number);
   480   run_next_test();
   481 });
   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";
   493   iccHelper.readDiallingNumber = function(numLen) {
   494     return number.substring(0, numLen);
   495   };
   497   helper.writeHexOctet(number.length + 1);
   498   helper.writeHexOctet(PDU_TOA_ISDN);
   499   do_check_eq(iccHelper.readNumberWithLength(), number);
   501   helper.writeHexOctet(0xff);
   502   do_check_eq(iccHelper.readNumberWithLength(), null);
   504   run_next_test();
   505 });
   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;
   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   }
   526   // without +
   527   test("123456789");
   529   // with +
   530   test("+987654321");
   532   // extended BCD coding
   533   test("1*2#3,4*5#6,");
   535   // with + and extended BCD coding
   536   test("+1*2#3,4*5#6,");
   538   // non-supported characters should not be written.
   539   test("(1)23-456+789", "123456789");
   541   test("++(01)2*3-4#5,6+7(8)9*0#1,", "+012*34#5,6789*0#1,");
   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   }
   549   run_next_test();
   550 });
   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;
   560   // current date
   561   let dateInput = new Date();
   562   let dateOutput = new Date();
   563   helper.writeTimestamp(dateInput);
   564   dateOutput.setTime(helper.readTimestamp());
   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());
   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());
   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());
   589   run_next_test();
   590 });
   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;
   600   // 23
   601   let number = 23;
   602   let octet = helper.BCDToOctet(number);
   603   do_check_eq(helper.octetToBCD(octet), number);
   605   // 56
   606   number = 56;
   607   octet = helper.BCDToOctet(number);
   608   do_check_eq(helper.octetToBCD(octet), number);
   610   // 0x23
   611   octet = 0x23;
   612   number = helper.octetToBCD(octet);
   613   do_check_eq(helper.BCDToOctet(number), octet);
   615   // 0x56
   616   octet = 0x56;
   617   number = helper.octetToBCD(octet);
   618   do_check_eq(helper.BCDToOctet(number), octet);
   620   run_next_test();
   621 });
   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;
   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   }
   640   test_table([0x08], "ADN", true, false);
   641   test_table([0x08], "FDN", false, false);
   642   test_table([0x08], "SDN", false, true);
   644   run_next_test();
   645 });
   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];
   657   do_check_eq(ICCUtilsHelper.isGsm8BitAlphabet(langTable), true);
   658   do_check_eq(ICCUtilsHelper.isGsm8BitAlphabet(langShiftTable), true);
   659   do_check_eq(ICCUtilsHelper.isGsm8BitAlphabet("\uaaaa"), false);
   661   run_next_test();
   662 });
   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;
   673   buf.sendParcel = function() {
   674     // Request Type.
   675     do_check_eq(this.readInt32(), REQUEST_QUERY_FACILITY_LOCK)
   677     // Token : we don't care.
   678     this.readInt32();
   680     // String Array Length.
   681     do_check_eq(this.readInt32(), ril.v5Legacy ? 3 : 4);
   683     // Facility.
   684     do_check_eq(this.readString(), ICC_CB_FACILITY_FDN);
   686     // Password.
   687     do_check_eq(this.readString(), "");
   689     // Service class.
   690     do_check_eq(this.readString(), (ICC_SERVICE_CLASS_VOICE |
   691                                     ICC_SERVICE_CLASS_DATA  |
   692                                     ICC_SERVICE_CLASS_FAX).toString());
   694     if (!ril.v5Legacy) {
   695       // AID. Ignore because it's from modem.
   696       this.readInt32();
   697     }
   699     run_next_test();
   700   };
   702   ril.iccGetCardLockState({lockType: "fdn"});
   703 });
   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;
   711   function testGetNetworkNameFromICC(operatorData, expectedResult) {
   712     let result = ICCUtilsHelper.getNetworkNameFromICC(operatorData.mcc,
   713                                                       operatorData.mnc,
   714                                                       operatorData.lac);
   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   }
   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);
   728   // Set HPLMN
   729   RIL.iccInfo.mcc = 123;
   730   RIL.iccInfo.mnc = 456;
   732   RIL.voiceRegistrationState = {
   733     cell: {
   734       gsmLocationAreaCode: 0x1000
   735     }
   736   };
   737   RIL.operator = {};
   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   };
   749   // EF_OPL isn't available and current isn't in HPLMN,
   750   testGetNetworkNameFromICC({mcc: 321, mnc: 654, lac: 0x1000}, null);
   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"});
   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   ];
   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"});
   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"});
   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"});
   796   run_next_test();
   797 });
   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;
   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);
   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 });
   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;
   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   ];
   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);
   881   run_next_test();
   882 });
   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;
   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   };
   899   ril.iccIO = function fakeIccIO(options) {
   900     do_check_true(true);
   901     run_next_test();
   902   };
   904   io.loadLinearFixedEF({recordSize: 0x20});
   905 });
   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;
   916   io.getResponse = function fakeGetResponse(options) {
   917     do_check_true(true);
   918     run_next_test();
   919   };
   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   };
   927   io.loadLinearFixedEF({});
   928 });
   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;
   941   io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
   942     let pbr_1 = [
   943       0xa8, 0x05, 0xc0, 0x03, 0x4f, 0x3a, 0x01
   944     ];
   946     // Write data size
   947     buf.writeInt32(pbr_1.length * 2);
   949     // Write pbr
   950     for (let i = 0; i < pbr_1.length; i++) {
   951       helper.writeHexOctet(pbr_1[i]);
   952     }
   954     // Write string delimiter
   955     buf.writeStringDelimiter(pbr_1.length * 2);
   957     options.totalRecords = 2;
   958     if (options.callback) {
   959       options.callback(options);
   960     }
   961   };
   963   io.loadNextRecord = function fakeLoadNextRecord(options) {
   964     let pbr_2 = [
   965       0xff, 0xff, 0xff, 0xff, 0xff, 0xff
   966     ];
   968     options.p1++;
   969     if (options.callback) {
   970       options.callback(options);
   971     }
   972   };
   974   let successCb = function successCb(pbrs) {
   975     do_check_eq(pbrs[0].adn.fileId, 0x4f3a);
   976     do_check_eq(pbrs.length, 1);
   977   };
   979   let errorCb = function errorCb(errorMsg) {
   980     do_print("Reading EF_PBR failed, msg = " + errorMsg);
   981     do_check_true(false);
   982   };
   984   record.readPBR(successCb, errorCb);
   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);
   994   run_next_test();
   995 });
   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;
  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];
  1016     // Write data size
  1017     buf.writeInt32(email_1.length * 2);
  1019     // Write email
  1020     for (let i = 0; i < email_1.length; i++) {
  1021       helper.writeHexOctet(email_1[i]);
  1024     // Write string delimiter
  1025     buf.writeStringDelimiter(email_1.length * 2);
  1027     recordSize = email_1.length;
  1028     options.recordSize = recordSize;
  1029     if (options.callback) {
  1030       options.callback(options);
  1032   };
  1034   function doTestReadEmail(type, expectedResult) {
  1035     let fileId = 0x6a75;
  1036     let recordNumber = 1;
  1038     // fileId and recordNumber are dummy arguments.
  1039     record.readEmail(fileId, type, recordNumber, function(email) {
  1040       do_check_eq(email, expectedResult);
  1041     });
  1042   };
  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);
  1048   run_next_test();
  1049 });
  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;
  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   };
  1082   function do_test(pbr, expectedEmail, expectedAdnRecordId) {
  1083     buf.sendParcel = function() {
  1084       count++;
  1086       // Request Type.
  1087       do_check_eq(this.readInt32(), REQUEST_SIM_IO);
  1089       // Token : we don't care
  1090       this.readInt32();
  1092       // command.
  1093       do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
  1095       // fileId.
  1096       do_check_eq(this.readInt32(), fileId);
  1098       // pathId.
  1099       do_check_eq(this.readString(),
  1100                   EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK);
  1102       // p1.
  1103       do_check_eq(this.readInt32(), recordNumber);
  1105       // p2.
  1106       do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
  1108       // p3.
  1109       do_check_eq(this.readInt32(), recordSize);
  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);
  1121       this.readStringDelimiter(strLen);
  1122       do_check_eq(email, expectedEmail);
  1124       // pin2.
  1125       do_check_eq(this.readString(), null);
  1127       if (!ril.v5Legacy) {
  1128         // AID. Ignore because it's from modem.
  1129         this.readInt32();
  1132       if (count == NUM_TESTS) {
  1133         run_next_test();
  1135     };
  1136     recordHelper.updateEmail(pbr, recordNumber, expectedEmail, expectedAdnRecordId);
  1139   do_test(pbr, "test@mail.com");
  1140   pbr.email.fileType = ICC_USIM_TYPE2_TAG;
  1141   do_test(pbr, "test@mail.com", 1);
  1142 });
  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;
  1156   io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options)  {
  1157     let anr_1 = [
  1158       0x01, 0x05, 0x81, 0x10, 0x32,
  1159       0x54, 0xF6, 0xFF, 0xFF];
  1161     // Write data size
  1162     buf.writeInt32(anr_1.length * 2);
  1164     // Write anr
  1165     for (let i = 0; i < anr_1.length; i++) {
  1166       helper.writeHexOctet(anr_1[i]);
  1169     // Write string delimiter
  1170     buf.writeStringDelimiter(anr_1.length * 2);
  1172     recordSize = anr_1.length;
  1173     options.recordSize = recordSize;
  1174     if (options.callback) {
  1175       options.callback(options);
  1177   };
  1179   function doTestReadAnr(fileType, expectedResult) {
  1180     let fileId = 0x4f11;
  1181     let recordNumber = 1;
  1183     // fileId and recordNumber are dummy arguments.
  1184     record.readANR(fileId, fileType, recordNumber, function(anr) {
  1185       do_check_eq(anr, expectedResult);
  1186     });
  1187   };
  1189   doTestReadAnr(ICC_USIM_TYPE1_TAG, "0123456");
  1190   do_check_eq(record._anrRecordSize, recordSize);
  1192   run_next_test();
  1193 });
  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;
  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   };
  1226   function do_test(pbr, expectedANR, expectedAdnRecordId) {
  1227     buf.sendParcel = function() {
  1228       count++;
  1230       // Request Type.
  1231       do_check_eq(this.readInt32(), REQUEST_SIM_IO);
  1233       // Token : we don't care
  1234       this.readInt32();
  1236       // command.
  1237       do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
  1239       // fileId.
  1240       do_check_eq(this.readInt32(), fileId);
  1242       // pathId.
  1243       do_check_eq(this.readString(),
  1244                   EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK);
  1246       // p1.
  1247       do_check_eq(this.readInt32(), recordNumber);
  1249       // p2.
  1250       do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
  1252       // p3.
  1253       do_check_eq(this.readInt32(), recordSize);
  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);
  1268       this.readStringDelimiter(strLen);
  1270       // pin2.
  1271       do_check_eq(this.readString(), null);
  1273       if (!ril.v5Legacy) {
  1274         // AID. Ignore because it's from modem.
  1275         this.readInt32();
  1278       if (count == NUM_TESTS) {
  1279         run_next_test();
  1281     };
  1282     recordHelper.updateANR(pbr, recordNumber, expectedANR, expectedAdnRecordId);
  1285   do_test(pbr, "+123456789");
  1286   pbr.anr0.fileType = ICC_USIM_TYPE2_TAG;
  1287   do_test(pbr, "123456789", 1);
  1288 });
  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;
  1302   io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options)  {
  1303     let iap_1 = [0x01, 0x02];
  1305     // Write data size/
  1306     buf.writeInt32(iap_1.length * 2);
  1308     // Write iap.
  1309     for (let i = 0; i < iap_1.length; i++) {
  1310       helper.writeHexOctet(iap_1[i]);
  1313     // Write string delimiter.
  1314     buf.writeStringDelimiter(iap_1.length * 2);
  1316     recordSize = iap_1.length;
  1317     options.recordSize = recordSize;
  1318     if (options.callback) {
  1319       options.callback(options);
  1321   };
  1323   function doTestReadIAP(expectedIAP) {
  1324     const fileId = 0x4f17;
  1325     const recordNumber = 1;
  1327     let successCb = function successCb(iap) {
  1328       for (let i = 0; i < iap.length; i++) {
  1329         do_check_eq(expectedIAP[i], iap[i]);
  1331       run_next_test();
  1332     }.bind(this);
  1334     let errorCb = function errorCb(errorMsg) {
  1335       do_print(errorMsg);
  1336       do_check_true(false);
  1337       run_next_test();
  1338     }.bind(this);
  1340     record.readIAP(fileId, recordNumber, successCb, errorCb);
  1341   };
  1343   doTestReadIAP([1, 2]);
  1344 });
  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;
  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   };
  1373   function do_test(expectedIAP) {
  1374     buf.sendParcel = function() {
  1375       // Request Type.
  1376       do_check_eq(this.readInt32(), REQUEST_SIM_IO);
  1378       // Token : we don't care
  1379       this.readInt32();
  1381       // command.
  1382       do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
  1384       // fileId.
  1385       do_check_eq(this.readInt32(), fileId);
  1387       // pathId.
  1388       do_check_eq(this.readString(),
  1389                   EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK);
  1391       // p1.
  1392       do_check_eq(this.readInt32(), recordNumber);
  1394       // p2.
  1395       do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
  1397       // p3.
  1398       do_check_eq(this.readInt32(), recordSize);
  1400       // data.
  1401       let strLen = this.readInt32();
  1402       for (let i = 0; i < recordSize; i++) {
  1403         do_check_eq(expectedIAP[i], pduHelper.readHexOctet());
  1405       this.readStringDelimiter(strLen);
  1407       // pin2.
  1408       do_check_eq(this.readString(), null);
  1410       if (!ril.v5Legacy) {
  1411         // AID. Ignore because it's from modem.
  1412         this.readInt32();
  1415       run_next_test();
  1416     };
  1417     recordHelper.updateIAP(fileId, recordNumber, expectedIAP);
  1420   do_test([1, 2]);
  1421 });
  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;
  1435   ril.appType = CARD_APPTYPE_SIM;
  1436   const recordSize = 0x20;
  1437   let fileId;
  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   };
  1449   buf.sendParcel = function() {
  1450     // Request Type.
  1451     do_check_eq(this.readInt32(), REQUEST_SIM_IO);
  1453     // Token : we don't care
  1454     this.readInt32();
  1456     // command.
  1457     do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
  1459     // fileId.
  1460     do_check_eq(this.readInt32(), fileId);
  1462     // pathId.
  1463     do_check_eq(this.readString(), EF_PATH_MF_SIM + EF_PATH_DF_TELECOM);
  1465     // p1.
  1466     do_check_eq(this.readInt32(), 1);
  1468     // p2.
  1469     do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
  1471     // p3.
  1472     do_check_eq(this.readInt32(), 0x20);
  1474     // data.
  1475     let contact = pdu.readAlphaIdDiallingNumber(0x20);
  1476     do_check_eq(contact.alphaId, "test");
  1477     do_check_eq(contact.number, "123456");
  1479     // pin2.
  1480     if (fileId == ICC_EF_ADN) {
  1481       do_check_eq(this.readString(), null);
  1482     } else {
  1483       do_check_eq(this.readString(), "1111");
  1486     if (!ril.v5Legacy) {
  1487       // AID. Ignore because it's from modem.
  1488       this.readInt32();
  1491     if (fileId == ICC_EF_FDN) {
  1492       run_next_test();
  1494   };
  1496   fileId = ICC_EF_ADN;
  1497   record.updateADNLike(fileId,
  1498                        {recordId: 1, alphaId: "test", number: "123456"});
  1500   fileId = ICC_EF_FDN;
  1501   record.updateADNLike(fileId,
  1502                        {recordId: 1, alphaId: "test", number: "123456"},
  1503                        "1111");
  1504 });
  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;
  1517   function writeRecord (record) {
  1518     // Write data size
  1519     buf.writeInt32(record.length * 2);
  1521     for (let i = 0; i < record.length; i++) {
  1522       pduHelper.writeHexOctet(record[i]);
  1525     // Write string delimiter
  1526     buf.writeStringDelimiter(record.length * 2);
  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);
  1538   };
  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);
  1548   };
  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 });
  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;
  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];
  1581     // Override some functions to test.
  1582     contactHelper.getContactFieldRecordId = function(pbr, contact, field, onsuccess, onerror) {
  1583       onsuccess(1);
  1584     };
  1586     record.readPBR = function readPBR(onsuccess, onerror) {
  1587       onsuccess([{adn:{fileId: 0x6f3a}, email: {}, anr0: {}}]);
  1588     };
  1590     record.readADNLike = function readADNLike(fileId, onsuccess, onerror) {
  1591       onsuccess([{recordId: 1, alphaId: "name", number: "111111"}])
  1592     };
  1594     record.readEmail = function readEmail(fileId, fileType, recordNumber, onsuccess, onerror) {
  1595       onsuccess("hello@mail.com");
  1596     };
  1598     record.readANR = function readANR(fileId, fileType, recordNumber, onsuccess, onerror) {
  1599       onsuccess("123456");
  1600     };
  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]);
  1612     };
  1614     let onerror = function onerror(errorMsg) {
  1615       do_print("readICCContacts failed: " + errorMsg);
  1616       do_check_true(false);
  1617     };
  1619     contactHelper.readICCContacts(aSimType, aContactType, onsuccess, onerror);
  1622   let expectedContact1 = {
  1623     pbrIndex: 0,
  1624     recordId: 1,
  1625     alphaId:  "name",
  1626     number:   "111111"
  1627   };
  1629   let expectedContact2 = {
  1630     pbrIndex: 0,
  1631     recordId: 1,
  1632     alphaId:  "name",
  1633     number:   "111111",
  1634     email:    "hello@mail.com",
  1635     anr:      "123456"
  1636   };
  1638   // SIM
  1639   do_print("Test read SIM adn contacts");
  1640   do_test(CARD_APPTYPE_SIM, "adn", expectedContact1);
  1642   do_print("Test read SIM fdn contacts");
  1643   do_test(CARD_APPTYPE_SIM, "fdn", expectedContact1);
  1645   // USIM
  1646   do_print("Test read USIM adn contacts");
  1647   do_test(CARD_APPTYPE_USIM, "adn", expectedContact2);
  1649   do_print("Test read USIM fdn contacts");
  1650   do_test(CARD_APPTYPE_USIM, "fdn", expectedContact1);
  1652   // RUIM
  1653   do_print("Test read RUIM adn contacts");
  1654   do_test(CARD_APPTYPE_RUIM, "adn", expectedContact1);
  1656   do_print("Test read RUIM fdn contacts");
  1657   do_test(CARD_APPTYPE_RUIM, "fdn", expectedContact1);
  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);
  1663   do_print("Test read RUIM fdn contacts with enhanced phone book");
  1664   do_test(CARD_APPTYPE_RUIM, "fdn", expectedContact1, true);
  1666   run_next_test();
  1667 });
  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;
  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;
  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];
  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         }]);
  1715     };
  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);
  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     };
  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     };
  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     };
  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);
  1749       do_check_eq(email, aContact.email);
  1750       onsuccess();
  1751     };
  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);
  1760       if (Array.isArray(aContact.anr)) {
  1761         do_check_eq(number, aContact.anr[0]);
  1763       onsuccess();
  1764     };
  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;
  1773       onsuccess(recordId);
  1774     };
  1776     let isSuccess = false;
  1777     let onsuccess = function onsuccess() {
  1778       do_print("updateICCContact success");
  1779       isSuccess = true;
  1780     };
  1782     let onerror = function onerror(errorMsg) {
  1783       do_print("updateICCContact failed: " + errorMsg);
  1784     };
  1786     contactHelper.updateICCContact(aSimType, aContactType, aContact, aPin2, onsuccess, onerror);
  1787     do_check_true(isSuccess);
  1790   let contacts = [
  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.
  1801       pbrIndex: 0,
  1802       recordId: ADN_RECORD_ID,
  1803       alphaId:  "test2",
  1804       number:   "123456",
  1805     },
  1806     // a contact with email but no anr.
  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.
  1816       pbrIndex: 0,
  1817       recordId: ADN_RECORD_ID,
  1818       alphaId:  "test4",
  1819       number:   "123456",
  1820       anr:      ["+654321"]
  1821     }];
  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);
  1829     do_print("Test update SIM fdn contacts");
  1830     do_test(CARD_APPTYPE_SIM, "fdn", contact, "1234");
  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);
  1838     do_print("Test update USIM fdn contacts");
  1839     do_test(CARD_APPTYPE_USIM, "fdn", contact, "1234");
  1841     // RUIM
  1842     do_print("Test update RUIM adn contacts");
  1843     do_test(CARD_APPTYPE_RUIM, "adn", contact);
  1845     do_print("Test update RUIM fdn contacts");
  1846     do_test(CARD_APPTYPE_RUIM, "fdn", contact, "1234");
  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);
  1854     do_print("Test update RUIM fdn contacts with enhanced phone book");
  1855     do_test(CARD_APPTYPE_RUIM, "fdn", contact, "1234", null, true);
  1858   run_next_test();
  1859 });
  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;
  1872   let worker = newUint8Worker();
  1873   let context = worker.ContextPool._contexts[0];
  1874   let recordHelper = context.ICCRecordHelper;
  1875   let contactHelper = context.ICCContactHelper;
  1877   recordHelper.updateADNLike = function(fileId, contact, pin2, onsuccess, onerror) {
  1878     onsuccess();
  1879   };
  1881   let contact = {
  1882     pbrIndex: 0,
  1883     recordId: ADN_RECORD_ID,
  1884     alphaId:  "test2",
  1885     number:   "123456",
  1886   };
  1888   recordHelper.readIAP = function(fileId, recordNumber, onsuccess, onerror) {
  1889     onsuccess([EMAIL_RECORD_ID, ANR0_RECORD_ID]);
  1890   };
  1892   recordHelper.updateEmail = function(pbr, recordNumber, email, adnRecordId, onsuccess, onerror) {
  1893     do_check_true(email == null);
  1894     onsuccess();
  1895   };
  1897   recordHelper.updateANR = function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) {
  1898     do_check_true(number == null);
  1899     onsuccess();
  1900   };
  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}}]);
  1922     };
  1924     let successCb = function() {
  1925       do_check_true(true);
  1926     };
  1928     let errorCb = function(errorMsg) {
  1929       do_print(errorMsg);
  1930       do_check_true(false);
  1931     };
  1933     contactHelper.updateICCContact(CARD_APPTYPE_USIM, "adn", contact, null, successCb, errorCb);
  1936   do_test(ICC_USIM_TYPE1_TAG);
  1937   do_test(ICC_USIM_TYPE2_TAG);
  1939   run_next_test();
  1940 });
  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;
  1955   recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) {
  1956     if (records.length > MAX_RECORDS) {
  1957       onerror("No free record found.");
  1958       return;
  1961     onsuccess(records.length);
  1962   };
  1964   let successCb = function(pbrIndex, recordId) {
  1965     do_check_eq(pbrIndex, PBR_INDEX);
  1966     records[recordId] = {};
  1967   };
  1969   let errorCb = function(errorMsg) {
  1970     do_print(errorMsg);
  1971     do_check_true(false);
  1972   };
  1974   for (let i = 0; i < MAX_RECORDS; i++) {
  1975     contactHelper.findFreeICCContact(CARD_APPTYPE_SIM, "adn", successCb, errorCb);
  1977   // The 1st element, records[0], is null.
  1978   do_check_eq(records.length - 1, MAX_RECORDS);
  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   };
  1985   errorCb = function(errorMsg) {
  1986     do_check_true(errorMsg === "No free record found.");
  1987   };
  1988   contactHelper.findFreeICCContact(CARD_APPTYPE_SIM, "adn", successCb, errorCb);
  1990   run_next_test();
  1991 });
  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;
  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]}}];
  2010   recordHelper.readPBR = function readPBR(onsuccess, onerror) {
  2011     onsuccess(pbrs);
  2012   };
  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;
  2021     onsuccess(pbr.adn.records.length);
  2022   };
  2024   let successCb = function(pbrIndex, recordId) {
  2025     do_check_eq(pbrIndex, 0);
  2026     pbrs[pbrIndex].adn.records[recordId] = {};
  2027   };
  2029   let errorCb = function(errorMsg) {
  2030     do_check_true(false);
  2031   };
  2033   contactHelper.findFreeICCContact(CARD_APPTYPE_USIM, "adn", successCb, errorCb);
  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);
  2041   contactHelper.findFreeICCContact(CARD_APPTYPE_USIM, "adn", successCb, errorCb);
  2043   run_next_test();
  2044 });
  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;
  2054   function do_test(options, expectedErrorMsg) {
  2055     ril.sendChromeMessage = function(message) {
  2056       do_check_eq(message.errorMsg, expectedErrorMsg);
  2058     ril.readICCContacts(options);
  2061   // Error 1, didn't specify correct contactType.
  2062   do_test({}, CONTACT_ERR_REQUEST_NOT_SUPPORTED);
  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);
  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);
  2073   run_next_test();
  2074 });
  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;
  2084   const ICCID = "123456789";
  2085   ril.iccInfo.iccid = ICCID;
  2087   function do_test(options, expectedErrorMsg) {
  2088     ril.sendChromeMessage = function(message) {
  2089       do_check_eq(message.errorMsg, expectedErrorMsg);
  2091     ril.updateICCContact(options);
  2094   // Error 1, didn't specify correct contactType.
  2095   do_test({}, CONTACT_ERR_REQUEST_NOT_SUPPORTED);
  2097   // Error 2, specifying a correct contactType, but without providing 'contact'.
  2098   do_test({contactType: "adn"}, CONTACT_ERR_REQUEST_NOT_SUPPORTED);
  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);
  2104   // Error 4, without supplying pin2.
  2105   do_test({contactType: "fdn", contact: {contactId: ICCID + "1"}}, GECKO_ERROR_SIM_PIN2);
  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   };
  2113   let io = context.ICCIOHelper;
  2114   io.loadLinearFixedEF = function(options) {
  2115     options.totalRecords = 1;
  2116     options.p1 = 1;
  2117     options.callback(options);
  2118   };
  2120   do_test({contactType: "adn", contact: {}}, CONTACT_ERR_NO_FREE_RECORD_FOUND);
  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);
  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);
  2135   // Error 8, EF_PBR doesn't exist.
  2136   record.readPBR = function(onsuccess, onerror) {
  2137     onsuccess([]);
  2138   };
  2140   do_test({contactType: "adn", contact: {contactId: ICCID + "1"}},
  2141           CONTACT_ERR_CANNOT_ACCESS_PHONEBOOK);
  2143   run_next_test();
  2144 });
  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;
  2151   function do_test(errorCode, expectedErrorMsg) {
  2152     let called = false;
  2153     function errorCb(errorMsg) {
  2154       called = true;
  2155       do_check_eq(errorMsg, expectedErrorMsg);
  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);
  2167   for (let i = 0; i < ERROR_REJECTED_BY_REMOTE + 1; i++) {
  2168     do_test(i, RIL_ERROR_TO_GECKO_ERROR[i]);
  2171   run_next_test();
  2172 });
  2174 add_test(function test_personalization_state() {
  2175   let worker = newUint8Worker();
  2176   let context = worker.ContextPool._contexts[0];
  2177   let ril = context.RIL;
  2179   context.ICCRecordHelper.readICCID = function fakeReadICCID() {};
  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: [
  2188           app_state: CARD_APPSTATE_SUBSCRIPTION_PERSO,
  2189           perso_substate: cardPersoState
  2190         }],
  2191     };
  2193     ril._isCdma = isCdma;
  2194     ril._processICCStatus(iccStatus);
  2195     do_check_eq(ril.cardState, geckoCardState);
  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);
  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);
  2240   run_next_test();
  2241 });
  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;
  2251   context.ICCRecordHelper.readICCID = function fakeReadICCID() {};
  2253   function testCardAppState(cardAppState, geckoCardState) {
  2254     let iccStatus = {
  2255       cardState: CARD_STATE_PRESENT,
  2256       gsmUmtsSubscriptionAppIndex: 0,
  2257       apps: [
  2259         app_state: cardAppState
  2260       }],
  2261     };
  2263     ril._processICCStatus(iccStatus);
  2264     do_check_eq(ril.cardState, geckoCardState);
  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);
  2280   run_next_test();
  2281 });
  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;
  2291   context.ICCRecordHelper.readICCID = function fakeReadICCID() {};
  2293   function testPermanentBlocked(pin1_replaced, universalPINState, pin1) {
  2294     let iccStatus = {
  2295       cardState: CARD_STATE_PRESENT,
  2296       gsmUmtsSubscriptionAppIndex: 0,
  2297       universalPINState: universalPINState,
  2298       apps: [
  2300         pin1_replaced: pin1_replaced,
  2301         pin1: pin1
  2302       }]
  2303     };
  2305     ril._processICCStatus(iccStatus);
  2306     do_check_eq(ril.cardState, GECKO_CARDSTATE_PERMANENT_BLOCKED);
  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);
  2319   run_next_test();
  2320 });
  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;
  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;
  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";
  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;
  2348   const serviceClass = ICC_SERVICE_CLASS_VOICE |
  2349                        ICC_SERVICE_CLASS_DATA  |
  2350                        ICC_SERVICE_CLASS_FAX;
  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);
  2357       // Token : we don't care
  2358       this.readInt32();
  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     };
  2369     let lock = {lockType: aLock,
  2370                 enabled: aEnabled};
  2371     lock[GECKO_CARDLOCK_TO_PASSWORD_TYPE[aLock]] = aPassword;
  2373     ril.iccSetCardLock(lock);
  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);
  2381   run_next_test();
  2382 });
  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";
  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";
  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);
  2418       // Token : we don't care
  2419       this.readInt32();
  2421       let lockType = GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[aLock];
  2422       // Lock Type
  2423       do_check_eq(this.readInt32(), lockType);
  2425       // Pin/Puk.
  2426       do_check_eq(this.readString(), aPassword);
  2427     };
  2429     let lock = {lockType: aLock};
  2430     lock[GECKO_CARDLOCK_TO_PASSWORD_TYPE[aLock]] = aPassword;
  2431     ril.iccUnlockCardLock(lock);
  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);
  2451   run_next_test();
  2452 });
  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;
  2462   function do_test(imsi, mncLength, expectedMcc, expectedMnc) {
  2463     let result = helper.parseMccMncFromImsi(imsi, mncLength);
  2465     if (!imsi) {
  2466       do_check_eq(result, null);
  2467       return;
  2470     do_check_eq(result.mcc, expectedMcc);
  2471     do_check_eq(result.mnc, expectedMnc);
  2474   // Test the imsi is null.
  2475   do_test(null, null, null, null);
  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");
  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");
  2487   run_next_test();
  2488  });
  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;
  2502   function do_test(mncLengthInEf, imsi, expectedMcc, expectedMnc) {
  2503     ril.iccInfoPrivate.imsi = imsi;
  2505     io.loadTransparentEF = function fakeLoadTransparentEF(options) {
  2506       let ad = [0x00, 0x00, 0x00];
  2507       if (mncLengthInEf) {
  2508         ad.push(mncLengthInEf);
  2511       // Write data size
  2512       buf.writeInt32(ad.length * 2);
  2514       // Write data
  2515       for (let i = 0; i < ad.length; i++) {
  2516         helper.writeHexOctet(ad[i]);
  2519       // Write string delimiter
  2520       buf.writeStringDelimiter(ad.length * 2);
  2522       if (options.callback) {
  2523         options.callback(options);
  2525     };
  2527     record.readAD();
  2529     do_check_eq(ril.iccInfo.mcc, expectedMcc);
  2530     do_check_eq(ril.iccInfo.mnc, expectedMnc);
  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" );
  2538   run_next_test();
  2539 });
  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;
  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);
  2567       if (sst) {
  2568         sst[index] |= bitmask;
  2571     return sst;
  2574   ril.updateCellBroadcastConfig = function fakeUpdateCellBroadcastConfig() {
  2575     // Ignore updateCellBroadcastConfig after reading SST
  2576   };
  2578   function do_test(sst, supportedEf) {
  2579     // Clone supportedEf to local array for testing
  2580     let testEf = supportedEf.slice(0);
  2582     record.readMSISDN = function fakeReadMSISDN() {
  2583       testEf.splice(testEf.indexOf("MSISDN"), 1);
  2584     };
  2586     record.readMBDN = function fakeReadMBDN() {
  2587       testEf.splice(testEf.indexOf("MDN"), 1);
  2588     };
  2590     record.readMWIS = function fakeReadMWIS() {
  2591       testEf.splice(testEf.indexOf("MWIS"), 1);
  2592     };
  2594     io.loadTransparentEF = function fakeLoadTransparentEF(options) {
  2595       // Write data size
  2596       buf.writeInt32(sst.length * 2);
  2598       // Write data
  2599       for (let i = 0; i < sst.length; i++) {
  2600          gsmPdu.writeHexOctet(sst[i] || 0);
  2603       // Write string delimiter
  2604       buf.writeStringDelimiter(sst.length * 2);
  2606       if (options.callback) {
  2607         options.callback(options);
  2610       if (testEf.length !== 0) {
  2611         do_print("Un-handled EF: " + JSON.stringify(testEf));
  2612         do_check_true(false);
  2614     };
  2616     record.readSST();
  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);
  2626   run_next_test();
  2627 });
  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;
  2639   function testFetchSimRecordes(expectCalled) {
  2640     let ifCalled = [];
  2642     RIL.getIMSI = function() {
  2643       ifCalled.push("getIMSI");
  2644     };
  2646     simRecord.readAD = function() {
  2647       ifCalled.push("readAD");
  2648     };
  2650     simRecord.readSST = function() {
  2651       ifCalled.push("readSST");
  2652     };
  2654     simRecord.fetchSimRecords();
  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);
  2664   let expectCalled = ["getIMSI", "readAD", "readSST"];
  2665   testFetchSimRecordes(expectCalled);
  2667   run_next_test();
  2668 });
  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;
  2679   simRecord.fetchSimRecords = function() {
  2680     fetchTag = 0x01;
  2681   };
  2683   ruimRecord.fetchRuimRecords = function() {
  2684     fetchTag = 0x02;
  2685   };
  2687   RIL.appType = CARD_APPTYPE_SIM;
  2688   iccRecord.fetchICCRecords();
  2689   do_check_eq(fetchTag, 0x01);
  2691   RIL.appType = CARD_APPTYPE_RUIM;
  2692   iccRecord.fetchICCRecords();
  2693   do_check_eq(fetchTag, 0x02);
  2695   RIL.appType = CARD_APPTYPE_USIM;
  2696   iccRecord.fetchICCRecords();
  2697   do_check_eq(fetchTag, 0x01);
  2699   run_next_test();
  2700 });
  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;
  2715   worker.postMessage = function fakePostMessage(message) {
  2716     postedMessage = message;
  2717   };
  2719   io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
  2720     if (mwisData) {
  2721       // Write data size
  2722       buf.writeInt32(mwisData.length * 2);
  2724       // Write MWIS
  2725       for (let i = 0; i < mwisData.length; i++) {
  2726         helper.writeHexOctet(mwisData[i]);
  2729       // Write string delimiter
  2730       buf.writeStringDelimiter(mwisData.length * 2);
  2732       options.recordSize = mwisData.length;
  2733       if (options.callback) {
  2734         options.callback(options);
  2736     } else {
  2737       do_print("mwisData[] is not set.");
  2739   };
  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;
  2748     mwisData =  [ (isActive) ? 0x01 : 0x00,
  2749                   msgCount,
  2750                   0xFF, 0xFF, 0xFF ];
  2753   function do_test(isActive, msgCount) {
  2754     buildMwisData(isActive, msgCount);
  2755     recordHelper.readMWIS();
  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);
  2762   do_test(true, GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN);
  2763   do_test(true, 1);
  2764   do_test(true, 255);
  2766   do_test(false, 0);
  2767   do_test(false, 255); // Test the corner case when mwi is disable with incorrect msgCount.
  2769   run_next_test();
  2770 });
  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;
  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   };
  2797   function do_test(isActive, count) {
  2798     let mwis = ril.iccInfoPrivate.mwis;
  2799     let isUpdated = false;
  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;
  2806       return result;
  2809     buf.sendParcel = function() {
  2810       isUpdated = true;
  2812       // Request Type.
  2813       do_check_eq(this.readInt32(), REQUEST_SIM_IO);
  2815       // Token : we don't care
  2816       this.readInt32();
  2818       // command.
  2819       do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
  2821       // fileId.
  2822       do_check_eq(this.readInt32(), ICC_EF_MWIS);
  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));
  2828       // p1.
  2829       do_check_eq(this.readInt32(), recordNum);
  2831       // p2.
  2832       do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
  2834       // p3.
  2835       do_check_eq(this.readInt32(), recordSize);
  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());
  2844       this.readStringDelimiter(strLen);
  2846       // pin2.
  2847       do_check_eq(this.readString(), null);
  2849       if (!ril.v5Legacy) {
  2850         // AID. Ignore because it's from modem.
  2851         this.readInt32();
  2853     };
  2855     do_check_false(isUpdated);
  2857     recordHelper.updateMWIS({ active: isActive,
  2858                               msgCount: count });
  2860     do_check_true((ril.iccInfoPrivate.mwis) ? isUpdated : !isUpdated);
  2863   do_test(true, GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN);
  2864   do_test(true, 1);
  2865   do_test(true, 255);
  2867   do_test(false, 0);
  2869   // Test if Path ID is correct for SIM.
  2870   ril.appType = CARD_APPTYPE_SIM;
  2871   do_test(false, 0);
  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);
  2878   run_next_test();
  2879 });
  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;
  2898     });
  2900     _worker.debug = do_print;
  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         };
  2926     };
  2929   let workerHelper = newSmsOnSimWorkerHelper();
  2930   let worker = workerHelper.worker;
  2931   let context = worker.ContextPool._contexts[0];
  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";
  2944       workerHelper.fakeWokerBuffer();
  2946       context.Buf.writeString(SimSmsPduHex);
  2948       options.recordSize = 176; // Record length is fixed to 176 bytes.
  2949       if (options.callback) {
  2950         options.callback(options);
  2952   };
  2954   function newSmsOnSimParcel() {
  2955     let data = new Uint8Array(4 + 4); // Int32List with 1 element.
  2956     let offset = 0;
  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;
  2965     writeInt(1); // Length of Int32List
  2966     writeInt(1); // RecordNum = 1.
  2968     return newIncomingParcel(-1,
  2969                              RESPONSE_TYPE_UNSOLICITED,
  2970                              UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM,
  2971                              data);
  2974   function do_test() {
  2975     worker.onRILMessage(0, newSmsOnSimParcel());
  2977     let postedMessage = workerHelper.postedMessage;
  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);
  2985   do_test();
  2987   run_next_test();
  2988 });
  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;
  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];
  3011   for (let i = 0; i < tag_test.length; i++) {
  3012     pduHelper.writeHexOctet(tag_test[i]);
  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]);
  3020   tlv = berHelper.searchForNextTag(BER_FCP_FILE_IDENTIFIER_TAG, iter);
  3021   do_check_eq(tlv.value.fileId, 0x2FE2);
  3023   tlv = berHelper.searchForNextTag(BER_FCP_FILE_SIZE_DATA_TAG, iter);
  3024   do_check_eq(tlv.value.fileSizeData, 0x0A);
  3026   run_next_test();
  3027 });
  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;
  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];
  3049   for (let i = 0; i < tag_test.length; i++) {
  3050     pduHelper.writeHexOctet(tag_test[i]);
  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);
  3060   tlv = berHelper.searchForNextTag(BER_FCP_FILE_IDENTIFIER_TAG, iter);
  3061   do_check_eq(tlv.value.fileId, 0x6F40);
  3063   tlv = berHelper.searchForNextTag(BER_FCP_FILE_SIZE_DATA_TAG, iter);
  3064   do_check_eq(tlv.value.fileSizeData, 0x1A);
  3066   run_next_test();
  3067 });
  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;
  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   ];
  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]);
  3092     buf.writeStringDelimiter(strLen);
  3094     let options = {fileId: ICC_EF_ICCID,
  3095                    type: EF_TYPE_TRANSPARENT};
  3096     iccioHelper.processICCIOGetResponse(options);
  3098     do_check_eq(options.fileSize, 0x0A);
  3101   run_next_test();
  3102 });
  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;
  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   ];
  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]);
  3127     buf.writeStringDelimiter(strLen);
  3129     let options = {fileId: ICC_EF_MSISDN,
  3130                    type: EF_TYPE_LINEAR_FIXED};
  3131     iccioHelper.processICCIOGetResponse(options);
  3133     do_check_eq(options.fileSize, 0x1A);
  3134     do_check_eq(options.recordSize, 0x1A);
  3135     do_check_eq(options.totalRecords, 0x01);
  3138   run_next_test();
  3139 });
  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;
  3153   ril.reportStkServiceIsRunning = function fakeReportStkServiceIsRunning() {
  3154   };
  3156   function do_test(rawICCID, expectedICCID) {
  3157     io.loadTransparentEF = function fakeLoadTransparentEF(options) {
  3158       // Write data size
  3159       buf.writeInt32(rawICCID.length);
  3161       // Write data
  3162       for (let i = 0; i < rawICCID.length; i += 2) {
  3163         helper.writeHexOctet(parseInt(rawICCID.substr(i, 2), 16));
  3166       // Write string delimiter
  3167       buf.writeStringDelimiter(rawICCID.length);
  3169       if (options.callback) {
  3170         options.callback(options);
  3172     };
  3174     record.readICCID();
  3176     do_check_eq(ril.iccInfo.iccid, expectedICCID);
  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");
  3186   run_next_test();
  3187 });

mercurial