1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.telephony.uicc; 18 19 import android.compat.annotation.UnsupportedAppUsage; 20 import android.os.AsyncResult; 21 import android.os.Handler; 22 import android.os.Message; 23 24 import com.android.internal.telephony.CommandsInterface; 25 26 import java.util.ArrayList; 27 28 /** 29 * {@hide} 30 */ 31 public abstract class IccFileHandler extends Handler implements IccConstants { 32 private static final boolean VDBG = false; 33 34 //from TS 11.11 9.1 or elsewhere 35 static protected final int COMMAND_READ_BINARY = 0xb0; 36 static protected final int COMMAND_UPDATE_BINARY = 0xd6; 37 static protected final int COMMAND_READ_RECORD = 0xb2; 38 static protected final int COMMAND_UPDATE_RECORD = 0xdc; 39 static protected final int COMMAND_SEEK = 0xa2; 40 static protected final int COMMAND_GET_RESPONSE = 0xc0; 41 42 // from TS 11.11 9.2.5 43 static protected final int READ_RECORD_MODE_ABSOLUTE = 4; 44 45 //***** types of files TS 11.11 9.3 46 static protected final int EF_TYPE_TRANSPARENT = 0; 47 static protected final int EF_TYPE_LINEAR_FIXED = 1; 48 static protected final int EF_TYPE_CYCLIC = 3; 49 50 //***** types of files TS 11.11 9.3 51 static protected final int TYPE_RFU = 0; 52 static protected final int TYPE_MF = 1; 53 static protected final int TYPE_DF = 2; 54 static protected final int TYPE_EF = 4; 55 56 // size of GET_RESPONSE for EF's 57 static protected final int GET_RESPONSE_EF_SIZE_BYTES = 15; 58 static protected final int GET_RESPONSE_EF_IMG_SIZE_BYTES = 10; 59 60 // Byte order received in response to COMMAND_GET_RESPONSE 61 // Refer TS 51.011 Section 9.2.1 62 static protected final int RESPONSE_DATA_RFU_1 = 0; 63 static protected final int RESPONSE_DATA_RFU_2 = 1; 64 65 static protected final int RESPONSE_DATA_FILE_SIZE_1 = 2; 66 static protected final int RESPONSE_DATA_FILE_SIZE_2 = 3; 67 68 static protected final int RESPONSE_DATA_FILE_ID_1 = 4; 69 static protected final int RESPONSE_DATA_FILE_ID_2 = 5; 70 static protected final int RESPONSE_DATA_FILE_TYPE = 6; 71 static protected final int RESPONSE_DATA_RFU_3 = 7; 72 static protected final int RESPONSE_DATA_ACCESS_CONDITION_1 = 8; 73 static protected final int RESPONSE_DATA_ACCESS_CONDITION_2 = 9; 74 static protected final int RESPONSE_DATA_ACCESS_CONDITION_3 = 10; 75 static protected final int RESPONSE_DATA_FILE_STATUS = 11; 76 static protected final int RESPONSE_DATA_LENGTH = 12; 77 static protected final int RESPONSE_DATA_STRUCTURE = 13; 78 static protected final int RESPONSE_DATA_RECORD_LENGTH = 14; 79 80 81 //***** Events 82 83 /** Finished retrieving size of transparent EF; start loading. */ 84 static protected final int EVENT_GET_BINARY_SIZE_DONE = 4; 85 /** Finished loading contents of transparent EF; post result. */ 86 static protected final int EVENT_READ_BINARY_DONE = 5; 87 /** Finished retrieving size of records for linear-fixed EF; now load. */ 88 static protected final int EVENT_GET_RECORD_SIZE_DONE = 6; 89 /** Finished loading single record from a linear-fixed EF; post result. */ 90 static protected final int EVENT_READ_RECORD_DONE = 7; 91 /** Finished retrieving record size; post result. */ 92 static protected final int EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE = 8; 93 /** Finished retrieving image instance record; post result. */ 94 static protected final int EVENT_READ_IMG_DONE = 9; 95 /** Finished retrieving icon data; post result. */ 96 static protected final int EVENT_READ_ICON_DONE = 10; 97 /** Finished retrieving size of record for EFimg now. */ 98 static protected final int EVENT_GET_RECORD_SIZE_IMG_DONE = 11; 99 /** Finished retriveing record size of transparent file. */ 100 protected static final int EVENT_GET_EF_TRANSPARENT_SIZE_DONE = 12; 101 102 // member variables 103 @UnsupportedAppUsage 104 protected final CommandsInterface mCi; 105 @UnsupportedAppUsage 106 protected final UiccCardApplication mParentApp; 107 @UnsupportedAppUsage 108 protected final String mAid; 109 110 static class LoadLinearFixedContext { 111 112 int mEfid; 113 @UnsupportedAppUsage 114 int mRecordNum, mRecordSize, mCountRecords; 115 boolean mLoadAll; 116 String mPath; 117 118 Message mOnLoaded; 119 120 @UnsupportedAppUsage 121 ArrayList<byte[]> results; 122 123 @UnsupportedAppUsage LoadLinearFixedContext(int efid, int recordNum, Message onLoaded)124 LoadLinearFixedContext(int efid, int recordNum, Message onLoaded) { 125 mEfid = efid; 126 mRecordNum = recordNum; 127 mOnLoaded = onLoaded; 128 mLoadAll = false; 129 mPath = null; 130 } 131 LoadLinearFixedContext(int efid, int recordNum, String path, Message onLoaded)132 LoadLinearFixedContext(int efid, int recordNum, String path, Message onLoaded) { 133 mEfid = efid; 134 mRecordNum = recordNum; 135 mOnLoaded = onLoaded; 136 mLoadAll = false; 137 mPath = path; 138 } 139 LoadLinearFixedContext(int efid, String path, Message onLoaded)140 LoadLinearFixedContext(int efid, String path, Message onLoaded) { 141 mEfid = efid; 142 mRecordNum = 1; 143 mLoadAll = true; 144 mOnLoaded = onLoaded; 145 mPath = path; 146 } 147 LoadLinearFixedContext(int efid, Message onLoaded)148 LoadLinearFixedContext(int efid, Message onLoaded) { 149 mEfid = efid; 150 mRecordNum = 1; 151 mLoadAll = true; 152 mOnLoaded = onLoaded; 153 mPath = null; 154 } 155 } 156 157 /** 158 * Default constructor 159 */ IccFileHandler(UiccCardApplication app, String aid, CommandsInterface ci)160 protected IccFileHandler(UiccCardApplication app, String aid, CommandsInterface ci) { 161 mParentApp = app; 162 mAid = aid; 163 mCi = ci; 164 } 165 dispose()166 public void dispose() { 167 } 168 169 //***** Public Methods 170 171 /** 172 * Load a record from a SIM Linear Fixed EF 173 * 174 * @param fileid EF id 175 * @param path Path of the EF on the card 176 * @param recordNum 1-based (not 0-based) record number 177 * @param onLoaded 178 * 179 * ((AsyncResult)(onLoaded.obj)).result is the byte[] 180 * 181 */ 182 @UnsupportedAppUsage loadEFLinearFixed(int fileid, String path, int recordNum, Message onLoaded)183 public void loadEFLinearFixed(int fileid, String path, int recordNum, Message onLoaded) { 184 String efPath = (path == null) ? getEFPath(fileid) : path; 185 Message response 186 = obtainMessage(EVENT_GET_RECORD_SIZE_DONE, 187 new LoadLinearFixedContext(fileid, recordNum, efPath, onLoaded)); 188 189 mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, efPath, 190 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, response); 191 } 192 193 /** 194 * Load a record from a SIM Linear Fixed EF 195 * 196 * @param fileid EF id 197 * @param recordNum 1-based (not 0-based) record number 198 * @param onLoaded 199 * 200 * ((AsyncResult)(onLoaded.obj)).result is the byte[] 201 * 202 */ 203 @UnsupportedAppUsage loadEFLinearFixed(int fileid, int recordNum, Message onLoaded)204 public void loadEFLinearFixed(int fileid, int recordNum, Message onLoaded) { 205 loadEFLinearFixed(fileid, getEFPath(fileid), recordNum, onLoaded); 206 } 207 208 /** 209 * Load a image instance record from a SIM Linear Fixed EF-IMG 210 * 211 * @param recordNum 1-based (not 0-based) record number 212 * @param onLoaded 213 * 214 * ((AsyncResult)(onLoaded.obj)).result is the byte[] 215 * 216 */ loadEFImgLinearFixed(int recordNum, Message onLoaded)217 public void loadEFImgLinearFixed(int recordNum, Message onLoaded) { 218 Message response = obtainMessage(EVENT_GET_RECORD_SIZE_IMG_DONE, 219 new LoadLinearFixedContext(IccConstants.EF_IMG, recordNum, 220 onLoaded)); 221 222 mCi.iccIOForApp(COMMAND_GET_RESPONSE, IccConstants.EF_IMG, 223 getEFPath(IccConstants.EF_IMG), recordNum, 224 READ_RECORD_MODE_ABSOLUTE, GET_RESPONSE_EF_IMG_SIZE_BYTES, 225 null, null, mAid, response); 226 } 227 228 /** 229 * Get record size for a linear fixed EF 230 * 231 * @param fileid EF id 232 * @param path Path of the EF on the card 233 * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the recordSize[]. recordSize[0] is 234 * the single record length, recordSize[1] is the total length of the EF file 235 * and recordSize[2] is the number of records in the EF file. So recordSize[0] 236 * * recordSize[2] = recordSize[1]. 237 */ 238 @UnsupportedAppUsage getEFLinearRecordSize(int fileid, String path, Message onLoaded)239 public void getEFLinearRecordSize(int fileid, String path, Message onLoaded) { 240 String efPath = (path == null) ? getEFPath(fileid) : path; 241 Message response 242 = obtainMessage(EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE, 243 new LoadLinearFixedContext(fileid, efPath, onLoaded)); 244 mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, efPath, 245 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, response); 246 } 247 248 /** 249 * Get record size for a linear fixed EF 250 * 251 * @param fileid EF id 252 * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the recordSize[]. recordSize[0] is 253 * the single record length, recordSize[1] is the total length of the EF file 254 * and recordSize[2] is the number of records in the EF file. So recordSize[0] 255 * * recordSize[2] = recordSize[1]. 256 */ 257 @UnsupportedAppUsage getEFLinearRecordSize(int fileid, Message onLoaded)258 public void getEFLinearRecordSize(int fileid, Message onLoaded) { 259 getEFLinearRecordSize(fileid, getEFPath(fileid), onLoaded); 260 } 261 262 /** 263 * Get record size for a transparent EF 264 * 265 * @param fileid EF id 266 * @param path Path of the EF on the card 267 * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the size of data int 268 */ getEFTransparentRecordSize(int fileid, String path, Message onLoaded)269 public void getEFTransparentRecordSize(int fileid, String path, Message onLoaded) { 270 String efPath = (path == null) ? getEFPath(fileid) : path; 271 Message response = obtainMessage(EVENT_GET_EF_TRANSPARENT_SIZE_DONE, fileid, 0, onLoaded); 272 mCi.iccIOForApp( 273 COMMAND_GET_RESPONSE, 274 fileid, 275 getEFPath(fileid), 276 0, 277 0, 278 GET_RESPONSE_EF_SIZE_BYTES, 279 null, 280 null, 281 mAid, 282 response); 283 } 284 285 /** 286 * Get record size for a transparent EF 287 * 288 * @param fileid EF id 289 * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the size of the data int 290 */ getEFTransparentRecordSize(int fileid, Message onLoaded)291 public void getEFTransparentRecordSize(int fileid, Message onLoaded) { 292 getEFTransparentRecordSize(fileid, getEFPath(fileid), onLoaded); 293 } 294 295 /** 296 * Load all records from a SIM Linear Fixed EF 297 * 298 * @param fileid EF id 299 * @param path Path of the EF on the card 300 * @param onLoaded 301 * 302 * ((AsyncResult)(onLoaded.obj)).result is an ArrayList<byte[]> 303 */ 304 @UnsupportedAppUsage loadEFLinearFixedAll(int fileid, String path, Message onLoaded)305 public void loadEFLinearFixedAll(int fileid, String path, Message onLoaded) { 306 String efPath = (path == null) ? getEFPath(fileid) : path; 307 Message response = obtainMessage(EVENT_GET_RECORD_SIZE_DONE, 308 new LoadLinearFixedContext(fileid, efPath, onLoaded)); 309 310 mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, efPath, 311 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, response); 312 } 313 314 /** 315 * Load all records from a SIM Linear Fixed EF 316 * 317 * @param fileid EF id 318 * @param onLoaded 319 * 320 * ((AsyncResult)(onLoaded.obj)).result is an ArrayList<byte[]> 321 * 322 */ 323 @UnsupportedAppUsage loadEFLinearFixedAll(int fileid, Message onLoaded)324 public void loadEFLinearFixedAll(int fileid, Message onLoaded) { 325 loadEFLinearFixedAll(fileid, getEFPath(fileid), onLoaded); 326 } 327 328 /** 329 * Load a SIM Transparent EF 330 * 331 * @param fileid EF id 332 * @param onLoaded 333 * 334 * ((AsyncResult)(onLoaded.obj)).result is the byte[] 335 */ 336 @UnsupportedAppUsage loadEFTransparent(int fileid, Message onLoaded)337 public void loadEFTransparent(int fileid, Message onLoaded) { 338 Message response = obtainMessage(EVENT_GET_BINARY_SIZE_DONE, 339 fileid, 0, onLoaded); 340 341 mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid), 342 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, response); 343 } 344 345 /** 346 * Load first @size bytes from SIM Transparent EF 347 * 348 * @param fileid EF id 349 * @param size 350 * @param onLoaded 351 * 352 * ((AsyncResult)(onLoaded.obj)).result is the byte[] 353 * 354 */ loadEFTransparent(int fileid, int size, Message onLoaded)355 public void loadEFTransparent(int fileid, int size, Message onLoaded) { 356 Message response = obtainMessage(EVENT_READ_BINARY_DONE, 357 fileid, 0, onLoaded); 358 359 mCi.iccIOForApp(COMMAND_READ_BINARY, fileid, getEFPath(fileid), 360 0, 0, size, null, null, mAid, response); 361 } 362 363 /** 364 * Load a SIM Transparent EF-IMG. Used right after loadEFImgLinearFixed to 365 * retrive STK's icon data. 366 * 367 * @param fileid EF id 368 * @param onLoaded 369 * 370 * ((AsyncResult)(onLoaded.obj)).result is the byte[] 371 * 372 */ loadEFImgTransparent(int fileid, int highOffset, int lowOffset, int length, Message onLoaded)373 public void loadEFImgTransparent(int fileid, int highOffset, int lowOffset, 374 int length, Message onLoaded) { 375 Message response = obtainMessage(EVENT_READ_ICON_DONE, fileid, 0, 376 onLoaded); 377 378 logd("IccFileHandler: loadEFImgTransparent fileid = " + fileid 379 + " filePath = " + getEFPath(EF_IMG) + " highOffset = " + highOffset 380 + " lowOffset = " + lowOffset + " length = " + length); 381 382 /* Per TS 31.102, for displaying of Icon, under 383 * DF Telecom and DF Graphics , EF instance(s) (4FXX,transparent files) 384 * are present. The possible image file identifiers (EF instance) for 385 * EF img ( 4F20, linear fixed file) are : 4F01 ... 4F05. 386 * It should be MF_SIM + DF_TELECOM + DF_GRAPHICS, same path as EF IMG 387 */ 388 mCi.iccIOForApp(COMMAND_READ_BINARY, fileid, getEFPath(EF_IMG), 389 highOffset, lowOffset, length, null, null, mAid, response); 390 } 391 392 /** 393 * Update a record in a linear fixed EF 394 * @param fileid EF id 395 * @param path Path of the EF on the card 396 * @param recordNum 1-based (not 0-based) record number 397 * @param data must be exactly as long as the record in the EF 398 * @param pin2 for CHV2 operations, otherwist must be null 399 * @param onComplete onComplete.obj will be an AsyncResult 400 * onComplete.obj.userObj will be a IccIoResult on success 401 */ 402 @UnsupportedAppUsage updateEFLinearFixed(int fileid, String path, int recordNum, byte[] data, String pin2, Message onComplete)403 public void updateEFLinearFixed(int fileid, String path, int recordNum, byte[] data, 404 String pin2, Message onComplete) { 405 String efPath = (path == null) ? getEFPath(fileid) : path; 406 mCi.iccIOForApp(COMMAND_UPDATE_RECORD, fileid, efPath, 407 recordNum, READ_RECORD_MODE_ABSOLUTE, data.length, 408 IccUtils.bytesToHexString(data), pin2, mAid, onComplete); 409 } 410 411 /** 412 * Update a record in a linear fixed EF 413 * @param fileid EF id 414 * @param recordNum 1-based (not 0-based) record number 415 * @param data must be exactly as long as the record in the EF 416 * @param pin2 for CHV2 operations, otherwist must be null 417 * @param onComplete onComplete.obj will be an AsyncResult 418 * onComplete.obj.userObj will be a IccIoResult on success 419 */ 420 @UnsupportedAppUsage updateEFLinearFixed(int fileid, int recordNum, byte[] data, String pin2, Message onComplete)421 public void updateEFLinearFixed(int fileid, int recordNum, byte[] data, 422 String pin2, Message onComplete) { 423 mCi.iccIOForApp(COMMAND_UPDATE_RECORD, fileid, getEFPath(fileid), 424 recordNum, READ_RECORD_MODE_ABSOLUTE, data.length, 425 IccUtils.bytesToHexString(data), pin2, mAid, onComplete); 426 } 427 428 /** 429 * Update a transparent EF 430 * @param fileid EF id 431 * @param data must be exactly as long as the EF 432 */ 433 @UnsupportedAppUsage updateEFTransparent(int fileid, byte[] data, Message onComplete)434 public void updateEFTransparent(int fileid, byte[] data, Message onComplete) { 435 mCi.iccIOForApp(COMMAND_UPDATE_BINARY, fileid, getEFPath(fileid), 436 0, 0, data.length, 437 IccUtils.bytesToHexString(data), null, mAid, onComplete); 438 } 439 440 441 //***** Abstract Methods 442 443 444 //***** Private Methods 445 sendResult(Message response, Object result, Throwable ex)446 private void sendResult(Message response, Object result, Throwable ex) { 447 if (response == null) { 448 return; 449 } 450 451 AsyncResult.forMessage(response, result, ex); 452 453 response.sendToTarget(); 454 } 455 processException(Message response, AsyncResult ar)456 private boolean processException(Message response, AsyncResult ar) { 457 IccException iccException; 458 boolean flag = false; 459 IccIoResult result = (IccIoResult) ar.result; 460 if (ar.exception != null) { 461 sendResult(response, null, ar.exception); 462 flag = true; 463 } else { 464 iccException = result.getException(); 465 if (iccException != null) { 466 sendResult(response, null, iccException); 467 flag = true; 468 } 469 } 470 return flag; 471 } 472 473 //***** Overridden from Handler 474 475 @Override handleMessage(Message msg)476 public void handleMessage(Message msg) { 477 AsyncResult ar; 478 IccIoResult result; 479 Message response = null; 480 String str; 481 LoadLinearFixedContext lc; 482 483 byte data[]; 484 int size; 485 int fileid; 486 int recordSize[]; 487 String path = null; 488 489 try { 490 switch (msg.what) { 491 case EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE: 492 ar = (AsyncResult)msg.obj; 493 lc = (LoadLinearFixedContext) ar.userObj; 494 result = (IccIoResult) ar.result; 495 response = lc.mOnLoaded; 496 497 if (processException(response, (AsyncResult) msg.obj)) { 498 break; 499 } 500 501 data = result.payload; 502 503 if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE] || 504 EF_TYPE_LINEAR_FIXED != data[RESPONSE_DATA_STRUCTURE]) { 505 throw new IccFileTypeMismatch(); 506 } 507 508 recordSize = new int[3]; 509 recordSize[0] = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF; 510 recordSize[1] = getDataFileSize(data); 511 recordSize[2] = recordSize[1] / recordSize[0]; 512 513 sendResult(response, recordSize, null); 514 break; 515 516 case EVENT_GET_RECORD_SIZE_IMG_DONE: 517 case EVENT_GET_RECORD_SIZE_DONE: 518 ar = (AsyncResult)msg.obj; 519 lc = (LoadLinearFixedContext) ar.userObj; 520 result = (IccIoResult) ar.result; 521 response = lc.mOnLoaded; 522 523 if (processException(response, (AsyncResult) msg.obj)) { 524 loge("exception caught from EVENT_GET_RECORD_SIZE"); 525 break; 526 } 527 528 data = result.payload; 529 path = lc.mPath; 530 531 if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE]) { 532 throw new IccFileTypeMismatch(); 533 } 534 535 if (EF_TYPE_LINEAR_FIXED != data[RESPONSE_DATA_STRUCTURE]) { 536 throw new IccFileTypeMismatch(); 537 } 538 539 lc.mRecordSize = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF; 540 541 size = getDataFileSize(data); 542 543 lc.mCountRecords = size / lc.mRecordSize; 544 545 if (lc.mLoadAll) { 546 lc.results = new ArrayList<byte[]>(lc.mCountRecords); 547 } 548 549 if (path == null) { 550 path = getEFPath(lc.mEfid); 551 } 552 mCi.iccIOForApp(COMMAND_READ_RECORD, lc.mEfid, path, 553 lc.mRecordNum, 554 READ_RECORD_MODE_ABSOLUTE, 555 lc.mRecordSize, null, null, mAid, 556 obtainMessage(EVENT_READ_RECORD_DONE, lc)); 557 break; 558 case EVENT_GET_BINARY_SIZE_DONE: 559 ar = (AsyncResult)msg.obj; 560 response = (Message) ar.userObj; 561 result = (IccIoResult) ar.result; 562 563 if (processException(response, (AsyncResult) msg.obj)) { 564 break; 565 } 566 567 data = result.payload; 568 569 fileid = msg.arg1; 570 571 if (VDBG) { 572 logd(String.format("Contents of the Select Response for command %x: ", fileid) 573 + IccUtils.bytesToHexString(data)); 574 } 575 576 if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE]) { 577 throw new IccFileTypeMismatch(); 578 } 579 580 if (EF_TYPE_TRANSPARENT != data[RESPONSE_DATA_STRUCTURE]) { 581 throw new IccFileTypeMismatch(); 582 } 583 584 size = getDataFileSize(data); 585 586 mCi.iccIOForApp(COMMAND_READ_BINARY, fileid, getEFPath(fileid), 587 0, 0, size, null, null, mAid, 588 obtainMessage(EVENT_READ_BINARY_DONE, 589 fileid, 0, response)); 590 break; 591 592 case EVENT_READ_IMG_DONE: 593 case EVENT_READ_RECORD_DONE: 594 595 ar = (AsyncResult)msg.obj; 596 lc = (LoadLinearFixedContext) ar.userObj; 597 result = (IccIoResult) ar.result; 598 response = lc.mOnLoaded; 599 path = lc.mPath; 600 601 if (processException(response, (AsyncResult) msg.obj)) { 602 break; 603 } 604 605 if (!lc.mLoadAll) { 606 sendResult(response, result.payload, null); 607 } else { 608 lc.results.add(result.payload); 609 610 lc.mRecordNum++; 611 612 if (lc.mRecordNum > lc.mCountRecords) { 613 sendResult(response, lc.results, null); 614 } else { 615 if (path == null) { 616 path = getEFPath(lc.mEfid); 617 } 618 619 mCi.iccIOForApp(COMMAND_READ_RECORD, lc.mEfid, path, 620 lc.mRecordNum, 621 READ_RECORD_MODE_ABSOLUTE, 622 lc.mRecordSize, null, null, mAid, 623 obtainMessage(EVENT_READ_RECORD_DONE, lc)); 624 } 625 } 626 627 break; 628 629 case EVENT_READ_BINARY_DONE: 630 case EVENT_READ_ICON_DONE: 631 ar = (AsyncResult)msg.obj; 632 response = (Message) ar.userObj; 633 result = (IccIoResult) ar.result; 634 635 if (processException(response, (AsyncResult) msg.obj)) { 636 break; 637 } 638 639 sendResult(response, result.payload, null); 640 break; 641 642 case EVENT_GET_EF_TRANSPARENT_SIZE_DONE: 643 ar = (AsyncResult) msg.obj; 644 response = (Message) ar.userObj; 645 result = (IccIoResult) ar.result; 646 647 if (processException(response, (AsyncResult) msg.obj)) { 648 break; 649 } 650 651 data = result.payload; 652 653 fileid = msg.arg1; 654 655 if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE]) { 656 throw new IccFileTypeMismatch(); 657 } 658 659 if (EF_TYPE_TRANSPARENT != data[RESPONSE_DATA_STRUCTURE]) { 660 throw new IccFileTypeMismatch(); 661 } 662 663 size = getDataFileSize(data); 664 sendResult(response, size, null); 665 break; 666 667 }} catch (Exception exc) { 668 if (response != null) { 669 sendResult(response, null, exc); 670 } else { 671 loge("uncaught exception" + exc); 672 } 673 } 674 } 675 676 /** 677 * Returns the root path of the EF file. 678 * i.e returns MainFile + DFfile as a string. 679 * Ex: For EF_ADN on a SIM, it will return "3F007F10" 680 * This function handles only EFids that are common to 681 * RUIM, SIM, USIM and other types of Icc cards. 682 * 683 * @param efid of path to retrieve 684 * @return root path of the file. 685 */ getCommonIccEFPath(int efid)686 protected String getCommonIccEFPath(int efid) { 687 switch(efid) { 688 case EF_ADN: 689 case EF_FDN: 690 case EF_MSISDN: 691 case EF_SDN: 692 case EF_EXT1: 693 case EF_EXT2: 694 case EF_EXT3: 695 case EF_PSI: 696 return MF_SIM + DF_TELECOM; 697 698 case EF_ICCID: 699 case EF_PL: 700 return MF_SIM; 701 case EF_PBR: 702 // we only support global phonebook. 703 return MF_SIM + DF_TELECOM + DF_PHONEBOOK; 704 case EF_IMG: 705 return MF_SIM + DF_TELECOM + DF_GRAPHICS; 706 } 707 return null; 708 } 709 710 @UnsupportedAppUsage getEFPath(int efid)711 protected abstract String getEFPath(int efid); logd(String s)712 protected abstract void logd(String s); loge(String s)713 protected abstract void loge(String s); 714 715 /** 716 * Calculate the size of a data file 717 * 718 * @param data the raw file 719 * @return the size of the file 720 */ getDataFileSize(byte[] data)721 private static int getDataFileSize(byte[] data) { 722 return (((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8) 723 + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff)); 724 } 725 } 726