1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/system/gonk/tests/test_ril_worker_icc.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,3187 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + http://creativecommons.org/publicdomain/zero/1.0/ */ 1.6 + 1.7 +subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); 1.8 + 1.9 +function run_test() { 1.10 + run_next_test(); 1.11 +} 1.12 + 1.13 +/** 1.14 + * Helper function. 1.15 + */ 1.16 +function newUint8Worker() { 1.17 + let worker = newWorker(); 1.18 + let index = 0; // index for read 1.19 + let buf = []; 1.20 + 1.21 + let context = worker.ContextPool._contexts[0]; 1.22 + context.Buf.writeUint8 = function(value) { 1.23 + buf.push(value); 1.24 + }; 1.25 + 1.26 + context.Buf.readUint8 = function() { 1.27 + return buf[index++]; 1.28 + }; 1.29 + 1.30 + context.Buf.seekIncoming = function(offset) { 1.31 + index += offset; 1.32 + }; 1.33 + 1.34 + context.Buf.getReadAvailable = function() { 1.35 + return buf.length - index; 1.36 + }; 1.37 + 1.38 + worker.debug = do_print; 1.39 + 1.40 + return worker; 1.41 +} 1.42 + 1.43 +/** 1.44 + * Verify ICCPDUHelper#readICCUCS2String() 1.45 + */ 1.46 +add_test(function test_read_icc_ucs2_string() { 1.47 + let worker = newUint8Worker(); 1.48 + let context = worker.ContextPool._contexts[0]; 1.49 + let helper = context.GsmPDUHelper; 1.50 + let iccHelper = context.ICCPDUHelper; 1.51 + 1.52 + // 0x80 1.53 + let text = "TEST"; 1.54 + helper.writeUCS2String(text); 1.55 + // Also write two unused octets. 1.56 + let ffLen = 2; 1.57 + for (let i = 0; i < ffLen; i++) { 1.58 + helper.writeHexOctet(0xff); 1.59 + } 1.60 + do_check_eq(iccHelper.readICCUCS2String(0x80, (2 * text.length) + ffLen), text); 1.61 + 1.62 + // 0x81 1.63 + let array = [0x08, 0xd2, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, 1.64 + 0xff, 0xff]; 1.65 + let len = array.length; 1.66 + for (let i = 0; i < len; i++) { 1.67 + helper.writeHexOctet(array[i]); 1.68 + } 1.69 + do_check_eq(iccHelper.readICCUCS2String(0x81, len), "Mozilla\u694a"); 1.70 + 1.71 + // 0x82 1.72 + let array2 = [0x08, 0x69, 0x00, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 1.73 + 0xca, 0xff, 0xff]; 1.74 + let len2 = array2.length; 1.75 + for (let i = 0; i < len2; i++) { 1.76 + helper.writeHexOctet(array2[i]); 1.77 + } 1.78 + do_check_eq(iccHelper.readICCUCS2String(0x82, len2), "Mozilla\u694a"); 1.79 + 1.80 + run_next_test(); 1.81 +}); 1.82 + 1.83 +/** 1.84 + * Verify ICCPDUHelper#readDiallingNumber 1.85 + */ 1.86 +add_test(function test_read_dialling_number() { 1.87 + let worker = newUint8Worker(); 1.88 + let context = worker.ContextPool._contexts[0]; 1.89 + let helper = context.GsmPDUHelper; 1.90 + let iccHelper = context.ICCPDUHelper; 1.91 + let str = "123456789"; 1.92 + 1.93 + helper.readHexOctet = function() { 1.94 + return 0x81; 1.95 + }; 1.96 + 1.97 + helper.readSwappedNibbleBcdString = function(len) { 1.98 + return str.substring(0, len); 1.99 + }; 1.100 + 1.101 + for (let i = 0; i < str.length; i++) { 1.102 + do_check_eq(str.substring(0, i - 1), // -1 for the TON 1.103 + iccHelper.readDiallingNumber(i)); 1.104 + } 1.105 + 1.106 + run_next_test(); 1.107 +}); 1.108 + 1.109 +/** 1.110 + * Verify ICCPDUHelper#read8BitUnpackedToString 1.111 + */ 1.112 +add_test(function test_read_8bit_unpacked_to_string() { 1.113 + let worker = newUint8Worker(); 1.114 + let context = worker.ContextPool._contexts[0]; 1.115 + let helper = context.GsmPDUHelper; 1.116 + let iccHelper = context.ICCPDUHelper; 1.117 + const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; 1.118 + const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; 1.119 + 1.120 + // Test 1: Read GSM alphabets. 1.121 + // Write alphabets before ESCAPE. 1.122 + for (let i = 0; i < PDU_NL_EXTENDED_ESCAPE; i++) { 1.123 + helper.writeHexOctet(i); 1.124 + } 1.125 + 1.126 + // Write two ESCAPEs to make it become ' '. 1.127 + helper.writeHexOctet(PDU_NL_EXTENDED_ESCAPE); 1.128 + helper.writeHexOctet(PDU_NL_EXTENDED_ESCAPE); 1.129 + 1.130 + for (let i = PDU_NL_EXTENDED_ESCAPE + 1; i < langTable.length; i++) { 1.131 + helper.writeHexOctet(i); 1.132 + } 1.133 + 1.134 + // Also write two unused fields. 1.135 + let ffLen = 2; 1.136 + for (let i = 0; i < ffLen; i++) { 1.137 + helper.writeHexOctet(0xff); 1.138 + } 1.139 + 1.140 + do_check_eq(iccHelper.read8BitUnpackedToString(PDU_NL_EXTENDED_ESCAPE), 1.141 + langTable.substring(0, PDU_NL_EXTENDED_ESCAPE)); 1.142 + do_check_eq(iccHelper.read8BitUnpackedToString(2), " "); 1.143 + do_check_eq(iccHelper.read8BitUnpackedToString(langTable.length - 1.144 + PDU_NL_EXTENDED_ESCAPE - 1 + ffLen), 1.145 + langTable.substring(PDU_NL_EXTENDED_ESCAPE + 1)); 1.146 + 1.147 + // Test 2: Read GSM extended alphabets. 1.148 + for (let i = 0; i < langShiftTable.length; i++) { 1.149 + helper.writeHexOctet(PDU_NL_EXTENDED_ESCAPE); 1.150 + helper.writeHexOctet(i); 1.151 + } 1.152 + 1.153 + // Read string before RESERVED_CONTROL. 1.154 + do_check_eq(iccHelper.read8BitUnpackedToString(PDU_NL_RESERVED_CONTROL * 2), 1.155 + langShiftTable.substring(0, PDU_NL_RESERVED_CONTROL)); 1.156 + // ESCAPE + RESERVED_CONTROL will become ' '. 1.157 + do_check_eq(iccHelper.read8BitUnpackedToString(2), " "); 1.158 + // Read string between RESERVED_CONTROL and EXTENDED_ESCAPE. 1.159 + do_check_eq(iccHelper.read8BitUnpackedToString( 1.160 + (PDU_NL_EXTENDED_ESCAPE - PDU_NL_RESERVED_CONTROL - 1) * 2), 1.161 + langShiftTable.substring(PDU_NL_RESERVED_CONTROL + 1, 1.162 + PDU_NL_EXTENDED_ESCAPE)); 1.163 + // ESCAPE + ESCAPE will become ' '. 1.164 + do_check_eq(iccHelper.read8BitUnpackedToString(2), " "); 1.165 + // Read remaining string. 1.166 + do_check_eq(iccHelper.read8BitUnpackedToString( 1.167 + (langShiftTable.length - PDU_NL_EXTENDED_ESCAPE - 1) * 2), 1.168 + langShiftTable.substring(PDU_NL_EXTENDED_ESCAPE + 1)); 1.169 + 1.170 + run_next_test(); 1.171 +}); 1.172 + 1.173 +/** 1.174 + * Verify ICCPDUHelper#writeStringTo8BitUnpacked. 1.175 + * 1.176 + * Test writing GSM 8 bit alphabets. 1.177 + */ 1.178 +add_test(function test_write_string_to_8bit_unpacked() { 1.179 + let worker = newUint8Worker(); 1.180 + let context = worker.ContextPool._contexts[0]; 1.181 + let helper = context.GsmPDUHelper; 1.182 + let iccHelper = context.ICCPDUHelper; 1.183 + const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; 1.184 + const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; 1.185 + // Length of trailing 0xff. 1.186 + let ffLen = 2; 1.187 + let str; 1.188 + 1.189 + // Test 1, write GSM alphabets. 1.190 + iccHelper.writeStringTo8BitUnpacked(langTable.length + ffLen, langTable); 1.191 + 1.192 + for (let i = 0; i < langTable.length; i++) { 1.193 + do_check_eq(helper.readHexOctet(), i); 1.194 + } 1.195 + 1.196 + for (let i = 0; i < ffLen; i++) { 1.197 + do_check_eq(helper.readHexOctet(), 0xff); 1.198 + } 1.199 + 1.200 + // Test 2, write GSM extended alphabets. 1.201 + str = "\u000c\u20ac"; 1.202 + iccHelper.writeStringTo8BitUnpacked(4, str); 1.203 + 1.204 + do_check_eq(iccHelper.read8BitUnpackedToString(4), str); 1.205 + 1.206 + // Test 3, write GSM and GSM extended alphabets. 1.207 + // \u000c, \u20ac are from gsm extended alphabets. 1.208 + // \u00a3 is from gsm alphabet. 1.209 + str = "\u000c\u20ac\u00a3"; 1.210 + 1.211 + // 2 octets * 2 = 4 octets for 2 gsm extended alphabets, 1.212 + // 1 octet for 1 gsm alphabet, 1.213 + // 2 octes for trailing 0xff. 1.214 + // "Totally 7 octets are to be written." 1.215 + iccHelper.writeStringTo8BitUnpacked(7, str); 1.216 + 1.217 + do_check_eq(iccHelper.read8BitUnpackedToString(7), str); 1.218 + 1.219 + run_next_test(); 1.220 +}); 1.221 + 1.222 +/** 1.223 + * Verify ICCPDUHelper#writeStringTo8BitUnpacked with maximum octets written. 1.224 + */ 1.225 +add_test(function test_write_string_to_8bit_unpacked_with_max_octets_written() { 1.226 + let worker = newUint8Worker(); 1.227 + let context = worker.ContextPool._contexts[0]; 1.228 + let helper = context.GsmPDUHelper; 1.229 + let iccHelper = context.ICCPDUHelper; 1.230 + const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; 1.231 + const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; 1.232 + 1.233 + // The maximum of the number of octets that can be written is 3. 1.234 + // Only 3 characters shall be written even the length of the string is 4. 1.235 + iccHelper.writeStringTo8BitUnpacked(3, langTable.substring(0, 4)); 1.236 + helper.writeHexOctet(0xff); // dummy octet. 1.237 + for (let i = 0; i < 3; i++) { 1.238 + do_check_eq(helper.readHexOctet(), i); 1.239 + } 1.240 + do_check_false(helper.readHexOctet() == 4); 1.241 + 1.242 + // \u000c is GSM extended alphabet, 2 octets. 1.243 + // \u00a3 is GSM alphabet, 1 octet. 1.244 + let str = "\u000c\u00a3"; 1.245 + iccHelper.writeStringTo8BitUnpacked(3, str); 1.246 + do_check_eq(iccHelper.read8BitUnpackedToString(3), str); 1.247 + 1.248 + str = "\u00a3\u000c"; 1.249 + iccHelper.writeStringTo8BitUnpacked(3, str); 1.250 + do_check_eq(iccHelper.read8BitUnpackedToString(3), str); 1.251 + 1.252 + // 2 GSM extended alphabets cost 4 octets, but maximum is 3, so only the 1st 1.253 + // alphabet can be written. 1.254 + str = "\u000c\u000c"; 1.255 + iccHelper.writeStringTo8BitUnpacked(3, str); 1.256 + helper.writeHexOctet(0xff); // dummy octet. 1.257 + do_check_eq(iccHelper.read8BitUnpackedToString(4), str.substring(0, 1)); 1.258 + 1.259 + run_next_test(); 1.260 +}); 1.261 + 1.262 +/** 1.263 + * Verify ICCPDUHelper.readAlphaIdentifier 1.264 + */ 1.265 +add_test(function test_read_alpha_identifier() { 1.266 + let worker = newUint8Worker(); 1.267 + let context = worker.ContextPool._contexts[0]; 1.268 + let helper = context.GsmPDUHelper; 1.269 + let iccHelper = context.ICCPDUHelper; 1.270 + 1.271 + // UCS2: 0x80 1.272 + let text = "TEST"; 1.273 + helper.writeHexOctet(0x80); 1.274 + helper.writeUCS2String(text); 1.275 + // Also write two unused octets. 1.276 + let ffLen = 2; 1.277 + for (let i = 0; i < ffLen; i++) { 1.278 + helper.writeHexOctet(0xff); 1.279 + } 1.280 + do_check_eq(iccHelper.readAlphaIdentifier(1 + (2 * text.length) + ffLen), text); 1.281 + 1.282 + // UCS2: 0x81 1.283 + let array = [0x81, 0x08, 0xd2, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, 0xff, 0xff]; 1.284 + for (let i = 0; i < array.length; i++) { 1.285 + helper.writeHexOctet(array[i]); 1.286 + } 1.287 + do_check_eq(iccHelper.readAlphaIdentifier(array.length), "Mozilla\u694a"); 1.288 + 1.289 + // UCS2: 0x82 1.290 + let array2 = [0x82, 0x08, 0x69, 0x00, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, 0xff, 0xff]; 1.291 + for (let i = 0; i < array2.length; i++) { 1.292 + helper.writeHexOctet(array2[i]); 1.293 + } 1.294 + do_check_eq(iccHelper.readAlphaIdentifier(array2.length), "Mozilla\u694a"); 1.295 + 1.296 + // GSM 8 Bit Unpacked 1.297 + const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; 1.298 + for (let i = 0; i < PDU_NL_EXTENDED_ESCAPE; i++) { 1.299 + helper.writeHexOctet(i); 1.300 + } 1.301 + do_check_eq(iccHelper.readAlphaIdentifier(PDU_NL_EXTENDED_ESCAPE), 1.302 + langTable.substring(0, PDU_NL_EXTENDED_ESCAPE)); 1.303 + 1.304 + run_next_test(); 1.305 +}); 1.306 + 1.307 +/** 1.308 + * Verify ICCPDUHelper.writeAlphaIdentifier 1.309 + */ 1.310 +add_test(function test_write_alpha_identifier() { 1.311 + let worker = newUint8Worker(); 1.312 + let context = worker.ContextPool._contexts[0]; 1.313 + let helper = context.GsmPDUHelper; 1.314 + let iccHelper = context.ICCPDUHelper; 1.315 + // Length of trailing 0xff. 1.316 + let ffLen = 2; 1.317 + 1.318 + // Removal 1.319 + iccHelper.writeAlphaIdentifier(10, null); 1.320 + do_check_eq(iccHelper.readAlphaIdentifier(10), ""); 1.321 + 1.322 + // GSM 8 bit 1.323 + let str = "Mozilla"; 1.324 + iccHelper.writeAlphaIdentifier(str.length + ffLen, str); 1.325 + do_check_eq(iccHelper.readAlphaIdentifier(str.length + ffLen), str); 1.326 + 1.327 + // UCS2 1.328 + str = "Mozilla\u694a"; 1.329 + iccHelper.writeAlphaIdentifier(str.length * 2 + ffLen, str); 1.330 + // * 2 for each character will be encoded to UCS2 alphabets. 1.331 + do_check_eq(iccHelper.readAlphaIdentifier(str.length * 2 + ffLen), str); 1.332 + 1.333 + // Test with maximum octets written. 1.334 + // 1 coding scheme (0x80) and 1 UCS2 character, total 3 octets. 1.335 + str = "\u694a"; 1.336 + iccHelper.writeAlphaIdentifier(3, str); 1.337 + do_check_eq(iccHelper.readAlphaIdentifier(3), str); 1.338 + 1.339 + // 1 coding scheme (0x80) and 2 UCS2 characters, total 5 octets. 1.340 + // numOctets is limited to 4, so only 1 UCS2 character can be written. 1.341 + str = "\u694a\u694a"; 1.342 + iccHelper.writeAlphaIdentifier(4, str); 1.343 + helper.writeHexOctet(0xff); // dummy octet. 1.344 + do_check_eq(iccHelper.readAlphaIdentifier(5), str.substring(0, 1)); 1.345 + 1.346 + // Write 0 octet. 1.347 + iccHelper.writeAlphaIdentifier(0, "1"); 1.348 + helper.writeHexOctet(0xff); // dummy octet. 1.349 + do_check_eq(iccHelper.readAlphaIdentifier(1), ""); 1.350 + 1.351 + run_next_test(); 1.352 +}); 1.353 + 1.354 +/** 1.355 + * Verify ICCPDUHelper.readAlphaIdDiallingNumber 1.356 + */ 1.357 +add_test(function test_read_alpha_id_dialling_number() { 1.358 + let worker = newUint8Worker(); 1.359 + let context = worker.ContextPool._contexts[0]; 1.360 + let helper = context.GsmPDUHelper; 1.361 + let iccHelper = context.ICCPDUHelper; 1.362 + let buf = context.Buf; 1.363 + const recordSize = 32; 1.364 + 1.365 + function testReadAlphaIdDiallingNumber(contact) { 1.366 + iccHelper.readAlphaIdentifier = function() { 1.367 + return contact.alphaId; 1.368 + }; 1.369 + 1.370 + iccHelper.readNumberWithLength = function() { 1.371 + return contact.number; 1.372 + }; 1.373 + 1.374 + let strLen = recordSize * 2; 1.375 + buf.writeInt32(strLen); // fake length 1.376 + helper.writeHexOctet(0xff); // fake CCP 1.377 + helper.writeHexOctet(0xff); // fake EXT1 1.378 + buf.writeStringDelimiter(strLen); 1.379 + 1.380 + let contactR = iccHelper.readAlphaIdDiallingNumber(recordSize); 1.381 + if (contact.alphaId == "" && contact.number == "") { 1.382 + do_check_eq(contactR, null); 1.383 + } else { 1.384 + do_check_eq(contactR.alphaId, contact.alphaId); 1.385 + do_check_eq(contactR.number, contact.number); 1.386 + } 1.387 + } 1.388 + 1.389 + testReadAlphaIdDiallingNumber({alphaId: "AlphaId", number: "0987654321"}); 1.390 + testReadAlphaIdDiallingNumber({alphaId: "", number: ""}); 1.391 + 1.392 + run_next_test(); 1.393 +}); 1.394 + 1.395 +/** 1.396 + * Verify ICCPDUHelper.writeAlphaIdDiallingNumber 1.397 + */ 1.398 +add_test(function test_write_alpha_id_dialling_number() { 1.399 + let worker = newUint8Worker(); 1.400 + let context = worker.ContextPool._contexts[0]; 1.401 + let helper = context.ICCPDUHelper; 1.402 + const recordSize = 32; 1.403 + 1.404 + // Write a normal contact. 1.405 + let contactW = { 1.406 + alphaId: "Mozilla", 1.407 + number: "1234567890" 1.408 + }; 1.409 + helper.writeAlphaIdDiallingNumber(recordSize, contactW.alphaId, 1.410 + contactW.number); 1.411 + 1.412 + let contactR = helper.readAlphaIdDiallingNumber(recordSize); 1.413 + do_check_eq(contactW.alphaId, contactR.alphaId); 1.414 + do_check_eq(contactW.number, contactR.number); 1.415 + 1.416 + // Write a contact with alphaId encoded in UCS2 and number has '+'. 1.417 + let contactUCS2 = { 1.418 + alphaId: "火狐", 1.419 + number: "+1234567890" 1.420 + }; 1.421 + helper.writeAlphaIdDiallingNumber(recordSize, contactUCS2.alphaId, 1.422 + contactUCS2.number); 1.423 + contactR = helper.readAlphaIdDiallingNumber(recordSize); 1.424 + do_check_eq(contactUCS2.alphaId, contactR.alphaId); 1.425 + do_check_eq(contactUCS2.number, contactR.number); 1.426 + 1.427 + // Write a null contact (Removal). 1.428 + helper.writeAlphaIdDiallingNumber(recordSize); 1.429 + contactR = helper.readAlphaIdDiallingNumber(recordSize); 1.430 + do_check_eq(contactR, null); 1.431 + 1.432 + // Write a longer alphaId/dialling number 1.433 + // Dialling Number : Maximum 20 digits(10 octets). 1.434 + // Alpha Identifier: 32(recordSize) - 14 (10 octets for Dialling Number, 1 1.435 + // octet for TON/NPI, 1 for number length octet, and 2 for 1.436 + // Ext) = Maximum 18 octets. 1.437 + let longContact = { 1.438 + alphaId: "AAAAAAAAABBBBBBBBBCCCCCCCCC", 1.439 + number: "123456789012345678901234567890", 1.440 + }; 1.441 + helper.writeAlphaIdDiallingNumber(recordSize, longContact.alphaId, 1.442 + longContact.number); 1.443 + contactR = helper.readAlphaIdDiallingNumber(recordSize); 1.444 + do_check_eq(contactR.alphaId, "AAAAAAAAABBBBBBBBB"); 1.445 + do_check_eq(contactR.number, "12345678901234567890"); 1.446 + 1.447 + // Add '+' to number and test again. 1.448 + longContact.number = "+123456789012345678901234567890"; 1.449 + helper.writeAlphaIdDiallingNumber(recordSize, longContact.alphaId, 1.450 + longContact.number); 1.451 + contactR = helper.readAlphaIdDiallingNumber(recordSize); 1.452 + do_check_eq(contactR.alphaId, "AAAAAAAAABBBBBBBBB"); 1.453 + do_check_eq(contactR.number, "+12345678901234567890"); 1.454 + 1.455 + run_next_test(); 1.456 +}); 1.457 + 1.458 +/** 1.459 + * Verify ICCPDUHelper.writeDiallingNumber 1.460 + */ 1.461 +add_test(function test_write_dialling_number() { 1.462 + let worker = newUint8Worker(); 1.463 + let context = worker.ContextPool._contexts[0]; 1.464 + let helper = context.ICCPDUHelper; 1.465 + 1.466 + // with + 1.467 + let number = "+123456"; 1.468 + let len = 4; 1.469 + helper.writeDiallingNumber(number); 1.470 + do_check_eq(helper.readDiallingNumber(len), number); 1.471 + 1.472 + // without + 1.473 + number = "987654"; 1.474 + len = 4; 1.475 + helper.writeDiallingNumber(number); 1.476 + do_check_eq(helper.readDiallingNumber(len), number); 1.477 + 1.478 + number = "9876543"; 1.479 + len = 5; 1.480 + helper.writeDiallingNumber(number); 1.481 + do_check_eq(helper.readDiallingNumber(len), number); 1.482 + 1.483 + run_next_test(); 1.484 +}); 1.485 + 1.486 +/** 1.487 + * Verify ICCPDUHelper.readNumberWithLength 1.488 + */ 1.489 +add_test(function test_read_number_with_length() { 1.490 + let worker = newUint8Worker(); 1.491 + let context = worker.ContextPool._contexts[0]; 1.492 + let helper = context.GsmPDUHelper; 1.493 + let iccHelper = context.ICCPDUHelper; 1.494 + let number = "123456789"; 1.495 + 1.496 + iccHelper.readDiallingNumber = function(numLen) { 1.497 + return number.substring(0, numLen); 1.498 + }; 1.499 + 1.500 + helper.writeHexOctet(number.length + 1); 1.501 + helper.writeHexOctet(PDU_TOA_ISDN); 1.502 + do_check_eq(iccHelper.readNumberWithLength(), number); 1.503 + 1.504 + helper.writeHexOctet(0xff); 1.505 + do_check_eq(iccHelper.readNumberWithLength(), null); 1.506 + 1.507 + run_next_test(); 1.508 +}); 1.509 + 1.510 +/** 1.511 + * Verify ICCPDUHelper.writeNumberWithLength 1.512 + */ 1.513 +add_test(function test_write_number_with_length() { 1.514 + let worker = newUint8Worker(); 1.515 + let context = worker.ContextPool._contexts[0]; 1.516 + let helper = context.GsmPDUHelper; 1.517 + let iccHelper = context.ICCPDUHelper; 1.518 + 1.519 + function test(number, expectedNumber) { 1.520 + expectedNumber = expectedNumber || number; 1.521 + iccHelper.writeNumberWithLength(number); 1.522 + let numLen = helper.readHexOctet(); 1.523 + do_check_eq(expectedNumber, iccHelper.readDiallingNumber(numLen)); 1.524 + for (let i = 0; i < (ADN_MAX_BCD_NUMBER_BYTES - numLen); i++) { 1.525 + do_check_eq(0xff, helper.readHexOctet()); 1.526 + } 1.527 + } 1.528 + 1.529 + // without + 1.530 + test("123456789"); 1.531 + 1.532 + // with + 1.533 + test("+987654321"); 1.534 + 1.535 + // extended BCD coding 1.536 + test("1*2#3,4*5#6,"); 1.537 + 1.538 + // with + and extended BCD coding 1.539 + test("+1*2#3,4*5#6,"); 1.540 + 1.541 + // non-supported characters should not be written. 1.542 + test("(1)23-456+789", "123456789"); 1.543 + 1.544 + test("++(01)2*3-4#5,6+7(8)9*0#1,", "+012*34#5,6789*0#1,"); 1.545 + 1.546 + // null 1.547 + iccHelper.writeNumberWithLength(null); 1.548 + for (let i = 0; i < (ADN_MAX_BCD_NUMBER_BYTES + 1); i++) { 1.549 + do_check_eq(0xff, helper.readHexOctet()); 1.550 + } 1.551 + 1.552 + run_next_test(); 1.553 +}); 1.554 + 1.555 +/** 1.556 + * Verify GsmPDUHelper.writeTimestamp 1.557 + */ 1.558 +add_test(function test_write_timestamp() { 1.559 + let worker = newUint8Worker(); 1.560 + let context = worker.ContextPool._contexts[0]; 1.561 + let helper = context.GsmPDUHelper; 1.562 + 1.563 + // current date 1.564 + let dateInput = new Date(); 1.565 + let dateOutput = new Date(); 1.566 + helper.writeTimestamp(dateInput); 1.567 + dateOutput.setTime(helper.readTimestamp()); 1.568 + 1.569 + do_check_eq(dateInput.getFullYear(), dateOutput.getFullYear()); 1.570 + do_check_eq(dateInput.getMonth(), dateOutput.getMonth()); 1.571 + do_check_eq(dateInput.getDate(), dateOutput.getDate()); 1.572 + do_check_eq(dateInput.getHours(), dateOutput.getHours()); 1.573 + do_check_eq(dateInput.getMinutes(), dateOutput.getMinutes()); 1.574 + do_check_eq(dateInput.getSeconds(), dateOutput.getSeconds()); 1.575 + do_check_eq(dateInput.getTimezoneOffset(), dateOutput.getTimezoneOffset()); 1.576 + 1.577 + // 2034-01-23 12:34:56 -0800 GMT 1.578 + let time = Date.UTC(2034, 1, 23, 12, 34, 56); 1.579 + time = time - (8 * 60 * 60 * 1000); 1.580 + dateInput.setTime(time); 1.581 + helper.writeTimestamp(dateInput); 1.582 + dateOutput.setTime(helper.readTimestamp()); 1.583 + 1.584 + do_check_eq(dateInput.getFullYear(), dateOutput.getFullYear()); 1.585 + do_check_eq(dateInput.getMonth(), dateOutput.getMonth()); 1.586 + do_check_eq(dateInput.getDate(), dateOutput.getDate()); 1.587 + do_check_eq(dateInput.getHours(), dateOutput.getHours()); 1.588 + do_check_eq(dateInput.getMinutes(), dateOutput.getMinutes()); 1.589 + do_check_eq(dateInput.getSeconds(), dateOutput.getSeconds()); 1.590 + do_check_eq(dateInput.getTimezoneOffset(), dateOutput.getTimezoneOffset()); 1.591 + 1.592 + run_next_test(); 1.593 +}); 1.594 + 1.595 +/** 1.596 + * Verify GsmPDUHelper.octectToBCD and GsmPDUHelper.BCDToOctet 1.597 + */ 1.598 +add_test(function test_octect_BCD() { 1.599 + let worker = newUint8Worker(); 1.600 + let context = worker.ContextPool._contexts[0]; 1.601 + let helper = context.GsmPDUHelper; 1.602 + 1.603 + // 23 1.604 + let number = 23; 1.605 + let octet = helper.BCDToOctet(number); 1.606 + do_check_eq(helper.octetToBCD(octet), number); 1.607 + 1.608 + // 56 1.609 + number = 56; 1.610 + octet = helper.BCDToOctet(number); 1.611 + do_check_eq(helper.octetToBCD(octet), number); 1.612 + 1.613 + // 0x23 1.614 + octet = 0x23; 1.615 + number = helper.octetToBCD(octet); 1.616 + do_check_eq(helper.BCDToOctet(number), octet); 1.617 + 1.618 + // 0x56 1.619 + octet = 0x56; 1.620 + number = helper.octetToBCD(octet); 1.621 + do_check_eq(helper.BCDToOctet(number), octet); 1.622 + 1.623 + run_next_test(); 1.624 +}); 1.625 + 1.626 +/** 1.627 + * Verify ICCUtilsHelper.isICCServiceAvailable. 1.628 + */ 1.629 +add_test(function test_is_icc_service_available() { 1.630 + let worker = newUint8Worker(); 1.631 + let context = worker.ContextPool._contexts[0]; 1.632 + let ICCUtilsHelper = context.ICCUtilsHelper; 1.633 + let RIL = context.RIL; 1.634 + 1.635 + function test_table(sst, geckoService, simEnabled, usimEnabled) { 1.636 + RIL.iccInfoPrivate.sst = sst; 1.637 + RIL.appType = CARD_APPTYPE_SIM; 1.638 + do_check_eq(ICCUtilsHelper.isICCServiceAvailable(geckoService), simEnabled); 1.639 + RIL.appType = CARD_APPTYPE_USIM; 1.640 + do_check_eq(ICCUtilsHelper.isICCServiceAvailable(geckoService), usimEnabled); 1.641 + } 1.642 + 1.643 + test_table([0x08], "ADN", true, false); 1.644 + test_table([0x08], "FDN", false, false); 1.645 + test_table([0x08], "SDN", false, true); 1.646 + 1.647 + run_next_test(); 1.648 +}); 1.649 + 1.650 +/** 1.651 + * Verify ICCUtilsHelper.isGsm8BitAlphabet 1.652 + */ 1.653 +add_test(function test_is_gsm_8bit_alphabet() { 1.654 + let worker = newUint8Worker(); 1.655 + let context = worker.ContextPool._contexts[0]; 1.656 + let ICCUtilsHelper = context.ICCUtilsHelper; 1.657 + const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; 1.658 + const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; 1.659 + 1.660 + do_check_eq(ICCUtilsHelper.isGsm8BitAlphabet(langTable), true); 1.661 + do_check_eq(ICCUtilsHelper.isGsm8BitAlphabet(langShiftTable), true); 1.662 + do_check_eq(ICCUtilsHelper.isGsm8BitAlphabet("\uaaaa"), false); 1.663 + 1.664 + run_next_test(); 1.665 +}); 1.666 + 1.667 +/** 1.668 + * Verify RIL.iccGetCardLockState("fdn") 1.669 + */ 1.670 +add_test(function test_icc_get_card_lock_state_fdn() { 1.671 + let worker = newUint8Worker(); 1.672 + let context = worker.ContextPool._contexts[0]; 1.673 + let ril = context.RIL; 1.674 + let buf = context.Buf; 1.675 + 1.676 + buf.sendParcel = function() { 1.677 + // Request Type. 1.678 + do_check_eq(this.readInt32(), REQUEST_QUERY_FACILITY_LOCK) 1.679 + 1.680 + // Token : we don't care. 1.681 + this.readInt32(); 1.682 + 1.683 + // String Array Length. 1.684 + do_check_eq(this.readInt32(), ril.v5Legacy ? 3 : 4); 1.685 + 1.686 + // Facility. 1.687 + do_check_eq(this.readString(), ICC_CB_FACILITY_FDN); 1.688 + 1.689 + // Password. 1.690 + do_check_eq(this.readString(), ""); 1.691 + 1.692 + // Service class. 1.693 + do_check_eq(this.readString(), (ICC_SERVICE_CLASS_VOICE | 1.694 + ICC_SERVICE_CLASS_DATA | 1.695 + ICC_SERVICE_CLASS_FAX).toString()); 1.696 + 1.697 + if (!ril.v5Legacy) { 1.698 + // AID. Ignore because it's from modem. 1.699 + this.readInt32(); 1.700 + } 1.701 + 1.702 + run_next_test(); 1.703 + }; 1.704 + 1.705 + ril.iccGetCardLockState({lockType: "fdn"}); 1.706 +}); 1.707 + 1.708 +add_test(function test_get_network_name_from_icc() { 1.709 + let worker = newUint8Worker(); 1.710 + let context = worker.ContextPool._contexts[0]; 1.711 + let RIL = context.RIL; 1.712 + let ICCUtilsHelper = context.ICCUtilsHelper; 1.713 + 1.714 + function testGetNetworkNameFromICC(operatorData, expectedResult) { 1.715 + let result = ICCUtilsHelper.getNetworkNameFromICC(operatorData.mcc, 1.716 + operatorData.mnc, 1.717 + operatorData.lac); 1.718 + 1.719 + if (expectedResult == null) { 1.720 + do_check_eq(result, expectedResult); 1.721 + } else { 1.722 + do_check_eq(result.fullName, expectedResult.longName); 1.723 + do_check_eq(result.shortName, expectedResult.shortName); 1.724 + } 1.725 + } 1.726 + 1.727 + // Before EF_OPL and EF_PNN have been loaded. 1.728 + testGetNetworkNameFromICC({mcc: 123, mnc: 456, lac: 0x1000}, null); 1.729 + testGetNetworkNameFromICC({mcc: 321, mnc: 654, lac: 0x2000}, null); 1.730 + 1.731 + // Set HPLMN 1.732 + RIL.iccInfo.mcc = 123; 1.733 + RIL.iccInfo.mnc = 456; 1.734 + 1.735 + RIL.voiceRegistrationState = { 1.736 + cell: { 1.737 + gsmLocationAreaCode: 0x1000 1.738 + } 1.739 + }; 1.740 + RIL.operator = {}; 1.741 + 1.742 + // Set EF_PNN 1.743 + RIL.iccInfoPrivate = { 1.744 + PNN: [ 1.745 + {"fullName": "PNN1Long", "shortName": "PNN1Short"}, 1.746 + {"fullName": "PNN2Long", "shortName": "PNN2Short"}, 1.747 + {"fullName": "PNN3Long", "shortName": "PNN3Short"}, 1.748 + {"fullName": "PNN4Long", "shortName": "PNN4Short"} 1.749 + ] 1.750 + }; 1.751 + 1.752 + // EF_OPL isn't available and current isn't in HPLMN, 1.753 + testGetNetworkNameFromICC({mcc: 321, mnc: 654, lac: 0x1000}, null); 1.754 + 1.755 + // EF_OPL isn't available and current is in HPLMN, 1.756 + // the first record of PNN should be returned. 1.757 + testGetNetworkNameFromICC({mcc: 123, mnc: 456, lac: 0x1000}, 1.758 + {longName: "PNN1Long", shortName: "PNN1Short"}); 1.759 + 1.760 + // Set EF_OPL 1.761 + RIL.iccInfoPrivate.OPL = [ 1.762 + { 1.763 + "mcc": 123, 1.764 + "mnc": 456, 1.765 + "lacTacStart": 0, 1.766 + "lacTacEnd": 0xFFFE, 1.767 + "pnnRecordId": 4 1.768 + }, 1.769 + { 1.770 + "mcc": 321, 1.771 + "mnc": 654, 1.772 + "lacTacStart": 0, 1.773 + "lacTacEnd": 0x0010, 1.774 + "pnnRecordId": 3 1.775 + }, 1.776 + { 1.777 + "mcc": 321, 1.778 + "mnc": 654, 1.779 + "lacTacStart": 0x0100, 1.780 + "lacTacEnd": 0x1010, 1.781 + "pnnRecordId": 2 1.782 + } 1.783 + ]; 1.784 + 1.785 + // Both EF_PNN and EF_OPL are presented, and current PLMN is HPLMN, 1.786 + testGetNetworkNameFromICC({mcc: 123, mnc: 456, lac: 0x1000}, 1.787 + {longName: "PNN4Long", shortName: "PNN4Short"}); 1.788 + 1.789 + // Current PLMN is not HPLMN, and according to LAC, we should get 1.790 + // the second PNN record. 1.791 + testGetNetworkNameFromICC({mcc: 321, mnc: 654, lac: 0x1000}, 1.792 + {longName: "PNN2Long", shortName: "PNN2Short"}); 1.793 + 1.794 + // Current PLMN is not HPLMN, and according to LAC, we should get 1.795 + // the thrid PNN record. 1.796 + testGetNetworkNameFromICC({mcc: 321, mnc: 654, lac: 0x0001}, 1.797 + {longName: "PNN3Long", shortName: "PNN3Short"}); 1.798 + 1.799 + run_next_test(); 1.800 +}); 1.801 + 1.802 +add_test(function test_path_id_for_spid_and_spn() { 1.803 + let worker = newWorker({ 1.804 + postRILMessage: function(data) { 1.805 + // Do nothing 1.806 + }, 1.807 + postMessage: function(message) { 1.808 + // Do nothing 1.809 + }}); 1.810 + let context = worker.ContextPool._contexts[0]; 1.811 + let RIL = context.RIL; 1.812 + let ICCFileHelper = context.ICCFileHelper; 1.813 + 1.814 + // Test SIM 1.815 + RIL.appType = CARD_APPTYPE_SIM; 1.816 + do_check_eq(ICCFileHelper.getEFPath(ICC_EF_SPDI), 1.817 + EF_PATH_MF_SIM + EF_PATH_DF_GSM); 1.818 + do_check_eq(ICCFileHelper.getEFPath(ICC_EF_SPN), 1.819 + EF_PATH_MF_SIM + EF_PATH_DF_GSM); 1.820 + 1.821 + // Test USIM 1.822 + RIL.appType = CARD_APPTYPE_USIM; 1.823 + do_check_eq(ICCFileHelper.getEFPath(ICC_EF_SPDI), 1.824 + EF_PATH_MF_SIM + EF_PATH_ADF_USIM); 1.825 + do_check_eq(ICCFileHelper.getEFPath(ICC_EF_SPDI), 1.826 + EF_PATH_MF_SIM + EF_PATH_ADF_USIM); 1.827 + run_next_test(); 1.828 +}); 1.829 + 1.830 +/** 1.831 + * Verify ICCUtilsHelper.parsePbrTlvs 1.832 + */ 1.833 +add_test(function test_parse_pbr_tlvs() { 1.834 + let worker = newUint8Worker(); 1.835 + let context = worker.ContextPool._contexts[0]; 1.836 + let buf = context.Buf; 1.837 + 1.838 + let pbrTlvs = [ 1.839 + {tag: ICC_USIM_TYPE1_TAG, 1.840 + length: 0x0F, 1.841 + value: [{tag: ICC_USIM_EFADN_TAG, 1.842 + length: 0x03, 1.843 + value: [0x4F, 0x3A, 0x02]}, 1.844 + {tag: ICC_USIM_EFIAP_TAG, 1.845 + length: 0x03, 1.846 + value: [0x4F, 0x25, 0x01]}, 1.847 + {tag: ICC_USIM_EFPBC_TAG, 1.848 + length: 0x03, 1.849 + value: [0x4F, 0x09, 0x04]}] 1.850 + }, 1.851 + {tag: ICC_USIM_TYPE2_TAG, 1.852 + length: 0x05, 1.853 + value: [{tag: ICC_USIM_EFEMAIL_TAG, 1.854 + length: 0x03, 1.855 + value: [0x4F, 0x50, 0x0B]}, 1.856 + {tag: ICC_USIM_EFANR_TAG, 1.857 + length: 0x03, 1.858 + value: [0x4F, 0x11, 0x02]}, 1.859 + {tag: ICC_USIM_EFANR_TAG, 1.860 + length: 0x03, 1.861 + value: [0x4F, 0x12, 0x03]}] 1.862 + }, 1.863 + {tag: ICC_USIM_TYPE3_TAG, 1.864 + length: 0x0A, 1.865 + value: [{tag: ICC_USIM_EFCCP1_TAG, 1.866 + length: 0x03, 1.867 + value: [0x4F, 0x3D, 0x0A]}, 1.868 + {tag: ICC_USIM_EFEXT1_TAG, 1.869 + length: 0x03, 1.870 + value: [0x4F, 0x4A, 0x03]}] 1.871 + }, 1.872 + ]; 1.873 + 1.874 + let pbr = context.ICCUtilsHelper.parsePbrTlvs(pbrTlvs); 1.875 + do_check_eq(pbr.adn.fileId, 0x4F3a); 1.876 + do_check_eq(pbr.iap.fileId, 0x4F25); 1.877 + do_check_eq(pbr.pbc.fileId, 0x4F09); 1.878 + do_check_eq(pbr.email.fileId, 0x4F50); 1.879 + do_check_eq(pbr.anr0.fileId, 0x4f11); 1.880 + do_check_eq(pbr.anr1.fileId, 0x4f12); 1.881 + do_check_eq(pbr.ccp1.fileId, 0x4F3D); 1.882 + do_check_eq(pbr.ext1.fileId, 0x4F4A); 1.883 + 1.884 + run_next_test(); 1.885 +}); 1.886 + 1.887 +/** 1.888 + * Verify ICCIOHelper.loadLinearFixedEF with recordSize. 1.889 + */ 1.890 +add_test(function test_load_linear_fixed_ef() { 1.891 + let worker = newUint8Worker(); 1.892 + let context = worker.ContextPool._contexts[0]; 1.893 + let ril = context.RIL; 1.894 + let io = context.ICCIOHelper; 1.895 + 1.896 + io.getResponse = function fakeGetResponse(options) { 1.897 + // When recordSize is provided, loadLinearFixedEF should call iccIO directly. 1.898 + do_check_true(false); 1.899 + run_next_test(); 1.900 + }; 1.901 + 1.902 + ril.iccIO = function fakeIccIO(options) { 1.903 + do_check_true(true); 1.904 + run_next_test(); 1.905 + }; 1.906 + 1.907 + io.loadLinearFixedEF({recordSize: 0x20}); 1.908 +}); 1.909 + 1.910 +/** 1.911 + * Verify ICCIOHelper.loadLinearFixedEF without recordSize. 1.912 + */ 1.913 +add_test(function test_load_linear_fixed_ef() { 1.914 + let worker = newUint8Worker(); 1.915 + let context = worker.ContextPool._contexts[0]; 1.916 + let ril = context.RIL; 1.917 + let io = context.ICCIOHelper; 1.918 + 1.919 + io.getResponse = function fakeGetResponse(options) { 1.920 + do_check_true(true); 1.921 + run_next_test(); 1.922 + }; 1.923 + 1.924 + ril.iccIO = function fakeIccIO(options) { 1.925 + // When recordSize is not provided, loadLinearFixedEF should call getResponse. 1.926 + do_check_true(false); 1.927 + run_next_test(); 1.928 + }; 1.929 + 1.930 + io.loadLinearFixedEF({}); 1.931 +}); 1.932 + 1.933 +/** 1.934 + * Verify ICCRecordHelper.readPBR 1.935 + */ 1.936 +add_test(function test_read_pbr() { 1.937 + let worker = newUint8Worker(); 1.938 + let context = worker.ContextPool._contexts[0]; 1.939 + let helper = context.GsmPDUHelper; 1.940 + let record = context.ICCRecordHelper; 1.941 + let buf = context.Buf; 1.942 + let io = context.ICCIOHelper; 1.943 + 1.944 + io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { 1.945 + let pbr_1 = [ 1.946 + 0xa8, 0x05, 0xc0, 0x03, 0x4f, 0x3a, 0x01 1.947 + ]; 1.948 + 1.949 + // Write data size 1.950 + buf.writeInt32(pbr_1.length * 2); 1.951 + 1.952 + // Write pbr 1.953 + for (let i = 0; i < pbr_1.length; i++) { 1.954 + helper.writeHexOctet(pbr_1[i]); 1.955 + } 1.956 + 1.957 + // Write string delimiter 1.958 + buf.writeStringDelimiter(pbr_1.length * 2); 1.959 + 1.960 + options.totalRecords = 2; 1.961 + if (options.callback) { 1.962 + options.callback(options); 1.963 + } 1.964 + }; 1.965 + 1.966 + io.loadNextRecord = function fakeLoadNextRecord(options) { 1.967 + let pbr_2 = [ 1.968 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 1.969 + ]; 1.970 + 1.971 + options.p1++; 1.972 + if (options.callback) { 1.973 + options.callback(options); 1.974 + } 1.975 + }; 1.976 + 1.977 + let successCb = function successCb(pbrs) { 1.978 + do_check_eq(pbrs[0].adn.fileId, 0x4f3a); 1.979 + do_check_eq(pbrs.length, 1); 1.980 + }; 1.981 + 1.982 + let errorCb = function errorCb(errorMsg) { 1.983 + do_print("Reading EF_PBR failed, msg = " + errorMsg); 1.984 + do_check_true(false); 1.985 + }; 1.986 + 1.987 + record.readPBR(successCb, errorCb); 1.988 + 1.989 + // Check cache pbrs when 2nd call 1.990 + let ifLoadEF = false; 1.991 + io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { 1.992 + ifLoadEF = true; 1.993 + } 1.994 + record.readPBR(successCb, errorCb); 1.995 + do_check_false(ifLoadEF); 1.996 + 1.997 + run_next_test(); 1.998 +}); 1.999 + 1.1000 +/** 1.1001 + * Verify ICCRecordHelper.readEmail 1.1002 + */ 1.1003 +add_test(function test_read_email() { 1.1004 + let worker = newUint8Worker(); 1.1005 + let context = worker.ContextPool._contexts[0]; 1.1006 + let helper = context.GsmPDUHelper; 1.1007 + let record = context.ICCRecordHelper; 1.1008 + let buf = context.Buf; 1.1009 + let io = context.ICCIOHelper; 1.1010 + let recordSize; 1.1011 + 1.1012 + io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { 1.1013 + let email_1 = [ 1.1014 + 0x65, 0x6D, 0x61, 0x69, 0x6C, 1.1015 + 0x00, 0x6D, 0x6F, 0x7A, 0x69, 1.1016 + 0x6C, 0x6C, 0x61, 0x2E, 0x63, 1.1017 + 0x6F, 0x6D, 0x02, 0x23]; 1.1018 + 1.1019 + // Write data size 1.1020 + buf.writeInt32(email_1.length * 2); 1.1021 + 1.1022 + // Write email 1.1023 + for (let i = 0; i < email_1.length; i++) { 1.1024 + helper.writeHexOctet(email_1[i]); 1.1025 + } 1.1026 + 1.1027 + // Write string delimiter 1.1028 + buf.writeStringDelimiter(email_1.length * 2); 1.1029 + 1.1030 + recordSize = email_1.length; 1.1031 + options.recordSize = recordSize; 1.1032 + if (options.callback) { 1.1033 + options.callback(options); 1.1034 + } 1.1035 + }; 1.1036 + 1.1037 + function doTestReadEmail(type, expectedResult) { 1.1038 + let fileId = 0x6a75; 1.1039 + let recordNumber = 1; 1.1040 + 1.1041 + // fileId and recordNumber are dummy arguments. 1.1042 + record.readEmail(fileId, type, recordNumber, function(email) { 1.1043 + do_check_eq(email, expectedResult); 1.1044 + }); 1.1045 + }; 1.1046 + 1.1047 + doTestReadEmail(ICC_USIM_TYPE1_TAG, "email@mozilla.com$#"); 1.1048 + doTestReadEmail(ICC_USIM_TYPE2_TAG, "email@mozilla.com"); 1.1049 + do_check_eq(record._emailRecordSize, recordSize); 1.1050 + 1.1051 + run_next_test(); 1.1052 +}); 1.1053 + 1.1054 +/** 1.1055 + * Verify ICCRecordHelper.updateEmail 1.1056 + */ 1.1057 +add_test(function test_update_email() { 1.1058 + const recordSize = 0x20; 1.1059 + const recordNumber = 1; 1.1060 + const fileId = 0x4f50; 1.1061 + const NUM_TESTS = 2; 1.1062 + let worker = newUint8Worker(); 1.1063 + let context = worker.ContextPool._contexts[0]; 1.1064 + let pduHelper = context.GsmPDUHelper; 1.1065 + let iccHelper = context.ICCPDUHelper; 1.1066 + let ril = context.RIL; 1.1067 + ril.appType = CARD_APPTYPE_USIM; 1.1068 + let recordHelper = context.ICCRecordHelper; 1.1069 + let buf = context.Buf; 1.1070 + let ioHelper = context.ICCIOHelper; 1.1071 + let pbr = {email: {fileId: fileId, fileType: ICC_USIM_TYPE1_TAG}, 1.1072 + adn: {sfi: 1}}; 1.1073 + let count = 0; 1.1074 + 1.1075 + // Override. 1.1076 + ioHelper.updateLinearFixedEF = function(options) { 1.1077 + options.pathId = context.ICCFileHelper.getEFPath(options.fileId); 1.1078 + options.command = ICC_COMMAND_UPDATE_RECORD; 1.1079 + options.p1 = options.recordNumber; 1.1080 + options.p2 = READ_RECORD_ABSOLUTE_MODE; 1.1081 + options.p3 = recordSize; 1.1082 + ril.iccIO(options); 1.1083 + }; 1.1084 + 1.1085 + function do_test(pbr, expectedEmail, expectedAdnRecordId) { 1.1086 + buf.sendParcel = function() { 1.1087 + count++; 1.1088 + 1.1089 + // Request Type. 1.1090 + do_check_eq(this.readInt32(), REQUEST_SIM_IO); 1.1091 + 1.1092 + // Token : we don't care 1.1093 + this.readInt32(); 1.1094 + 1.1095 + // command. 1.1096 + do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD); 1.1097 + 1.1098 + // fileId. 1.1099 + do_check_eq(this.readInt32(), fileId); 1.1100 + 1.1101 + // pathId. 1.1102 + do_check_eq(this.readString(), 1.1103 + EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK); 1.1104 + 1.1105 + // p1. 1.1106 + do_check_eq(this.readInt32(), recordNumber); 1.1107 + 1.1108 + // p2. 1.1109 + do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE); 1.1110 + 1.1111 + // p3. 1.1112 + do_check_eq(this.readInt32(), recordSize); 1.1113 + 1.1114 + // data. 1.1115 + let strLen = this.readInt32(); 1.1116 + let email; 1.1117 + if (pbr.email.fileType === ICC_USIM_TYPE1_TAG) { 1.1118 + email = iccHelper.read8BitUnpackedToString(recordSize); 1.1119 + } else { 1.1120 + email = iccHelper.read8BitUnpackedToString(recordSize - 2); 1.1121 + do_check_eq(pduHelper.readHexOctet(), pbr.adn.sfi); 1.1122 + do_check_eq(pduHelper.readHexOctet(), expectedAdnRecordId); 1.1123 + } 1.1124 + this.readStringDelimiter(strLen); 1.1125 + do_check_eq(email, expectedEmail); 1.1126 + 1.1127 + // pin2. 1.1128 + do_check_eq(this.readString(), null); 1.1129 + 1.1130 + if (!ril.v5Legacy) { 1.1131 + // AID. Ignore because it's from modem. 1.1132 + this.readInt32(); 1.1133 + } 1.1134 + 1.1135 + if (count == NUM_TESTS) { 1.1136 + run_next_test(); 1.1137 + } 1.1138 + }; 1.1139 + recordHelper.updateEmail(pbr, recordNumber, expectedEmail, expectedAdnRecordId); 1.1140 + } 1.1141 + 1.1142 + do_test(pbr, "test@mail.com"); 1.1143 + pbr.email.fileType = ICC_USIM_TYPE2_TAG; 1.1144 + do_test(pbr, "test@mail.com", 1); 1.1145 +}); 1.1146 + 1.1147 +/** 1.1148 + * Verify ICCRecordHelper.readANR 1.1149 + */ 1.1150 +add_test(function test_read_anr() { 1.1151 + let worker = newUint8Worker(); 1.1152 + let context = worker.ContextPool._contexts[0]; 1.1153 + let helper = context.GsmPDUHelper; 1.1154 + let record = context.ICCRecordHelper; 1.1155 + let buf = context.Buf; 1.1156 + let io = context.ICCIOHelper; 1.1157 + let recordSize; 1.1158 + 1.1159 + io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { 1.1160 + let anr_1 = [ 1.1161 + 0x01, 0x05, 0x81, 0x10, 0x32, 1.1162 + 0x54, 0xF6, 0xFF, 0xFF]; 1.1163 + 1.1164 + // Write data size 1.1165 + buf.writeInt32(anr_1.length * 2); 1.1166 + 1.1167 + // Write anr 1.1168 + for (let i = 0; i < anr_1.length; i++) { 1.1169 + helper.writeHexOctet(anr_1[i]); 1.1170 + } 1.1171 + 1.1172 + // Write string delimiter 1.1173 + buf.writeStringDelimiter(anr_1.length * 2); 1.1174 + 1.1175 + recordSize = anr_1.length; 1.1176 + options.recordSize = recordSize; 1.1177 + if (options.callback) { 1.1178 + options.callback(options); 1.1179 + } 1.1180 + }; 1.1181 + 1.1182 + function doTestReadAnr(fileType, expectedResult) { 1.1183 + let fileId = 0x4f11; 1.1184 + let recordNumber = 1; 1.1185 + 1.1186 + // fileId and recordNumber are dummy arguments. 1.1187 + record.readANR(fileId, fileType, recordNumber, function(anr) { 1.1188 + do_check_eq(anr, expectedResult); 1.1189 + }); 1.1190 + }; 1.1191 + 1.1192 + doTestReadAnr(ICC_USIM_TYPE1_TAG, "0123456"); 1.1193 + do_check_eq(record._anrRecordSize, recordSize); 1.1194 + 1.1195 + run_next_test(); 1.1196 +}); 1.1197 + 1.1198 +/** 1.1199 + * Verify ICCRecordHelper.updateANR 1.1200 + */ 1.1201 +add_test(function test_update_anr() { 1.1202 + const recordSize = 0x20; 1.1203 + const recordNumber = 1; 1.1204 + const fileId = 0x4f11; 1.1205 + const NUM_TESTS = 2; 1.1206 + let worker = newUint8Worker(); 1.1207 + let context = worker.ContextPool._contexts[0]; 1.1208 + let pduHelper = context.GsmPDUHelper; 1.1209 + let iccHelper = context.ICCPDUHelper; 1.1210 + let ril = context.RIL; 1.1211 + ril.appType = CARD_APPTYPE_USIM; 1.1212 + let recordHelper = context.ICCRecordHelper; 1.1213 + let buf = context.Buf; 1.1214 + let ioHelper = context.ICCIOHelper; 1.1215 + let pbr = {anr0: {fileId: fileId, fileType: ICC_USIM_TYPE1_TAG}, 1.1216 + adn: {sfi: 1}}; 1.1217 + let count = 0; 1.1218 + 1.1219 + // Override. 1.1220 + ioHelper.updateLinearFixedEF = function(options) { 1.1221 + options.pathId = context.ICCFileHelper.getEFPath(options.fileId); 1.1222 + options.command = ICC_COMMAND_UPDATE_RECORD; 1.1223 + options.p1 = options.recordNumber; 1.1224 + options.p2 = READ_RECORD_ABSOLUTE_MODE; 1.1225 + options.p3 = recordSize; 1.1226 + ril.iccIO(options); 1.1227 + }; 1.1228 + 1.1229 + function do_test(pbr, expectedANR, expectedAdnRecordId) { 1.1230 + buf.sendParcel = function() { 1.1231 + count++; 1.1232 + 1.1233 + // Request Type. 1.1234 + do_check_eq(this.readInt32(), REQUEST_SIM_IO); 1.1235 + 1.1236 + // Token : we don't care 1.1237 + this.readInt32(); 1.1238 + 1.1239 + // command. 1.1240 + do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD); 1.1241 + 1.1242 + // fileId. 1.1243 + do_check_eq(this.readInt32(), fileId); 1.1244 + 1.1245 + // pathId. 1.1246 + do_check_eq(this.readString(), 1.1247 + EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK); 1.1248 + 1.1249 + // p1. 1.1250 + do_check_eq(this.readInt32(), recordNumber); 1.1251 + 1.1252 + // p2. 1.1253 + do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE); 1.1254 + 1.1255 + // p3. 1.1256 + do_check_eq(this.readInt32(), recordSize); 1.1257 + 1.1258 + // data. 1.1259 + let strLen = this.readInt32(); 1.1260 + // EF_AAS, ignore. 1.1261 + pduHelper.readHexOctet(); 1.1262 + do_check_eq(iccHelper.readNumberWithLength(), expectedANR); 1.1263 + // EF_CCP, ignore. 1.1264 + pduHelper.readHexOctet(); 1.1265 + // EF_EXT1, ignore. 1.1266 + pduHelper.readHexOctet(); 1.1267 + if (pbr.anr0.fileType === ICC_USIM_TYPE2_TAG) { 1.1268 + do_check_eq(pduHelper.readHexOctet(), pbr.adn.sfi); 1.1269 + do_check_eq(pduHelper.readHexOctet(), expectedAdnRecordId); 1.1270 + } 1.1271 + this.readStringDelimiter(strLen); 1.1272 + 1.1273 + // pin2. 1.1274 + do_check_eq(this.readString(), null); 1.1275 + 1.1276 + if (!ril.v5Legacy) { 1.1277 + // AID. Ignore because it's from modem. 1.1278 + this.readInt32(); 1.1279 + } 1.1280 + 1.1281 + if (count == NUM_TESTS) { 1.1282 + run_next_test(); 1.1283 + } 1.1284 + }; 1.1285 + recordHelper.updateANR(pbr, recordNumber, expectedANR, expectedAdnRecordId); 1.1286 + } 1.1287 + 1.1288 + do_test(pbr, "+123456789"); 1.1289 + pbr.anr0.fileType = ICC_USIM_TYPE2_TAG; 1.1290 + do_test(pbr, "123456789", 1); 1.1291 +}); 1.1292 + 1.1293 +/** 1.1294 + * Verify ICCRecordHelper.readIAP 1.1295 + */ 1.1296 +add_test(function test_read_iap() { 1.1297 + let worker = newUint8Worker(); 1.1298 + let context = worker.ContextPool._contexts[0]; 1.1299 + let helper = context.GsmPDUHelper; 1.1300 + let record = context.ICCRecordHelper; 1.1301 + let buf = context.Buf; 1.1302 + let io = context.ICCIOHelper; 1.1303 + let recordSize; 1.1304 + 1.1305 + io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { 1.1306 + let iap_1 = [0x01, 0x02]; 1.1307 + 1.1308 + // Write data size/ 1.1309 + buf.writeInt32(iap_1.length * 2); 1.1310 + 1.1311 + // Write iap. 1.1312 + for (let i = 0; i < iap_1.length; i++) { 1.1313 + helper.writeHexOctet(iap_1[i]); 1.1314 + } 1.1315 + 1.1316 + // Write string delimiter. 1.1317 + buf.writeStringDelimiter(iap_1.length * 2); 1.1318 + 1.1319 + recordSize = iap_1.length; 1.1320 + options.recordSize = recordSize; 1.1321 + if (options.callback) { 1.1322 + options.callback(options); 1.1323 + } 1.1324 + }; 1.1325 + 1.1326 + function doTestReadIAP(expectedIAP) { 1.1327 + const fileId = 0x4f17; 1.1328 + const recordNumber = 1; 1.1329 + 1.1330 + let successCb = function successCb(iap) { 1.1331 + for (let i = 0; i < iap.length; i++) { 1.1332 + do_check_eq(expectedIAP[i], iap[i]); 1.1333 + } 1.1334 + run_next_test(); 1.1335 + }.bind(this); 1.1336 + 1.1337 + let errorCb = function errorCb(errorMsg) { 1.1338 + do_print(errorMsg); 1.1339 + do_check_true(false); 1.1340 + run_next_test(); 1.1341 + }.bind(this); 1.1342 + 1.1343 + record.readIAP(fileId, recordNumber, successCb, errorCb); 1.1344 + }; 1.1345 + 1.1346 + doTestReadIAP([1, 2]); 1.1347 +}); 1.1348 + 1.1349 +/** 1.1350 + * Verify ICCRecordHelper.updateIAP 1.1351 + */ 1.1352 +add_test(function test_update_iap() { 1.1353 + const recordSize = 2; 1.1354 + const recordNumber = 1; 1.1355 + const fileId = 0x4f17; 1.1356 + let worker = newUint8Worker(); 1.1357 + let context = worker.ContextPool._contexts[0]; 1.1358 + let pduHelper = context.GsmPDUHelper; 1.1359 + let ril = context.RIL; 1.1360 + ril.appType = CARD_APPTYPE_USIM; 1.1361 + let recordHelper = context.ICCRecordHelper; 1.1362 + let buf = context.Buf; 1.1363 + let ioHelper = context.ICCIOHelper; 1.1364 + let count = 0; 1.1365 + 1.1366 + // Override. 1.1367 + ioHelper.updateLinearFixedEF = function(options) { 1.1368 + options.pathId = context.ICCFileHelper.getEFPath(options.fileId); 1.1369 + options.command = ICC_COMMAND_UPDATE_RECORD; 1.1370 + options.p1 = options.recordNumber; 1.1371 + options.p2 = READ_RECORD_ABSOLUTE_MODE; 1.1372 + options.p3 = recordSize; 1.1373 + ril.iccIO(options); 1.1374 + }; 1.1375 + 1.1376 + function do_test(expectedIAP) { 1.1377 + buf.sendParcel = function() { 1.1378 + // Request Type. 1.1379 + do_check_eq(this.readInt32(), REQUEST_SIM_IO); 1.1380 + 1.1381 + // Token : we don't care 1.1382 + this.readInt32(); 1.1383 + 1.1384 + // command. 1.1385 + do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD); 1.1386 + 1.1387 + // fileId. 1.1388 + do_check_eq(this.readInt32(), fileId); 1.1389 + 1.1390 + // pathId. 1.1391 + do_check_eq(this.readString(), 1.1392 + EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK); 1.1393 + 1.1394 + // p1. 1.1395 + do_check_eq(this.readInt32(), recordNumber); 1.1396 + 1.1397 + // p2. 1.1398 + do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE); 1.1399 + 1.1400 + // p3. 1.1401 + do_check_eq(this.readInt32(), recordSize); 1.1402 + 1.1403 + // data. 1.1404 + let strLen = this.readInt32(); 1.1405 + for (let i = 0; i < recordSize; i++) { 1.1406 + do_check_eq(expectedIAP[i], pduHelper.readHexOctet()); 1.1407 + } 1.1408 + this.readStringDelimiter(strLen); 1.1409 + 1.1410 + // pin2. 1.1411 + do_check_eq(this.readString(), null); 1.1412 + 1.1413 + if (!ril.v5Legacy) { 1.1414 + // AID. Ignore because it's from modem. 1.1415 + this.readInt32(); 1.1416 + } 1.1417 + 1.1418 + run_next_test(); 1.1419 + }; 1.1420 + recordHelper.updateIAP(fileId, recordNumber, expectedIAP); 1.1421 + } 1.1422 + 1.1423 + do_test([1, 2]); 1.1424 +}); 1.1425 + 1.1426 +/** 1.1427 + * Verify ICCRecordHelper.updateADNLike. 1.1428 + */ 1.1429 +add_test(function test_update_adn_like() { 1.1430 + let worker = newUint8Worker(); 1.1431 + let context = worker.ContextPool._contexts[0]; 1.1432 + let ril = context.RIL; 1.1433 + let record = context.ICCRecordHelper; 1.1434 + let io = context.ICCIOHelper; 1.1435 + let pdu = context.ICCPDUHelper; 1.1436 + let buf = context.Buf; 1.1437 + 1.1438 + ril.appType = CARD_APPTYPE_SIM; 1.1439 + const recordSize = 0x20; 1.1440 + let fileId; 1.1441 + 1.1442 + // Override. 1.1443 + io.updateLinearFixedEF = function(options) { 1.1444 + options.pathId = context.ICCFileHelper.getEFPath(options.fileId); 1.1445 + options.command = ICC_COMMAND_UPDATE_RECORD; 1.1446 + options.p1 = options.recordNumber; 1.1447 + options.p2 = READ_RECORD_ABSOLUTE_MODE; 1.1448 + options.p3 = recordSize; 1.1449 + ril.iccIO(options); 1.1450 + }; 1.1451 + 1.1452 + buf.sendParcel = function() { 1.1453 + // Request Type. 1.1454 + do_check_eq(this.readInt32(), REQUEST_SIM_IO); 1.1455 + 1.1456 + // Token : we don't care 1.1457 + this.readInt32(); 1.1458 + 1.1459 + // command. 1.1460 + do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD); 1.1461 + 1.1462 + // fileId. 1.1463 + do_check_eq(this.readInt32(), fileId); 1.1464 + 1.1465 + // pathId. 1.1466 + do_check_eq(this.readString(), EF_PATH_MF_SIM + EF_PATH_DF_TELECOM); 1.1467 + 1.1468 + // p1. 1.1469 + do_check_eq(this.readInt32(), 1); 1.1470 + 1.1471 + // p2. 1.1472 + do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE); 1.1473 + 1.1474 + // p3. 1.1475 + do_check_eq(this.readInt32(), 0x20); 1.1476 + 1.1477 + // data. 1.1478 + let contact = pdu.readAlphaIdDiallingNumber(0x20); 1.1479 + do_check_eq(contact.alphaId, "test"); 1.1480 + do_check_eq(contact.number, "123456"); 1.1481 + 1.1482 + // pin2. 1.1483 + if (fileId == ICC_EF_ADN) { 1.1484 + do_check_eq(this.readString(), null); 1.1485 + } else { 1.1486 + do_check_eq(this.readString(), "1111"); 1.1487 + } 1.1488 + 1.1489 + if (!ril.v5Legacy) { 1.1490 + // AID. Ignore because it's from modem. 1.1491 + this.readInt32(); 1.1492 + } 1.1493 + 1.1494 + if (fileId == ICC_EF_FDN) { 1.1495 + run_next_test(); 1.1496 + } 1.1497 + }; 1.1498 + 1.1499 + fileId = ICC_EF_ADN; 1.1500 + record.updateADNLike(fileId, 1.1501 + {recordId: 1, alphaId: "test", number: "123456"}); 1.1502 + 1.1503 + fileId = ICC_EF_FDN; 1.1504 + record.updateADNLike(fileId, 1.1505 + {recordId: 1, alphaId: "test", number: "123456"}, 1.1506 + "1111"); 1.1507 +}); 1.1508 + 1.1509 +/** 1.1510 + * Verify ICCRecordHelper.findFreeRecordId. 1.1511 + */ 1.1512 +add_test(function test_find_free_record_id() { 1.1513 + let worker = newUint8Worker(); 1.1514 + let context = worker.ContextPool._contexts[0]; 1.1515 + let pduHelper = context.GsmPDUHelper; 1.1516 + let recordHelper = context.ICCRecordHelper; 1.1517 + let buf = context.Buf; 1.1518 + let io = context.ICCIOHelper; 1.1519 + 1.1520 + function writeRecord (record) { 1.1521 + // Write data size 1.1522 + buf.writeInt32(record.length * 2); 1.1523 + 1.1524 + for (let i = 0; i < record.length; i++) { 1.1525 + pduHelper.writeHexOctet(record[i]); 1.1526 + } 1.1527 + 1.1528 + // Write string delimiter 1.1529 + buf.writeStringDelimiter(record.length * 2); 1.1530 + } 1.1531 + 1.1532 + io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { 1.1533 + // Some random data. 1.1534 + let record = [0x12, 0x34, 0x56, 0x78, 0x90]; 1.1535 + options.p1 = 1; 1.1536 + options.totalRecords = 2; 1.1537 + writeRecord(record); 1.1538 + if (options.callback) { 1.1539 + options.callback(options); 1.1540 + } 1.1541 + }; 1.1542 + 1.1543 + io.loadNextRecord = function fakeLoadNextRecord(options) { 1.1544 + // Unused bytes. 1.1545 + let record = [0xff, 0xff, 0xff, 0xff, 0xff]; 1.1546 + options.p1++; 1.1547 + writeRecord(record); 1.1548 + if (options.callback) { 1.1549 + options.callback(options); 1.1550 + } 1.1551 + }; 1.1552 + 1.1553 + let fileId = 0x0000; // Dummy. 1.1554 + recordHelper.findFreeRecordId( 1.1555 + fileId, 1.1556 + function(recordId) { 1.1557 + do_check_eq(recordId, 2); 1.1558 + run_next_test(); 1.1559 + }.bind(this), 1.1560 + function(errorMsg) { 1.1561 + do_print(errorMsg); 1.1562 + do_check_true(false); 1.1563 + run_next_test(); 1.1564 + }.bind(this)); 1.1565 +}); 1.1566 + 1.1567 +/** 1.1568 + * Verify ICCContactHelper.readICCContacts 1.1569 + */ 1.1570 +add_test(function test_read_icc_contacts() { 1.1571 + let worker = newUint8Worker(); 1.1572 + let context = worker.ContextPool._contexts[0]; 1.1573 + let record = context.ICCRecordHelper; 1.1574 + let contactHelper = context.ICCContactHelper; 1.1575 + let ril = context.RIL; 1.1576 + 1.1577 + function do_test(aSimType, aContactType, aExpectedContact, aEnhancedPhoneBook) { 1.1578 + ril.appType = aSimType; 1.1579 + ril._isCdma = (aSimType === CARD_APPTYPE_RUIM); 1.1580 + ril.iccInfoPrivate.cst = (aEnhancedPhoneBook) ? 1.1581 + [0x0, 0x0C, 0x0, 0x0, 0x0]: 1.1582 + [0x0, 0x00, 0x0, 0x0, 0x0]; 1.1583 + 1.1584 + // Override some functions to test. 1.1585 + contactHelper.getContactFieldRecordId = function(pbr, contact, field, onsuccess, onerror) { 1.1586 + onsuccess(1); 1.1587 + }; 1.1588 + 1.1589 + record.readPBR = function readPBR(onsuccess, onerror) { 1.1590 + onsuccess([{adn:{fileId: 0x6f3a}, email: {}, anr0: {}}]); 1.1591 + }; 1.1592 + 1.1593 + record.readADNLike = function readADNLike(fileId, onsuccess, onerror) { 1.1594 + onsuccess([{recordId: 1, alphaId: "name", number: "111111"}]) 1.1595 + }; 1.1596 + 1.1597 + record.readEmail = function readEmail(fileId, fileType, recordNumber, onsuccess, onerror) { 1.1598 + onsuccess("hello@mail.com"); 1.1599 + }; 1.1600 + 1.1601 + record.readANR = function readANR(fileId, fileType, recordNumber, onsuccess, onerror) { 1.1602 + onsuccess("123456"); 1.1603 + }; 1.1604 + 1.1605 + let onsuccess = function onsuccess(contacts) { 1.1606 + let contact = contacts[0]; 1.1607 + for (let key in contact) { 1.1608 + do_print("check " + key); 1.1609 + if (Array.isArray(contact[key])) { 1.1610 + do_check_eq(contact[key][0], aExpectedContact[key]); 1.1611 + } else { 1.1612 + do_check_eq(contact[key], aExpectedContact[key]); 1.1613 + } 1.1614 + } 1.1615 + }; 1.1616 + 1.1617 + let onerror = function onerror(errorMsg) { 1.1618 + do_print("readICCContacts failed: " + errorMsg); 1.1619 + do_check_true(false); 1.1620 + }; 1.1621 + 1.1622 + contactHelper.readICCContacts(aSimType, aContactType, onsuccess, onerror); 1.1623 + } 1.1624 + 1.1625 + let expectedContact1 = { 1.1626 + pbrIndex: 0, 1.1627 + recordId: 1, 1.1628 + alphaId: "name", 1.1629 + number: "111111" 1.1630 + }; 1.1631 + 1.1632 + let expectedContact2 = { 1.1633 + pbrIndex: 0, 1.1634 + recordId: 1, 1.1635 + alphaId: "name", 1.1636 + number: "111111", 1.1637 + email: "hello@mail.com", 1.1638 + anr: "123456" 1.1639 + }; 1.1640 + 1.1641 + // SIM 1.1642 + do_print("Test read SIM adn contacts"); 1.1643 + do_test(CARD_APPTYPE_SIM, "adn", expectedContact1); 1.1644 + 1.1645 + do_print("Test read SIM fdn contacts"); 1.1646 + do_test(CARD_APPTYPE_SIM, "fdn", expectedContact1); 1.1647 + 1.1648 + // USIM 1.1649 + do_print("Test read USIM adn contacts"); 1.1650 + do_test(CARD_APPTYPE_USIM, "adn", expectedContact2); 1.1651 + 1.1652 + do_print("Test read USIM fdn contacts"); 1.1653 + do_test(CARD_APPTYPE_USIM, "fdn", expectedContact1); 1.1654 + 1.1655 + // RUIM 1.1656 + do_print("Test read RUIM adn contacts"); 1.1657 + do_test(CARD_APPTYPE_RUIM, "adn", expectedContact1); 1.1658 + 1.1659 + do_print("Test read RUIM fdn contacts"); 1.1660 + do_test(CARD_APPTYPE_RUIM, "fdn", expectedContact1); 1.1661 + 1.1662 + // RUIM with enhanced phone book 1.1663 + do_print("Test read RUIM adn contacts with enhanced phone book"); 1.1664 + do_test(CARD_APPTYPE_RUIM, "adn", expectedContact2, true); 1.1665 + 1.1666 + do_print("Test read RUIM fdn contacts with enhanced phone book"); 1.1667 + do_test(CARD_APPTYPE_RUIM, "fdn", expectedContact1, true); 1.1668 + 1.1669 + run_next_test(); 1.1670 +}); 1.1671 + 1.1672 +/** 1.1673 + * Verify ICCContactHelper.updateICCContact with appType is CARD_APPTYPE_USIM. 1.1674 + */ 1.1675 +add_test(function test_update_icc_contact() { 1.1676 + const ADN_RECORD_ID = 100; 1.1677 + const ADN_SFI = 1; 1.1678 + const IAP_FILE_ID = 0x4f17; 1.1679 + const EMAIL_FILE_ID = 0x4f50; 1.1680 + const EMAIL_RECORD_ID = 20; 1.1681 + const ANR0_FILE_ID = 0x4f11; 1.1682 + const ANR0_RECORD_ID = 30; 1.1683 + 1.1684 + let worker = newUint8Worker(); 1.1685 + let context = worker.ContextPool._contexts[0]; 1.1686 + let recordHelper = context.ICCRecordHelper; 1.1687 + let contactHelper = context.ICCContactHelper; 1.1688 + let ril = context.RIL; 1.1689 + 1.1690 + function do_test(aSimType, aContactType, aContact, aPin2, aFileType, aHaveIapIndex, aEnhancedPhoneBook) { 1.1691 + ril.appType = aSimType; 1.1692 + ril._isCdma = (aSimType === CARD_APPTYPE_RUIM); 1.1693 + ril.iccInfoPrivate.cst = (aEnhancedPhoneBook) ? [0x0, 0x0C, 0x0, 0x0, 0x0] 1.1694 + : [0x0, 0x00, 0x0, 0x0, 0x0]; 1.1695 + 1.1696 + recordHelper.readPBR = function(onsuccess, onerror) { 1.1697 + if (aFileType === ICC_USIM_TYPE1_TAG) { 1.1698 + onsuccess([{ 1.1699 + adn: {fileId: ICC_EF_ADN}, 1.1700 + email: {fileId: EMAIL_FILE_ID, 1.1701 + fileType: ICC_USIM_TYPE1_TAG}, 1.1702 + anr0: {fileId: ANR0_FILE_ID, 1.1703 + fileType: ICC_USIM_TYPE1_TAG} 1.1704 + }]); 1.1705 + } else if (aFileType === ICC_USIM_TYPE2_TAG) { 1.1706 + onsuccess([{ 1.1707 + adn: {fileId: ICC_EF_ADN, 1.1708 + sfi: ADN_SFI}, 1.1709 + iap: {fileId: IAP_FILE_ID}, 1.1710 + email: {fileId: EMAIL_FILE_ID, 1.1711 + fileType: ICC_USIM_TYPE2_TAG, 1.1712 + indexInIAP: 0}, 1.1713 + anr0: {fileId: ANR0_FILE_ID, 1.1714 + fileType: ICC_USIM_TYPE2_TAG, 1.1715 + indexInIAP: 1} 1.1716 + }]); 1.1717 + } 1.1718 + }; 1.1719 + 1.1720 + recordHelper.updateADNLike = function(fileId, contact, pin2, onsuccess, onerror) { 1.1721 + if (aContactType === "fdn") { 1.1722 + do_check_eq(fileId, ICC_EF_FDN); 1.1723 + } else if (aContactType === "adn") { 1.1724 + do_check_eq(fileId, ICC_EF_ADN); 1.1725 + } 1.1726 + do_check_eq(pin2, aPin2); 1.1727 + do_check_eq(contact.alphaId, aContact.alphaId); 1.1728 + do_check_eq(contact.number, aContact.number); 1.1729 + onsuccess(); 1.1730 + }; 1.1731 + 1.1732 + recordHelper.readIAP = function(fileId, recordNumber, onsuccess, onerror) { 1.1733 + do_check_eq(fileId, IAP_FILE_ID); 1.1734 + do_check_eq(recordNumber, ADN_RECORD_ID); 1.1735 + onsuccess((aHaveIapIndex) ? [EMAIL_RECORD_ID, ANR0_RECORD_ID] 1.1736 + : [0xff, 0xff]); 1.1737 + }; 1.1738 + 1.1739 + recordHelper.updateIAP = function(fileId, recordNumber, iap, onsuccess, onerror) { 1.1740 + do_check_eq(fileId, IAP_FILE_ID); 1.1741 + do_check_eq(recordNumber, ADN_RECORD_ID); 1.1742 + onsuccess(); 1.1743 + }; 1.1744 + 1.1745 + recordHelper.updateEmail = function(pbr, recordNumber, email, adnRecordId, onsuccess, onerror) { 1.1746 + do_check_eq(pbr.email.fileId, EMAIL_FILE_ID); 1.1747 + if (pbr.email.fileType === ICC_USIM_TYPE1_TAG) { 1.1748 + do_check_eq(recordNumber, ADN_RECORD_ID); 1.1749 + } else if (pbr.email.fileType === ICC_USIM_TYPE2_TAG) { 1.1750 + do_check_eq(recordNumber, EMAIL_RECORD_ID); 1.1751 + } 1.1752 + do_check_eq(email, aContact.email); 1.1753 + onsuccess(); 1.1754 + }; 1.1755 + 1.1756 + recordHelper.updateANR = function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) { 1.1757 + do_check_eq(pbr.anr0.fileId, ANR0_FILE_ID); 1.1758 + if (pbr.anr0.fileType === ICC_USIM_TYPE1_TAG) { 1.1759 + do_check_eq(recordNumber, ADN_RECORD_ID); 1.1760 + } else if (pbr.anr0.fileType === ICC_USIM_TYPE2_TAG) { 1.1761 + do_check_eq(recordNumber, ANR0_RECORD_ID); 1.1762 + } 1.1763 + if (Array.isArray(aContact.anr)) { 1.1764 + do_check_eq(number, aContact.anr[0]); 1.1765 + } 1.1766 + onsuccess(); 1.1767 + }; 1.1768 + 1.1769 + recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) { 1.1770 + let recordId = 0; 1.1771 + if (fileId === EMAIL_FILE_ID) { 1.1772 + recordId = EMAIL_RECORD_ID; 1.1773 + } else if (fileId === ANR0_FILE_ID) { 1.1774 + recordId = ANR0_RECORD_ID; 1.1775 + } 1.1776 + onsuccess(recordId); 1.1777 + }; 1.1778 + 1.1779 + let isSuccess = false; 1.1780 + let onsuccess = function onsuccess() { 1.1781 + do_print("updateICCContact success"); 1.1782 + isSuccess = true; 1.1783 + }; 1.1784 + 1.1785 + let onerror = function onerror(errorMsg) { 1.1786 + do_print("updateICCContact failed: " + errorMsg); 1.1787 + }; 1.1788 + 1.1789 + contactHelper.updateICCContact(aSimType, aContactType, aContact, aPin2, onsuccess, onerror); 1.1790 + do_check_true(isSuccess); 1.1791 + } 1.1792 + 1.1793 + let contacts = [ 1.1794 + { 1.1795 + pbrIndex: 0, 1.1796 + recordId: ADN_RECORD_ID, 1.1797 + alphaId: "test", 1.1798 + number: "123456", 1.1799 + email: "test@mail.com", 1.1800 + anr: ["+654321"] 1.1801 + }, 1.1802 + // a contact without email and anr. 1.1803 + { 1.1804 + pbrIndex: 0, 1.1805 + recordId: ADN_RECORD_ID, 1.1806 + alphaId: "test2", 1.1807 + number: "123456", 1.1808 + }, 1.1809 + // a contact with email but no anr. 1.1810 + { 1.1811 + pbrIndex: 0, 1.1812 + recordId: ADN_RECORD_ID, 1.1813 + alphaId: "test3", 1.1814 + number: "123456", 1.1815 + email: "test@mail.com" 1.1816 + }, 1.1817 + // a contact with anr but no email. 1.1818 + { 1.1819 + pbrIndex: 0, 1.1820 + recordId: ADN_RECORD_ID, 1.1821 + alphaId: "test4", 1.1822 + number: "123456", 1.1823 + anr: ["+654321"] 1.1824 + }]; 1.1825 + 1.1826 + for (let i = 0; i < contacts.length; i++) { 1.1827 + let contact = contacts[i]; 1.1828 + // SIM 1.1829 + do_print("Test update SIM adn contacts"); 1.1830 + do_test(CARD_APPTYPE_SIM, "adn", contact); 1.1831 + 1.1832 + do_print("Test update SIM fdn contacts"); 1.1833 + do_test(CARD_APPTYPE_SIM, "fdn", contact, "1234"); 1.1834 + 1.1835 + // USIM 1.1836 + do_print("Test update USIM adn contacts"); 1.1837 + do_test(CARD_APPTYPE_USIM, "adn", contact, null, ICC_USIM_TYPE1_TAG); 1.1838 + do_test(CARD_APPTYPE_USIM, "adn", contact, null, ICC_USIM_TYPE2_TAG, true); 1.1839 + do_test(CARD_APPTYPE_USIM, "adn", contact, null, ICC_USIM_TYPE2_TAG, false); 1.1840 + 1.1841 + do_print("Test update USIM fdn contacts"); 1.1842 + do_test(CARD_APPTYPE_USIM, "fdn", contact, "1234"); 1.1843 + 1.1844 + // RUIM 1.1845 + do_print("Test update RUIM adn contacts"); 1.1846 + do_test(CARD_APPTYPE_RUIM, "adn", contact); 1.1847 + 1.1848 + do_print("Test update RUIM fdn contacts"); 1.1849 + do_test(CARD_APPTYPE_RUIM, "fdn", contact, "1234"); 1.1850 + 1.1851 + // RUIM with enhanced phone book 1.1852 + do_print("Test update RUIM adn contacts with enhanced phone book"); 1.1853 + do_test(CARD_APPTYPE_RUIM, "adn", contact, null, ICC_USIM_TYPE1_TAG, null, true); 1.1854 + do_test(CARD_APPTYPE_RUIM, "adn", contact, null, ICC_USIM_TYPE2_TAG, true, true); 1.1855 + do_test(CARD_APPTYPE_RUIM, "adn", contact, null, ICC_USIM_TYPE2_TAG, false, true); 1.1856 + 1.1857 + do_print("Test update RUIM fdn contacts with enhanced phone book"); 1.1858 + do_test(CARD_APPTYPE_RUIM, "fdn", contact, "1234", null, true); 1.1859 + } 1.1860 + 1.1861 + run_next_test(); 1.1862 +}); 1.1863 + 1.1864 +/** 1.1865 + * Verify updateICCContact with removal of anr and email with File Type 1. 1.1866 + */ 1.1867 +add_test(function test_update_icc_contact_with_remove_type1_attr() { 1.1868 + const ADN_RECORD_ID = 100; 1.1869 + const IAP_FILE_ID = 0x4f17; 1.1870 + const EMAIL_FILE_ID = 0x4f50; 1.1871 + const EMAIL_RECORD_ID = 20; 1.1872 + const ANR0_FILE_ID = 0x4f11; 1.1873 + const ANR0_RECORD_ID = 30; 1.1874 + 1.1875 + let worker = newUint8Worker(); 1.1876 + let context = worker.ContextPool._contexts[0]; 1.1877 + let recordHelper = context.ICCRecordHelper; 1.1878 + let contactHelper = context.ICCContactHelper; 1.1879 + 1.1880 + recordHelper.updateADNLike = function(fileId, contact, pin2, onsuccess, onerror) { 1.1881 + onsuccess(); 1.1882 + }; 1.1883 + 1.1884 + let contact = { 1.1885 + pbrIndex: 0, 1.1886 + recordId: ADN_RECORD_ID, 1.1887 + alphaId: "test2", 1.1888 + number: "123456", 1.1889 + }; 1.1890 + 1.1891 + recordHelper.readIAP = function(fileId, recordNumber, onsuccess, onerror) { 1.1892 + onsuccess([EMAIL_RECORD_ID, ANR0_RECORD_ID]); 1.1893 + }; 1.1894 + 1.1895 + recordHelper.updateEmail = function(pbr, recordNumber, email, adnRecordId, onsuccess, onerror) { 1.1896 + do_check_true(email == null); 1.1897 + onsuccess(); 1.1898 + }; 1.1899 + 1.1900 + recordHelper.updateANR = function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) { 1.1901 + do_check_true(number == null); 1.1902 + onsuccess(); 1.1903 + }; 1.1904 + 1.1905 + function do_test(type) { 1.1906 + recordHelper.readPBR = function(onsuccess, onerror) { 1.1907 + if (type == ICC_USIM_TYPE1_TAG) { 1.1908 + onsuccess([{ 1.1909 + adn: {fileId: ICC_EF_ADN}, 1.1910 + email: {fileId: EMAIL_FILE_ID, 1.1911 + fileType: ICC_USIM_TYPE1_TAG}, 1.1912 + anr0: {fileId: ANR0_FILE_ID, 1.1913 + fileType: ICC_USIM_TYPE1_TAG}}]); 1.1914 + } else { 1.1915 + onsuccess([{ 1.1916 + adn: {fileId: ICC_EF_ADN}, 1.1917 + iap: {fileId: IAP_FILE_ID}, 1.1918 + email: {fileId: EMAIL_FILE_ID, 1.1919 + fileType: ICC_USIM_TYPE2_TAG, 1.1920 + indexInIAP: 0}, 1.1921 + anr0: {fileId: ANR0_FILE_ID, 1.1922 + fileType: ICC_USIM_TYPE2_TAG, 1.1923 + indexInIAP: 1}}]); 1.1924 + } 1.1925 + }; 1.1926 + 1.1927 + let successCb = function() { 1.1928 + do_check_true(true); 1.1929 + }; 1.1930 + 1.1931 + let errorCb = function(errorMsg) { 1.1932 + do_print(errorMsg); 1.1933 + do_check_true(false); 1.1934 + }; 1.1935 + 1.1936 + contactHelper.updateICCContact(CARD_APPTYPE_USIM, "adn", contact, null, successCb, errorCb); 1.1937 + } 1.1938 + 1.1939 + do_test(ICC_USIM_TYPE1_TAG); 1.1940 + do_test(ICC_USIM_TYPE2_TAG); 1.1941 + 1.1942 + run_next_test(); 1.1943 +}); 1.1944 + 1.1945 +/** 1.1946 + * Verify ICCContactHelper.findFreeICCContact in SIM 1.1947 + */ 1.1948 +add_test(function test_find_free_icc_contact_sim() { 1.1949 + let worker = newUint8Worker(); 1.1950 + let context = worker.ContextPool._contexts[0]; 1.1951 + let recordHelper = context.ICCRecordHelper; 1.1952 + let contactHelper = context.ICCContactHelper; 1.1953 + // Correct record Id starts with 1, so put a null element at index 0. 1.1954 + let records = [null]; 1.1955 + const MAX_RECORDS = 3; 1.1956 + const PBR_INDEX = 0; 1.1957 + 1.1958 + recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) { 1.1959 + if (records.length > MAX_RECORDS) { 1.1960 + onerror("No free record found."); 1.1961 + return; 1.1962 + } 1.1963 + 1.1964 + onsuccess(records.length); 1.1965 + }; 1.1966 + 1.1967 + let successCb = function(pbrIndex, recordId) { 1.1968 + do_check_eq(pbrIndex, PBR_INDEX); 1.1969 + records[recordId] = {}; 1.1970 + }; 1.1971 + 1.1972 + let errorCb = function(errorMsg) { 1.1973 + do_print(errorMsg); 1.1974 + do_check_true(false); 1.1975 + }; 1.1976 + 1.1977 + for (let i = 0; i < MAX_RECORDS; i++) { 1.1978 + contactHelper.findFreeICCContact(CARD_APPTYPE_SIM, "adn", successCb, errorCb); 1.1979 + } 1.1980 + // The 1st element, records[0], is null. 1.1981 + do_check_eq(records.length - 1, MAX_RECORDS); 1.1982 + 1.1983 + // Now the EF is full, so finding a free one should result failure. 1.1984 + successCb = function(pbrIndex, recordId) { 1.1985 + do_check_true(false); 1.1986 + }; 1.1987 + 1.1988 + errorCb = function(errorMsg) { 1.1989 + do_check_true(errorMsg === "No free record found."); 1.1990 + }; 1.1991 + contactHelper.findFreeICCContact(CARD_APPTYPE_SIM, "adn", successCb, errorCb); 1.1992 + 1.1993 + run_next_test(); 1.1994 +}); 1.1995 + 1.1996 +/** 1.1997 + * Verify ICCContactHelper.findFreeICCContact in USIM 1.1998 + */ 1.1999 +add_test(function test_find_free_icc_contact_usim() { 1.2000 + let worker = newUint8Worker(); 1.2001 + let context = worker.ContextPool._contexts[0]; 1.2002 + let recordHelper = context.ICCRecordHelper; 1.2003 + let contactHelper = context.ICCContactHelper; 1.2004 + const ADN1_FILE_ID = 0x6f3a; 1.2005 + const ADN2_FILE_ID = 0x6f3b; 1.2006 + const MAX_RECORDS = 3; 1.2007 + 1.2008 + // The adn in the first phonebook set has already two records, which means 1.2009 + // only 1 free record remained. 1.2010 + let pbrs = [{adn: {fileId: ADN1_FILE_ID, records: [null, {}, {}]}}, 1.2011 + {adn: {fileId: ADN2_FILE_ID, records: [null]}}]; 1.2012 + 1.2013 + recordHelper.readPBR = function readPBR(onsuccess, onerror) { 1.2014 + onsuccess(pbrs); 1.2015 + }; 1.2016 + 1.2017 + recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) { 1.2018 + let pbr = (fileId == ADN1_FILE_ID ? pbrs[0]: pbrs[1]); 1.2019 + if (pbr.adn.records.length > MAX_RECORDS) { 1.2020 + onerror("No free record found."); 1.2021 + return; 1.2022 + } 1.2023 + 1.2024 + onsuccess(pbr.adn.records.length); 1.2025 + }; 1.2026 + 1.2027 + let successCb = function(pbrIndex, recordId) { 1.2028 + do_check_eq(pbrIndex, 0); 1.2029 + pbrs[pbrIndex].adn.records[recordId] = {}; 1.2030 + }; 1.2031 + 1.2032 + let errorCb = function(errorMsg) { 1.2033 + do_check_true(false); 1.2034 + }; 1.2035 + 1.2036 + contactHelper.findFreeICCContact(CARD_APPTYPE_USIM, "adn", successCb, errorCb); 1.2037 + 1.2038 + // Now the EF_ADN in the 1st phonebook set is full, so the next free contact 1.2039 + // will come from the 2nd phonebook set. 1.2040 + successCb = function(pbrIndex, recordId) { 1.2041 + do_check_eq(pbrIndex, 1); 1.2042 + do_check_eq(recordId, 1); 1.2043 + } 1.2044 + contactHelper.findFreeICCContact(CARD_APPTYPE_USIM, "adn", successCb, errorCb); 1.2045 + 1.2046 + run_next_test(); 1.2047 +}); 1.2048 + 1.2049 +/** 1.2050 + * Test error message returned in onerror for readICCContacts. 1.2051 + */ 1.2052 +add_test(function test_error_message_read_icc_contact () { 1.2053 + let worker = newUint8Worker(); 1.2054 + let context = worker.ContextPool._contexts[0]; 1.2055 + let ril = context.RIL; 1.2056 + 1.2057 + function do_test(options, expectedErrorMsg) { 1.2058 + ril.sendChromeMessage = function(message) { 1.2059 + do_check_eq(message.errorMsg, expectedErrorMsg); 1.2060 + } 1.2061 + ril.readICCContacts(options); 1.2062 + } 1.2063 + 1.2064 + // Error 1, didn't specify correct contactType. 1.2065 + do_test({}, CONTACT_ERR_REQUEST_NOT_SUPPORTED); 1.2066 + 1.2067 + // Error 2, specifying a non-supported contactType. 1.2068 + ril.appType = CARD_APPTYPE_USIM; 1.2069 + do_test({contactType: "sdn"}, CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED); 1.2070 + 1.2071 + // Error 3, suppose we update the supported PBR fields in USIM_PBR_FIELDS, 1.2072 + // but forget to add implemenetations for it. 1.2073 + USIM_PBR_FIELDS.push("pbc"); 1.2074 + do_test({contactType: "adn"}, CONTACT_ERR_FIELD_NOT_SUPPORTED); 1.2075 + 1.2076 + run_next_test(); 1.2077 +}); 1.2078 + 1.2079 +/** 1.2080 + * Test error message returned in onerror for updateICCContact. 1.2081 + */ 1.2082 +add_test(function test_error_message_update_icc_contact() { 1.2083 + let worker = newUint8Worker(); 1.2084 + let context = worker.ContextPool._contexts[0]; 1.2085 + let ril = context.RIL; 1.2086 + 1.2087 + const ICCID = "123456789"; 1.2088 + ril.iccInfo.iccid = ICCID; 1.2089 + 1.2090 + function do_test(options, expectedErrorMsg) { 1.2091 + ril.sendChromeMessage = function(message) { 1.2092 + do_check_eq(message.errorMsg, expectedErrorMsg); 1.2093 + } 1.2094 + ril.updateICCContact(options); 1.2095 + } 1.2096 + 1.2097 + // Error 1, didn't specify correct contactType. 1.2098 + do_test({}, CONTACT_ERR_REQUEST_NOT_SUPPORTED); 1.2099 + 1.2100 + // Error 2, specifying a correct contactType, but without providing 'contact'. 1.2101 + do_test({contactType: "adn"}, CONTACT_ERR_REQUEST_NOT_SUPPORTED); 1.2102 + 1.2103 + // Error 3, specifying a non-supported contactType. 1.2104 + ril.appType = CARD_APPTYPE_USIM; 1.2105 + do_test({contactType: "sdn", contact: {}}, CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED); 1.2106 + 1.2107 + // Error 4, without supplying pin2. 1.2108 + do_test({contactType: "fdn", contact: {contactId: ICCID + "1"}}, GECKO_ERROR_SIM_PIN2); 1.2109 + 1.2110 + // Error 5, No free record found in EF_ADN. 1.2111 + let record = context.ICCRecordHelper; 1.2112 + record.readPBR = function(onsuccess, onerror) { 1.2113 + onsuccess([{adn: {fileId: 0x4f3a}}]); 1.2114 + }; 1.2115 + 1.2116 + let io = context.ICCIOHelper; 1.2117 + io.loadLinearFixedEF = function(options) { 1.2118 + options.totalRecords = 1; 1.2119 + options.p1 = 1; 1.2120 + options.callback(options); 1.2121 + }; 1.2122 + 1.2123 + do_test({contactType: "adn", contact: {}}, CONTACT_ERR_NO_FREE_RECORD_FOUND); 1.2124 + 1.2125 + // Error 6, ICC IO Error. 1.2126 + io.loadLinearFixedEF = function(options) { 1.2127 + ril[REQUEST_SIM_IO](0, {rilRequestError: ERROR_GENERIC_FAILURE}); 1.2128 + }; 1.2129 + do_test({contactType: "adn", contact: {contactId: ICCID + "1"}}, 1.2130 + GECKO_ERROR_GENERIC_FAILURE); 1.2131 + 1.2132 + // Error 7, suppose we update the supported PBR fields in USIM_PBR_FIELDS, 1.2133 + // but forget to add implemenetations for it. 1.2134 + USIM_PBR_FIELDS.push("pbc"); 1.2135 + do_test({contactType: "adn", contact: {contactId: ICCID + "1"}}, 1.2136 + CONTACT_ERR_FIELD_NOT_SUPPORTED); 1.2137 + 1.2138 + // Error 8, EF_PBR doesn't exist. 1.2139 + record.readPBR = function(onsuccess, onerror) { 1.2140 + onsuccess([]); 1.2141 + }; 1.2142 + 1.2143 + do_test({contactType: "adn", contact: {contactId: ICCID + "1"}}, 1.2144 + CONTACT_ERR_CANNOT_ACCESS_PHONEBOOK); 1.2145 + 1.2146 + run_next_test(); 1.2147 +}); 1.2148 + 1.2149 +add_test(function test_process_icc_io_error() { 1.2150 + let worker = newUint8Worker(); 1.2151 + let context = worker.ContextPool._contexts[0]; 1.2152 + let ioHelper = context.ICCIOHelper; 1.2153 + 1.2154 + function do_test(errorCode, expectedErrorMsg) { 1.2155 + let called = false; 1.2156 + function errorCb(errorMsg) { 1.2157 + called = true; 1.2158 + do_check_eq(errorMsg, expectedErrorMsg); 1.2159 + } 1.2160 + 1.2161 + ioHelper.processICCIOError({rilRequestError: errorCode, 1.2162 + fileId: 0xffff, 1.2163 + command: 0xff, 1.2164 + sw1: 0xff, 1.2165 + sw2: 0xff, 1.2166 + onerror: errorCb}); 1.2167 + do_check_true(called); 1.2168 + } 1.2169 + 1.2170 + for (let i = 0; i < ERROR_REJECTED_BY_REMOTE + 1; i++) { 1.2171 + do_test(i, RIL_ERROR_TO_GECKO_ERROR[i]); 1.2172 + } 1.2173 + 1.2174 + run_next_test(); 1.2175 +}); 1.2176 + 1.2177 +add_test(function test_personalization_state() { 1.2178 + let worker = newUint8Worker(); 1.2179 + let context = worker.ContextPool._contexts[0]; 1.2180 + let ril = context.RIL; 1.2181 + 1.2182 + context.ICCRecordHelper.readICCID = function fakeReadICCID() {}; 1.2183 + 1.2184 + function testPersonalization(isCdma, cardPersoState, geckoCardState) { 1.2185 + let iccStatus = { 1.2186 + cardState: CARD_STATE_PRESENT, 1.2187 + gsmUmtsSubscriptionAppIndex: (!isCdma) ? 0 : -1, 1.2188 + cdmaSubscriptionAppIndex: (isCdma) ? 0 : -1, 1.2189 + apps: [ 1.2190 + { 1.2191 + app_state: CARD_APPSTATE_SUBSCRIPTION_PERSO, 1.2192 + perso_substate: cardPersoState 1.2193 + }], 1.2194 + }; 1.2195 + 1.2196 + ril._isCdma = isCdma; 1.2197 + ril._processICCStatus(iccStatus); 1.2198 + do_check_eq(ril.cardState, geckoCardState); 1.2199 + } 1.2200 + 1.2201 + // Test GSM personalization state. 1.2202 + testPersonalization(false, CARD_PERSOSUBSTATE_SIM_NETWORK, 1.2203 + GECKO_CARDSTATE_NETWORK_LOCKED); 1.2204 + testPersonalization(false, CARD_PERSOSUBSTATE_SIM_CORPORATE, 1.2205 + GECKO_CARDSTATE_CORPORATE_LOCKED); 1.2206 + testPersonalization(false, CARD_PERSOSUBSTATE_SIM_SERVICE_PROVIDER, 1.2207 + GECKO_CARDSTATE_SERVICE_PROVIDER_LOCKED); 1.2208 + testPersonalization(false, CARD_PERSOSUBSTATE_SIM_NETWORK_PUK, 1.2209 + GECKO_CARDSTATE_NETWORK_PUK_REQUIRED); 1.2210 + testPersonalization(false, CARD_PERSOSUBSTATE_SIM_CORPORATE_PUK, 1.2211 + GECKO_CARDSTATE_CORPORATE_PUK_REQUIRED); 1.2212 + testPersonalization(false, CARD_PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK, 1.2213 + GECKO_CARDSTATE_SERVICE_PROVIDER_PUK_REQUIRED); 1.2214 + testPersonalization(false, CARD_PERSOSUBSTATE_READY, 1.2215 + GECKO_CARDSTATE_PERSONALIZATION_READY); 1.2216 + 1.2217 + // Test CDMA personalization state. 1.2218 + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK1, 1.2219 + GECKO_CARDSTATE_NETWORK1_LOCKED); 1.2220 + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK2, 1.2221 + GECKO_CARDSTATE_NETWORK2_LOCKED); 1.2222 + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_HRPD, 1.2223 + GECKO_CARDSTATE_HRPD_NETWORK_LOCKED); 1.2224 + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_CORPORATE, 1.2225 + GECKO_CARDSTATE_RUIM_CORPORATE_LOCKED); 1.2226 + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER, 1.2227 + GECKO_CARDSTATE_RUIM_SERVICE_PROVIDER_LOCKED); 1.2228 + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_RUIM, 1.2229 + GECKO_CARDSTATE_RUIM_LOCKED); 1.2230 + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK1_PUK, 1.2231 + GECKO_CARDSTATE_NETWORK1_PUK_REQUIRED); 1.2232 + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK2_PUK, 1.2233 + GECKO_CARDSTATE_NETWORK2_PUK_REQUIRED); 1.2234 + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_HRPD_PUK, 1.2235 + GECKO_CARDSTATE_HRPD_NETWORK_PUK_REQUIRED); 1.2236 + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_CORPORATE_PUK, 1.2237 + GECKO_CARDSTATE_RUIM_CORPORATE_PUK_REQUIRED); 1.2238 + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK, 1.2239 + GECKO_CARDSTATE_RUIM_SERVICE_PROVIDER_PUK_REQUIRED); 1.2240 + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_RUIM_PUK, 1.2241 + GECKO_CARDSTATE_RUIM_PUK_REQUIRED); 1.2242 + 1.2243 + run_next_test(); 1.2244 +}); 1.2245 + 1.2246 +/** 1.2247 + * Verify SIM app_state in _processICCStatus 1.2248 + */ 1.2249 +add_test(function test_card_app_state() { 1.2250 + let worker = newUint8Worker(); 1.2251 + let context = worker.ContextPool._contexts[0]; 1.2252 + let ril = context.RIL; 1.2253 + 1.2254 + context.ICCRecordHelper.readICCID = function fakeReadICCID() {}; 1.2255 + 1.2256 + function testCardAppState(cardAppState, geckoCardState) { 1.2257 + let iccStatus = { 1.2258 + cardState: CARD_STATE_PRESENT, 1.2259 + gsmUmtsSubscriptionAppIndex: 0, 1.2260 + apps: [ 1.2261 + { 1.2262 + app_state: cardAppState 1.2263 + }], 1.2264 + }; 1.2265 + 1.2266 + ril._processICCStatus(iccStatus); 1.2267 + do_check_eq(ril.cardState, geckoCardState); 1.2268 + } 1.2269 + 1.2270 + testCardAppState(CARD_APPSTATE_ILLEGAL, 1.2271 + GECKO_CARDSTATE_ILLEGAL); 1.2272 + testCardAppState(CARD_APPSTATE_PIN, 1.2273 + GECKO_CARDSTATE_PIN_REQUIRED); 1.2274 + testCardAppState(CARD_APPSTATE_PUK, 1.2275 + GECKO_CARDSTATE_PUK_REQUIRED); 1.2276 + testCardAppState(CARD_APPSTATE_READY, 1.2277 + GECKO_CARDSTATE_READY); 1.2278 + testCardAppState(CARD_APPSTATE_UNKNOWN, 1.2279 + GECKO_CARDSTATE_UNKNOWN); 1.2280 + testCardAppState(CARD_APPSTATE_DETECTED, 1.2281 + GECKO_CARDSTATE_UNKNOWN); 1.2282 + 1.2283 + run_next_test(); 1.2284 +}); 1.2285 + 1.2286 +/** 1.2287 + * Verify permanent blocked for ICC. 1.2288 + */ 1.2289 +add_test(function test_icc_permanent_blocked() { 1.2290 + let worker = newUint8Worker(); 1.2291 + let context = worker.ContextPool._contexts[0]; 1.2292 + let ril = context.RIL; 1.2293 + 1.2294 + context.ICCRecordHelper.readICCID = function fakeReadICCID() {}; 1.2295 + 1.2296 + function testPermanentBlocked(pin1_replaced, universalPINState, pin1) { 1.2297 + let iccStatus = { 1.2298 + cardState: CARD_STATE_PRESENT, 1.2299 + gsmUmtsSubscriptionAppIndex: 0, 1.2300 + universalPINState: universalPINState, 1.2301 + apps: [ 1.2302 + { 1.2303 + pin1_replaced: pin1_replaced, 1.2304 + pin1: pin1 1.2305 + }] 1.2306 + }; 1.2307 + 1.2308 + ril._processICCStatus(iccStatus); 1.2309 + do_check_eq(ril.cardState, GECKO_CARDSTATE_PERMANENT_BLOCKED); 1.2310 + } 1.2311 + 1.2312 + testPermanentBlocked(1, 1.2313 + CARD_PINSTATE_ENABLED_PERM_BLOCKED, 1.2314 + CARD_PINSTATE_UNKNOWN); 1.2315 + testPermanentBlocked(1, 1.2316 + CARD_PINSTATE_ENABLED_PERM_BLOCKED, 1.2317 + CARD_PINSTATE_ENABLED_PERM_BLOCKED); 1.2318 + testPermanentBlocked(0, 1.2319 + CARD_PINSTATE_UNKNOWN, 1.2320 + CARD_PINSTATE_ENABLED_PERM_BLOCKED); 1.2321 + 1.2322 + run_next_test(); 1.2323 +}); 1.2324 + 1.2325 +/** 1.2326 + * Verify iccSetCardLock - Facility Lock. 1.2327 + */ 1.2328 +add_test(function test_set_icc_card_lock_facility_lock() { 1.2329 + let worker = newUint8Worker(); 1.2330 + let context = worker.ContextPool._contexts[0]; 1.2331 + let aid = "123456789"; 1.2332 + let ril = context.RIL; 1.2333 + ril.aid = aid; 1.2334 + ril.v5Legacy = false; 1.2335 + let buf = context.Buf; 1.2336 + 1.2337 + let GECKO_CARDLOCK_TO_FACILITIY_LOCK = {}; 1.2338 + GECKO_CARDLOCK_TO_FACILITIY_LOCK[GECKO_CARDLOCK_PIN] = ICC_CB_FACILITY_SIM; 1.2339 + GECKO_CARDLOCK_TO_FACILITIY_LOCK[GECKO_CARDLOCK_FDN] = ICC_CB_FACILITY_FDN; 1.2340 + 1.2341 + let GECKO_CARDLOCK_TO_PASSWORD_TYPE = {}; 1.2342 + GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_PIN] = "pin"; 1.2343 + GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_FDN] = "pin2"; 1.2344 + 1.2345 + const pin = "1234"; 1.2346 + const pin2 = "4321"; 1.2347 + let GECKO_CARDLOCK_TO_PASSWORD = {}; 1.2348 + GECKO_CARDLOCK_TO_PASSWORD[GECKO_CARDLOCK_PIN] = pin; 1.2349 + GECKO_CARDLOCK_TO_PASSWORD[GECKO_CARDLOCK_FDN] = pin2; 1.2350 + 1.2351 + const serviceClass = ICC_SERVICE_CLASS_VOICE | 1.2352 + ICC_SERVICE_CLASS_DATA | 1.2353 + ICC_SERVICE_CLASS_FAX; 1.2354 + 1.2355 + function do_test(aLock, aPassword, aEnabled) { 1.2356 + buf.sendParcel = function fakeSendParcel () { 1.2357 + // Request Type. 1.2358 + do_check_eq(this.readInt32(), REQUEST_SET_FACILITY_LOCK); 1.2359 + 1.2360 + // Token : we don't care 1.2361 + this.readInt32(); 1.2362 + 1.2363 + let parcel = this.readStringList(); 1.2364 + do_check_eq(parcel.length, 5); 1.2365 + do_check_eq(parcel[0], GECKO_CARDLOCK_TO_FACILITIY_LOCK[aLock]); 1.2366 + do_check_eq(parcel[1], aEnabled ? "1" : "0"); 1.2367 + do_check_eq(parcel[2], GECKO_CARDLOCK_TO_PASSWORD[aLock]); 1.2368 + do_check_eq(parcel[3], serviceClass.toString()); 1.2369 + do_check_eq(parcel[4], aid); 1.2370 + }; 1.2371 + 1.2372 + let lock = {lockType: aLock, 1.2373 + enabled: aEnabled}; 1.2374 + lock[GECKO_CARDLOCK_TO_PASSWORD_TYPE[aLock]] = aPassword; 1.2375 + 1.2376 + ril.iccSetCardLock(lock); 1.2377 + } 1.2378 + 1.2379 + do_test(GECKO_CARDLOCK_PIN, pin, true); 1.2380 + do_test(GECKO_CARDLOCK_PIN, pin, false); 1.2381 + do_test(GECKO_CARDLOCK_FDN, pin2, true); 1.2382 + do_test(GECKO_CARDLOCK_FDN, pin2, false); 1.2383 + 1.2384 + run_next_test(); 1.2385 +}); 1.2386 + 1.2387 +/** 1.2388 + * Verify iccUnlockCardLock. 1.2389 + */ 1.2390 +add_test(function test_unlock_card_lock_corporateLocked() { 1.2391 + let worker = newUint8Worker(); 1.2392 + let context = worker.ContextPool._contexts[0]; 1.2393 + let ril = context.RIL; 1.2394 + let buf = context.Buf; 1.2395 + const pin = "12345678"; 1.2396 + const puk = "12345678"; 1.2397 + 1.2398 + let GECKO_CARDLOCK_TO_PASSWORD_TYPE = {}; 1.2399 + GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_NCK] = "pin"; 1.2400 + GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_NCK1] = "pin"; 1.2401 + GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_NCK2] = "pin"; 1.2402 + GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_HNCK] = "pin"; 1.2403 + GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_CCK] = "pin"; 1.2404 + GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_SPCK] = "pin"; 1.2405 + GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_RCCK] = "pin"; 1.2406 + GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_RSPCK] = "pin"; 1.2407 + GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_NCK_PUK] = "puk"; 1.2408 + GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_NCK1_PUK] = "puk"; 1.2409 + GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_NCK2_PUK] = "puk"; 1.2410 + GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_HNCK_PUK] = "puk"; 1.2411 + GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_CCK_PUK] = "puk"; 1.2412 + GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_SPCK_PUK] = "puk"; 1.2413 + GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_RCCK_PUK] = "puk"; 1.2414 + GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_RSPCK_PUK] = "puk"; 1.2415 + 1.2416 + function do_test(aLock, aPassword) { 1.2417 + buf.sendParcel = function fakeSendParcel () { 1.2418 + // Request Type. 1.2419 + do_check_eq(this.readInt32(), REQUEST_ENTER_NETWORK_DEPERSONALIZATION_CODE); 1.2420 + 1.2421 + // Token : we don't care 1.2422 + this.readInt32(); 1.2423 + 1.2424 + let lockType = GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[aLock]; 1.2425 + // Lock Type 1.2426 + do_check_eq(this.readInt32(), lockType); 1.2427 + 1.2428 + // Pin/Puk. 1.2429 + do_check_eq(this.readString(), aPassword); 1.2430 + }; 1.2431 + 1.2432 + let lock = {lockType: aLock}; 1.2433 + lock[GECKO_CARDLOCK_TO_PASSWORD_TYPE[aLock]] = aPassword; 1.2434 + ril.iccUnlockCardLock(lock); 1.2435 + } 1.2436 + 1.2437 + do_test(GECKO_CARDLOCK_NCK, pin); 1.2438 + do_test(GECKO_CARDLOCK_NCK1, pin); 1.2439 + do_test(GECKO_CARDLOCK_NCK2, pin); 1.2440 + do_test(GECKO_CARDLOCK_HNCK, pin); 1.2441 + do_test(GECKO_CARDLOCK_CCK, pin); 1.2442 + do_test(GECKO_CARDLOCK_SPCK, pin); 1.2443 + do_test(GECKO_CARDLOCK_RCCK, pin); 1.2444 + do_test(GECKO_CARDLOCK_RSPCK, pin); 1.2445 + do_test(GECKO_CARDLOCK_NCK_PUK, puk); 1.2446 + do_test(GECKO_CARDLOCK_NCK1_PUK, puk); 1.2447 + do_test(GECKO_CARDLOCK_NCK2_PUK, puk); 1.2448 + do_test(GECKO_CARDLOCK_HNCK_PUK, puk); 1.2449 + do_test(GECKO_CARDLOCK_CCK_PUK, puk); 1.2450 + do_test(GECKO_CARDLOCK_SPCK_PUK, puk); 1.2451 + do_test(GECKO_CARDLOCK_RCCK_PUK, puk); 1.2452 + do_test(GECKO_CARDLOCK_RSPCK_PUK, puk); 1.2453 + 1.2454 + run_next_test(); 1.2455 +}); 1.2456 + 1.2457 +/** 1.2458 + * Verify MCC and MNC parsing 1.2459 + */ 1.2460 +add_test(function test_mcc_mnc_parsing() { 1.2461 + let worker = newUint8Worker(); 1.2462 + let context = worker.ContextPool._contexts[0]; 1.2463 + let helper = context.ICCUtilsHelper; 1.2464 + 1.2465 + function do_test(imsi, mncLength, expectedMcc, expectedMnc) { 1.2466 + let result = helper.parseMccMncFromImsi(imsi, mncLength); 1.2467 + 1.2468 + if (!imsi) { 1.2469 + do_check_eq(result, null); 1.2470 + return; 1.2471 + } 1.2472 + 1.2473 + do_check_eq(result.mcc, expectedMcc); 1.2474 + do_check_eq(result.mnc, expectedMnc); 1.2475 + } 1.2476 + 1.2477 + // Test the imsi is null. 1.2478 + do_test(null, null, null, null); 1.2479 + 1.2480 + // Test MCC is Taiwan 1.2481 + do_test("466923202422409", 0x02, "466", "92"); 1.2482 + do_test("466923202422409", 0x03, "466", "923"); 1.2483 + do_test("466923202422409", null, "466", "92"); 1.2484 + 1.2485 + // Test MCC is US 1.2486 + do_test("310260542718417", 0x02, "310", "26"); 1.2487 + do_test("310260542718417", 0x03, "310", "260"); 1.2488 + do_test("310260542718417", null, "310", "260"); 1.2489 + 1.2490 + run_next_test(); 1.2491 + }); 1.2492 + 1.2493 + /** 1.2494 + * Verify reading EF_AD and parsing MCC/MNC 1.2495 + */ 1.2496 +add_test(function test_reading_ad_and_parsing_mcc_mnc() { 1.2497 + let worker = newUint8Worker(); 1.2498 + let context = worker.ContextPool._contexts[0]; 1.2499 + let record = context.SimRecordHelper; 1.2500 + let helper = context.GsmPDUHelper; 1.2501 + let ril = context.RIL; 1.2502 + let buf = context.Buf; 1.2503 + let io = context.ICCIOHelper; 1.2504 + 1.2505 + function do_test(mncLengthInEf, imsi, expectedMcc, expectedMnc) { 1.2506 + ril.iccInfoPrivate.imsi = imsi; 1.2507 + 1.2508 + io.loadTransparentEF = function fakeLoadTransparentEF(options) { 1.2509 + let ad = [0x00, 0x00, 0x00]; 1.2510 + if (mncLengthInEf) { 1.2511 + ad.push(mncLengthInEf); 1.2512 + } 1.2513 + 1.2514 + // Write data size 1.2515 + buf.writeInt32(ad.length * 2); 1.2516 + 1.2517 + // Write data 1.2518 + for (let i = 0; i < ad.length; i++) { 1.2519 + helper.writeHexOctet(ad[i]); 1.2520 + } 1.2521 + 1.2522 + // Write string delimiter 1.2523 + buf.writeStringDelimiter(ad.length * 2); 1.2524 + 1.2525 + if (options.callback) { 1.2526 + options.callback(options); 1.2527 + } 1.2528 + }; 1.2529 + 1.2530 + record.readAD(); 1.2531 + 1.2532 + do_check_eq(ril.iccInfo.mcc, expectedMcc); 1.2533 + do_check_eq(ril.iccInfo.mnc, expectedMnc); 1.2534 + } 1.2535 + 1.2536 + do_test(undefined, "466923202422409", "466", "92" ); 1.2537 + do_test(0x03, "466923202422409", "466", "923"); 1.2538 + do_test(undefined, "310260542718417", "310", "260"); 1.2539 + do_test(0x02, "310260542718417", "310", "26" ); 1.2540 + 1.2541 + run_next_test(); 1.2542 +}); 1.2543 + 1.2544 +add_test(function test_reading_optional_efs() { 1.2545 + let worker = newUint8Worker(); 1.2546 + let context = worker.ContextPool._contexts[0]; 1.2547 + let record = context.SimRecordHelper; 1.2548 + let gsmPdu = context.GsmPDUHelper; 1.2549 + let ril = context.RIL; 1.2550 + let buf = context.Buf; 1.2551 + let io = context.ICCIOHelper; 1.2552 + 1.2553 + function buildSST(supportedEf) { 1.2554 + let sst = []; 1.2555 + let len = supportedEf.length; 1.2556 + for (let i = 0; i < len; i++) { 1.2557 + let index, bitmask, iccService; 1.2558 + if (ril.appType === CARD_APPTYPE_SIM) { 1.2559 + iccService = GECKO_ICC_SERVICES.sim[supportedEf[i]]; 1.2560 + iccService -= 1; 1.2561 + index = Math.floor(iccService / 4); 1.2562 + bitmask = 2 << ((iccService % 4) << 1); 1.2563 + } else if (ril.appType === CARD_APPTYPE_USIM){ 1.2564 + iccService = GECKO_ICC_SERVICES.usim[supportedEf[i]]; 1.2565 + iccService -= 1; 1.2566 + index = Math.floor(iccService / 8); 1.2567 + bitmask = 1 << ((iccService % 8) << 0); 1.2568 + } 1.2569 + 1.2570 + if (sst) { 1.2571 + sst[index] |= bitmask; 1.2572 + } 1.2573 + } 1.2574 + return sst; 1.2575 + } 1.2576 + 1.2577 + ril.updateCellBroadcastConfig = function fakeUpdateCellBroadcastConfig() { 1.2578 + // Ignore updateCellBroadcastConfig after reading SST 1.2579 + }; 1.2580 + 1.2581 + function do_test(sst, supportedEf) { 1.2582 + // Clone supportedEf to local array for testing 1.2583 + let testEf = supportedEf.slice(0); 1.2584 + 1.2585 + record.readMSISDN = function fakeReadMSISDN() { 1.2586 + testEf.splice(testEf.indexOf("MSISDN"), 1); 1.2587 + }; 1.2588 + 1.2589 + record.readMBDN = function fakeReadMBDN() { 1.2590 + testEf.splice(testEf.indexOf("MDN"), 1); 1.2591 + }; 1.2592 + 1.2593 + record.readMWIS = function fakeReadMWIS() { 1.2594 + testEf.splice(testEf.indexOf("MWIS"), 1); 1.2595 + }; 1.2596 + 1.2597 + io.loadTransparentEF = function fakeLoadTransparentEF(options) { 1.2598 + // Write data size 1.2599 + buf.writeInt32(sst.length * 2); 1.2600 + 1.2601 + // Write data 1.2602 + for (let i = 0; i < sst.length; i++) { 1.2603 + gsmPdu.writeHexOctet(sst[i] || 0); 1.2604 + } 1.2605 + 1.2606 + // Write string delimiter 1.2607 + buf.writeStringDelimiter(sst.length * 2); 1.2608 + 1.2609 + if (options.callback) { 1.2610 + options.callback(options); 1.2611 + } 1.2612 + 1.2613 + if (testEf.length !== 0) { 1.2614 + do_print("Un-handled EF: " + JSON.stringify(testEf)); 1.2615 + do_check_true(false); 1.2616 + } 1.2617 + }; 1.2618 + 1.2619 + record.readSST(); 1.2620 + } 1.2621 + 1.2622 + // TODO: Add all necessary optional EFs eventually 1.2623 + let supportedEf = ["MSISDN", "MDN", "MWIS"]; 1.2624 + ril.appType = CARD_APPTYPE_SIM; 1.2625 + do_test(buildSST(supportedEf), supportedEf); 1.2626 + ril.appType = CARD_APPTYPE_USIM; 1.2627 + do_test(buildSST(supportedEf), supportedEf); 1.2628 + 1.2629 + run_next_test(); 1.2630 +}); 1.2631 + 1.2632 +/** 1.2633 + * Verify fetchSimRecords. 1.2634 + */ 1.2635 +add_test(function test_fetch_sim_recodes() { 1.2636 + let worker = newWorker(); 1.2637 + let context = worker.ContextPool._contexts[0]; 1.2638 + let RIL = context.RIL; 1.2639 + let iccRecord = context.ICCRecordHelper; 1.2640 + let simRecord = context.SimRecordHelper; 1.2641 + 1.2642 + function testFetchSimRecordes(expectCalled) { 1.2643 + let ifCalled = []; 1.2644 + 1.2645 + RIL.getIMSI = function() { 1.2646 + ifCalled.push("getIMSI"); 1.2647 + }; 1.2648 + 1.2649 + simRecord.readAD = function() { 1.2650 + ifCalled.push("readAD"); 1.2651 + }; 1.2652 + 1.2653 + simRecord.readSST = function() { 1.2654 + ifCalled.push("readSST"); 1.2655 + }; 1.2656 + 1.2657 + simRecord.fetchSimRecords(); 1.2658 + 1.2659 + for (let i = 0; i < expectCalled.length; i++ ) { 1.2660 + if (ifCalled[i] != expectCalled[i]) { 1.2661 + do_print(expectCalled[i] + " is not called."); 1.2662 + do_check_true(false); 1.2663 + } 1.2664 + } 1.2665 + } 1.2666 + 1.2667 + let expectCalled = ["getIMSI", "readAD", "readSST"]; 1.2668 + testFetchSimRecordes(expectCalled); 1.2669 + 1.2670 + run_next_test(); 1.2671 +}); 1.2672 + 1.2673 +add_test(function test_fetch_icc_recodes() { 1.2674 + let worker = newWorker(); 1.2675 + let context = worker.ContextPool._contexts[0]; 1.2676 + let RIL = context.RIL; 1.2677 + let iccRecord = context.ICCRecordHelper; 1.2678 + let simRecord = context.SimRecordHelper; 1.2679 + let ruimRecord = context.RuimRecordHelper; 1.2680 + let fetchTag = 0x00; 1.2681 + 1.2682 + simRecord.fetchSimRecords = function() { 1.2683 + fetchTag = 0x01; 1.2684 + }; 1.2685 + 1.2686 + ruimRecord.fetchRuimRecords = function() { 1.2687 + fetchTag = 0x02; 1.2688 + }; 1.2689 + 1.2690 + RIL.appType = CARD_APPTYPE_SIM; 1.2691 + iccRecord.fetchICCRecords(); 1.2692 + do_check_eq(fetchTag, 0x01); 1.2693 + 1.2694 + RIL.appType = CARD_APPTYPE_RUIM; 1.2695 + iccRecord.fetchICCRecords(); 1.2696 + do_check_eq(fetchTag, 0x02); 1.2697 + 1.2698 + RIL.appType = CARD_APPTYPE_USIM; 1.2699 + iccRecord.fetchICCRecords(); 1.2700 + do_check_eq(fetchTag, 0x01); 1.2701 + 1.2702 + run_next_test(); 1.2703 +}); 1.2704 + 1.2705 +/** 1.2706 + * Verify SimRecordHelper.readMWIS 1.2707 + */ 1.2708 +add_test(function test_read_mwis() { 1.2709 + let worker = newUint8Worker(); 1.2710 + let context = worker.ContextPool._contexts[0]; 1.2711 + let helper = context.GsmPDUHelper; 1.2712 + let recordHelper = context.SimRecordHelper; 1.2713 + let buf = context.Buf; 1.2714 + let io = context.ICCIOHelper; 1.2715 + let mwisData; 1.2716 + let postedMessage; 1.2717 + 1.2718 + worker.postMessage = function fakePostMessage(message) { 1.2719 + postedMessage = message; 1.2720 + }; 1.2721 + 1.2722 + io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { 1.2723 + if (mwisData) { 1.2724 + // Write data size 1.2725 + buf.writeInt32(mwisData.length * 2); 1.2726 + 1.2727 + // Write MWIS 1.2728 + for (let i = 0; i < mwisData.length; i++) { 1.2729 + helper.writeHexOctet(mwisData[i]); 1.2730 + } 1.2731 + 1.2732 + // Write string delimiter 1.2733 + buf.writeStringDelimiter(mwisData.length * 2); 1.2734 + 1.2735 + options.recordSize = mwisData.length; 1.2736 + if (options.callback) { 1.2737 + options.callback(options); 1.2738 + } 1.2739 + } else { 1.2740 + do_print("mwisData[] is not set."); 1.2741 + } 1.2742 + }; 1.2743 + 1.2744 + function buildMwisData(isActive, msgCount) { 1.2745 + if (msgCount < 0 || msgCount === GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN) { 1.2746 + msgCount = 0; 1.2747 + } else if (msgCount > 255) { 1.2748 + msgCount = 255; 1.2749 + } 1.2750 + 1.2751 + mwisData = [ (isActive) ? 0x01 : 0x00, 1.2752 + msgCount, 1.2753 + 0xFF, 0xFF, 0xFF ]; 1.2754 + } 1.2755 + 1.2756 + function do_test(isActive, msgCount) { 1.2757 + buildMwisData(isActive, msgCount); 1.2758 + recordHelper.readMWIS(); 1.2759 + 1.2760 + do_check_eq("iccmwis", postedMessage.rilMessageType); 1.2761 + do_check_eq(isActive, postedMessage.mwi.active); 1.2762 + do_check_eq((isActive) ? msgCount : 0, postedMessage.mwi.msgCount); 1.2763 + } 1.2764 + 1.2765 + do_test(true, GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN); 1.2766 + do_test(true, 1); 1.2767 + do_test(true, 255); 1.2768 + 1.2769 + do_test(false, 0); 1.2770 + do_test(false, 255); // Test the corner case when mwi is disable with incorrect msgCount. 1.2771 + 1.2772 + run_next_test(); 1.2773 +}); 1.2774 + 1.2775 +/** 1.2776 + * Verify SimRecordHelper.updateMWIS 1.2777 + */ 1.2778 +add_test(function test_update_mwis() { 1.2779 + let worker = newUint8Worker(); 1.2780 + let context = worker.ContextPool._contexts[0]; 1.2781 + let pduHelper = context.GsmPDUHelper; 1.2782 + let ril = context.RIL; 1.2783 + ril.appType = CARD_APPTYPE_USIM; 1.2784 + ril.iccInfoPrivate.mwis = [0x00, 0x00, 0x00, 0x00, 0x00]; 1.2785 + let recordHelper = context.SimRecordHelper; 1.2786 + let buf = context.Buf; 1.2787 + let ioHelper = context.ICCIOHelper; 1.2788 + let recordSize = ril.iccInfoPrivate.mwis.length; 1.2789 + let recordNum = 1; 1.2790 + 1.2791 + ioHelper.updateLinearFixedEF = function(options) { 1.2792 + options.pathId = context.ICCFileHelper.getEFPath(options.fileId); 1.2793 + options.command = ICC_COMMAND_UPDATE_RECORD; 1.2794 + options.p1 = options.recordNumber; 1.2795 + options.p2 = READ_RECORD_ABSOLUTE_MODE; 1.2796 + options.p3 = recordSize; 1.2797 + ril.iccIO(options); 1.2798 + }; 1.2799 + 1.2800 + function do_test(isActive, count) { 1.2801 + let mwis = ril.iccInfoPrivate.mwis; 1.2802 + let isUpdated = false; 1.2803 + 1.2804 + function buildMwisData() { 1.2805 + let result = mwis.slice(0); 1.2806 + result[0] = isActive? (mwis[0] | 0x01) : (mwis[0] & 0xFE); 1.2807 + result[1] = (count === GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN) ? 0 : count; 1.2808 + 1.2809 + return result; 1.2810 + } 1.2811 + 1.2812 + buf.sendParcel = function() { 1.2813 + isUpdated = true; 1.2814 + 1.2815 + // Request Type. 1.2816 + do_check_eq(this.readInt32(), REQUEST_SIM_IO); 1.2817 + 1.2818 + // Token : we don't care 1.2819 + this.readInt32(); 1.2820 + 1.2821 + // command. 1.2822 + do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD); 1.2823 + 1.2824 + // fileId. 1.2825 + do_check_eq(this.readInt32(), ICC_EF_MWIS); 1.2826 + 1.2827 + // pathId. 1.2828 + do_check_eq(this.readString(), 1.2829 + EF_PATH_MF_SIM + ((ril.appType === CARD_APPTYPE_USIM) ? EF_PATH_ADF_USIM : EF_PATH_DF_GSM)); 1.2830 + 1.2831 + // p1. 1.2832 + do_check_eq(this.readInt32(), recordNum); 1.2833 + 1.2834 + // p2. 1.2835 + do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE); 1.2836 + 1.2837 + // p3. 1.2838 + do_check_eq(this.readInt32(), recordSize); 1.2839 + 1.2840 + // data. 1.2841 + let strLen = this.readInt32(); 1.2842 + do_check_eq(recordSize * 2, strLen); 1.2843 + let expectedMwis = buildMwisData(); 1.2844 + for (let i = 0; i < recordSize; i++) { 1.2845 + do_check_eq(expectedMwis[i], pduHelper.readHexOctet()); 1.2846 + } 1.2847 + this.readStringDelimiter(strLen); 1.2848 + 1.2849 + // pin2. 1.2850 + do_check_eq(this.readString(), null); 1.2851 + 1.2852 + if (!ril.v5Legacy) { 1.2853 + // AID. Ignore because it's from modem. 1.2854 + this.readInt32(); 1.2855 + } 1.2856 + }; 1.2857 + 1.2858 + do_check_false(isUpdated); 1.2859 + 1.2860 + recordHelper.updateMWIS({ active: isActive, 1.2861 + msgCount: count }); 1.2862 + 1.2863 + do_check_true((ril.iccInfoPrivate.mwis) ? isUpdated : !isUpdated); 1.2864 + } 1.2865 + 1.2866 + do_test(true, GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN); 1.2867 + do_test(true, 1); 1.2868 + do_test(true, 255); 1.2869 + 1.2870 + do_test(false, 0); 1.2871 + 1.2872 + // Test if Path ID is correct for SIM. 1.2873 + ril.appType = CARD_APPTYPE_SIM; 1.2874 + do_test(false, 0); 1.2875 + 1.2876 + // Test if loadLinearFixedEF() is not invoked in updateMWIS() when 1.2877 + // EF_MWIS is not loaded/available. 1.2878 + delete ril.iccInfoPrivate.mwis; 1.2879 + do_test(false, 0); 1.2880 + 1.2881 + run_next_test(); 1.2882 +}); 1.2883 + 1.2884 +/** 1.2885 + * Verify the call flow of receiving Class 2 SMS stored in SIM: 1.2886 + * 1. UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM. 1.2887 + * 2. SimRecordHelper.readSMS(). 1.2888 + * 3. sendChromeMessage() with rilMessageType == "sms-received". 1.2889 + */ 1.2890 +add_test(function test_read_new_sms_on_sim() { 1.2891 + // Instead of reusing newUint8Worker defined in this file, 1.2892 + // we define our own worker to fake the methods in WorkerBuffer dynamically. 1.2893 + function newSmsOnSimWorkerHelper() { 1.2894 + let _postedMessage; 1.2895 + let _worker = newWorker({ 1.2896 + postRILMessage: function(data) { 1.2897 + }, 1.2898 + postMessage: function(message) { 1.2899 + _postedMessage = message; 1.2900 + } 1.2901 + }); 1.2902 + 1.2903 + _worker.debug = do_print; 1.2904 + 1.2905 + return { 1.2906 + get postedMessage() { 1.2907 + return _postedMessage; 1.2908 + }, 1.2909 + get worker() { 1.2910 + return _worker; 1.2911 + }, 1.2912 + fakeWokerBuffer: function() { 1.2913 + let context = _worker.ContextPool._contexts[0]; 1.2914 + let index = 0; // index for read 1.2915 + let buf = []; 1.2916 + context.Buf.writeUint8 = function(value) { 1.2917 + buf.push(value); 1.2918 + }; 1.2919 + context.Buf.readUint8 = function() { 1.2920 + return buf[index++]; 1.2921 + }; 1.2922 + context.Buf.seekIncoming = function(offset) { 1.2923 + index += offset; 1.2924 + }; 1.2925 + context.Buf.getReadAvailable = function() { 1.2926 + return buf.length - index; 1.2927 + }; 1.2928 + } 1.2929 + }; 1.2930 + } 1.2931 + 1.2932 + let workerHelper = newSmsOnSimWorkerHelper(); 1.2933 + let worker = workerHelper.worker; 1.2934 + let context = worker.ContextPool._contexts[0]; 1.2935 + 1.2936 + context.ICCIOHelper.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { 1.2937 + // SimStatus: Unread, SMSC:+0123456789, Sender: +9876543210, Text: How are you? 1.2938 + let SimSmsPduHex = "0306911032547698040A9189674523010000208062917314080CC8F71D14969741F977FD07" 1.2939 + // In 4.2.25 EF_SMS Short Messages of 3GPP TS 31.102: 1.2940 + // 1. Record length == 176 bytes. 1.2941 + // 2. Any bytes in the record following the TPDU shall be filled with 'FF'. 1.2942 + + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 1.2943 + + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 1.2944 + + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 1.2945 + + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"; 1.2946 + 1.2947 + workerHelper.fakeWokerBuffer(); 1.2948 + 1.2949 + context.Buf.writeString(SimSmsPduHex); 1.2950 + 1.2951 + options.recordSize = 176; // Record length is fixed to 176 bytes. 1.2952 + if (options.callback) { 1.2953 + options.callback(options); 1.2954 + } 1.2955 + }; 1.2956 + 1.2957 + function newSmsOnSimParcel() { 1.2958 + let data = new Uint8Array(4 + 4); // Int32List with 1 element. 1.2959 + let offset = 0; 1.2960 + 1.2961 + function writeInt(value) { 1.2962 + data[offset++] = value & 0xFF; 1.2963 + data[offset++] = (value >> 8) & 0xFF; 1.2964 + data[offset++] = (value >> 16) & 0xFF; 1.2965 + data[offset++] = (value >> 24) & 0xFF; 1.2966 + } 1.2967 + 1.2968 + writeInt(1); // Length of Int32List 1.2969 + writeInt(1); // RecordNum = 1. 1.2970 + 1.2971 + return newIncomingParcel(-1, 1.2972 + RESPONSE_TYPE_UNSOLICITED, 1.2973 + UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM, 1.2974 + data); 1.2975 + } 1.2976 + 1.2977 + function do_test() { 1.2978 + worker.onRILMessage(0, newSmsOnSimParcel()); 1.2979 + 1.2980 + let postedMessage = workerHelper.postedMessage; 1.2981 + 1.2982 + do_check_eq("sms-received", postedMessage.rilMessageType); 1.2983 + do_check_eq("+0123456789", postedMessage.SMSC); 1.2984 + do_check_eq("+9876543210", postedMessage.sender); 1.2985 + do_check_eq("How are you?", postedMessage.body); 1.2986 + } 1.2987 + 1.2988 + do_test(); 1.2989 + 1.2990 + run_next_test(); 1.2991 +}); 1.2992 + 1.2993 +// Test ICC_COMMAND_GET_RESPONSE with FCP template format. 1.2994 +/** 1.2995 + * Verify transparent structure with FCP template format. 1.2996 + */ 1.2997 +add_test(function test_fcp_template_for_transparent_structure() { 1.2998 + let worker = newUint8Worker(); 1.2999 + let context = worker.ContextPool._contexts[0]; 1.3000 + let pduHelper = context.GsmPDUHelper; 1.3001 + let berHelper = context.BerTlvHelper; 1.3002 + 1.3003 + let tag_test = [ 1.3004 + 0x62, 1.3005 + 0x22, 1.3006 + 0x82, 0x02, 0x41, 0x21, 1.3007 + 0x83, 0x02, 0x2F, 0xE2, 1.3008 + 0xA5, 0x09, 0xC1, 0x04, 0x40, 0x0F, 0xF5, 0x55, 0x92, 0x01, 0x00, 1.3009 + 0x8A, 0x01, 0x05, 1.3010 + 0x8B, 0x03, 0x2F, 0x06, 0x0B, 1.3011 + 0x80, 0x02, 0x00, 0x0A, 1.3012 + 0x88, 0x01, 0x10]; 1.3013 + 1.3014 + for (let i = 0; i < tag_test.length; i++) { 1.3015 + pduHelper.writeHexOctet(tag_test[i]); 1.3016 + } 1.3017 + 1.3018 + let berTlv = berHelper.decode(tag_test.length); 1.3019 + let iter = Iterator(berTlv.value); 1.3020 + let tlv = berHelper.searchForNextTag(BER_FCP_FILE_DESCRIPTOR_TAG, iter); 1.3021 + do_check_eq(tlv.value.fileStructure, UICC_EF_STRUCTURE[EF_TYPE_TRANSPARENT]); 1.3022 + 1.3023 + tlv = berHelper.searchForNextTag(BER_FCP_FILE_IDENTIFIER_TAG, iter); 1.3024 + do_check_eq(tlv.value.fileId, 0x2FE2); 1.3025 + 1.3026 + tlv = berHelper.searchForNextTag(BER_FCP_FILE_SIZE_DATA_TAG, iter); 1.3027 + do_check_eq(tlv.value.fileSizeData, 0x0A); 1.3028 + 1.3029 + run_next_test(); 1.3030 +}); 1.3031 + 1.3032 +/** 1.3033 + * Verify linear fixed structure with FCP template format. 1.3034 + */ 1.3035 +add_test(function test_fcp_template_for_linear_fixed_structure() { 1.3036 + let worker = newUint8Worker(); 1.3037 + let context = worker.ContextPool._contexts[0]; 1.3038 + let pduHelper = context.GsmPDUHelper; 1.3039 + let berHelper = context.BerTlvHelper; 1.3040 + 1.3041 + let tag_test = [ 1.3042 + 0x62, 1.3043 + 0x1E, 1.3044 + 0x82, 0x05, 0x42, 0x21, 0x00, 0x1A, 0x01, 1.3045 + 0x83, 0x02, 0x6F, 0x40, 1.3046 + 0xA5, 0x03, 0x92, 0x01, 0x00, 1.3047 + 0x8A, 0x01, 0x07, 1.3048 + 0x8B, 0x03, 0x6F, 0x06, 0x02, 1.3049 + 0x80, 0x02, 0x00, 0x1A, 1.3050 + 0x88, 0x00]; 1.3051 + 1.3052 + for (let i = 0; i < tag_test.length; i++) { 1.3053 + pduHelper.writeHexOctet(tag_test[i]); 1.3054 + } 1.3055 + 1.3056 + let berTlv = berHelper.decode(tag_test.length); 1.3057 + let iter = Iterator(berTlv.value); 1.3058 + let tlv = berHelper.searchForNextTag(BER_FCP_FILE_DESCRIPTOR_TAG, iter); 1.3059 + do_check_eq(tlv.value.fileStructure, UICC_EF_STRUCTURE[EF_TYPE_LINEAR_FIXED]); 1.3060 + do_check_eq(tlv.value.recordLength, 0x1A); 1.3061 + do_check_eq(tlv.value.numOfRecords, 0x01); 1.3062 + 1.3063 + tlv = berHelper.searchForNextTag(BER_FCP_FILE_IDENTIFIER_TAG, iter); 1.3064 + do_check_eq(tlv.value.fileId, 0x6F40); 1.3065 + 1.3066 + tlv = berHelper.searchForNextTag(BER_FCP_FILE_SIZE_DATA_TAG, iter); 1.3067 + do_check_eq(tlv.value.fileSizeData, 0x1A); 1.3068 + 1.3069 + run_next_test(); 1.3070 +}); 1.3071 + 1.3072 +add_test(function test_icc_io_get_response_for_transparent_structure() { 1.3073 + let worker = newUint8Worker(); 1.3074 + let context = worker.ContextPool._contexts[0]; 1.3075 + let buf = context.Buf; 1.3076 + let iccioHelper = context.ICCIOHelper; 1.3077 + let pduHelper = context.GsmPDUHelper; 1.3078 + 1.3079 + let responseArray = [ 1.3080 + // SIM response. 1.3081 + [0x00, 0x00, 0x00, 0x0A, 0x2F, 0xE2, 0x04, 0x00, 0x0A, 0xA0, 0xAA, 0x00, 1.3082 + 0x02, 0x00, 0x00], 1.3083 + // USIM response. 1.3084 + [0x62, 0x22, 0x82, 0x02, 0x41, 0x21, 0x83, 0x02, 0x2F, 0xE2, 0xA5, 0x09, 1.3085 + 0xC1, 0x04, 0x40, 0x0F, 0xF5, 0x55, 0x92, 0x01, 0x00, 0x8A, 0x01, 0x05, 1.3086 + 0x8B, 0x03, 0x2F, 0x06, 0x0B, 0x80, 0x02, 0x00, 0x0A, 0x88, 0x01, 0x10] 1.3087 + ]; 1.3088 + 1.3089 + for (let i = 0; i < responseArray.length; i++) { 1.3090 + let strLen = responseArray[i].length * 2; 1.3091 + buf.writeInt32(strLen); 1.3092 + for (let j = 0; j < responseArray[i].length; j++) { 1.3093 + pduHelper.writeHexOctet(responseArray[i][j]); 1.3094 + } 1.3095 + buf.writeStringDelimiter(strLen); 1.3096 + 1.3097 + let options = {fileId: ICC_EF_ICCID, 1.3098 + type: EF_TYPE_TRANSPARENT}; 1.3099 + iccioHelper.processICCIOGetResponse(options); 1.3100 + 1.3101 + do_check_eq(options.fileSize, 0x0A); 1.3102 + } 1.3103 + 1.3104 + run_next_test(); 1.3105 +}); 1.3106 + 1.3107 +add_test(function test_icc_io_get_response_for_linear_fixed_structure() { 1.3108 + let worker = newUint8Worker(); 1.3109 + let context = worker.ContextPool._contexts[0]; 1.3110 + let buf = context.Buf; 1.3111 + let iccioHelper = context.ICCIOHelper; 1.3112 + let pduHelper = context.GsmPDUHelper; 1.3113 + 1.3114 + let responseArray = [ 1.3115 + // SIM response. 1.3116 + [0x00, 0x00, 0x00, 0x1A, 0x6F, 0x40, 0x04, 0x00, 0x11, 0xA0, 0xAA, 0x00, 1.3117 + 0x02, 0x01, 0x1A], 1.3118 + // USIM response. 1.3119 + [0x62, 0x1E, 0x82, 0x05, 0x42, 0x21, 0x00, 0x1A, 0x01, 0x83, 0x02, 0x6F, 1.3120 + 0x40, 0xA5, 0x03, 0x92, 0x01, 0x00, 0x8A, 0x01, 0x07, 0x8B, 0x03, 0x6F, 1.3121 + 0x06, 0x02, 0x80, 0x02, 0x00, 0x1A, 0x88, 0x00] 1.3122 + ]; 1.3123 + 1.3124 + for (let i = 0; i < responseArray.length; i++) { 1.3125 + let strLen = responseArray[i].length * 2; 1.3126 + buf.writeInt32(strLen); 1.3127 + for (let j = 0; j < responseArray[i].length; j++) { 1.3128 + pduHelper.writeHexOctet(responseArray[i][j]); 1.3129 + } 1.3130 + buf.writeStringDelimiter(strLen); 1.3131 + 1.3132 + let options = {fileId: ICC_EF_MSISDN, 1.3133 + type: EF_TYPE_LINEAR_FIXED}; 1.3134 + iccioHelper.processICCIOGetResponse(options); 1.3135 + 1.3136 + do_check_eq(options.fileSize, 0x1A); 1.3137 + do_check_eq(options.recordSize, 0x1A); 1.3138 + do_check_eq(options.totalRecords, 0x01); 1.3139 + } 1.3140 + 1.3141 + run_next_test(); 1.3142 +}); 1.3143 + 1.3144 +/** 1.3145 + * Verify reading EF_ICCID. 1.3146 + */ 1.3147 +add_test(function test_handling_iccid() { 1.3148 + let worker = newUint8Worker(); 1.3149 + let context = worker.ContextPool._contexts[0]; 1.3150 + let record = context.ICCRecordHelper; 1.3151 + let helper = context.GsmPDUHelper; 1.3152 + let ril = context.RIL; 1.3153 + let buf = context.Buf; 1.3154 + let io = context.ICCIOHelper; 1.3155 + 1.3156 + ril.reportStkServiceIsRunning = function fakeReportStkServiceIsRunning() { 1.3157 + }; 1.3158 + 1.3159 + function do_test(rawICCID, expectedICCID) { 1.3160 + io.loadTransparentEF = function fakeLoadTransparentEF(options) { 1.3161 + // Write data size 1.3162 + buf.writeInt32(rawICCID.length); 1.3163 + 1.3164 + // Write data 1.3165 + for (let i = 0; i < rawICCID.length; i += 2) { 1.3166 + helper.writeHexOctet(parseInt(rawICCID.substr(i, 2), 16)); 1.3167 + } 1.3168 + 1.3169 + // Write string delimiter 1.3170 + buf.writeStringDelimiter(rawICCID.length); 1.3171 + 1.3172 + if (options.callback) { 1.3173 + options.callback(options); 1.3174 + } 1.3175 + }; 1.3176 + 1.3177 + record.readICCID(); 1.3178 + 1.3179 + do_check_eq(ril.iccInfo.iccid, expectedICCID); 1.3180 + } 1.3181 + 1.3182 + // Invalid char at high nibbile + low nibbile contains 0xF. 1.3183 + do_test("9868002E90909F001519", "89860020909"); 1.3184 + // Invalid char at low nibbile. 1.3185 + do_test("986800E2909090001519", "8986002090909005191"); 1.3186 + // Valid ICCID. 1.3187 + do_test("98101430121181157002", "89014103211118510720"); 1.3188 + 1.3189 + run_next_test(); 1.3190 +});