SapMessage.java revision e377aae948e58f974c3af14360d2f6ce09b868aa
1package com.android.bluetooth.sap; 2 3import java.io.IOException; 4import java.io.InputStream; 5import java.io.OutputStream; 6import java.security.InvalidParameterException; 7import java.util.Arrays; 8import java.util.Hashtable; 9import java.util.Map; 10import java.util.concurrent.atomic.AtomicInteger; 11 12import org.android.btsap.SapApi; 13import org.android.btsap.SapApi.*; 14import com.google.protobuf.micro.*; 15 16import android.os.Parcel; 17import android.os.Parcelable; 18import android.util.Log; 19 20/** 21 * SapMessage is used for incoming and outgoing messages. 22 * 23 * For incoming messages 24 * 25 */ 26public class SapMessage { 27 28 public static final String TAG = "SapMessage"; 29 public static final boolean DEBUG = SapService.DEBUG; 30 public static final boolean VERBOSE = SapService.VERBOSE; 31 public static final boolean TEST = SapService.PTS_TEST; 32 33 /* Message IDs - SAP specification */ 34 public static final int ID_CONNECT_REQ = 0x00; 35 public static final int ID_CONNECT_RESP = 0x01; 36 37 public static final int ID_DISCONNECT_REQ = 0x02; 38 public static final int ID_DISCONNECT_RESP = 0x03; 39 public static final int ID_DISCONNECT_IND = 0x04; 40 41 public static final int ID_TRANSFER_APDU_REQ = 0x05; 42 public static final int ID_TRANSFER_APDU_RESP = 0x06; 43 44 public static final int ID_TRANSFER_ATR_REQ = 0x07; 45 public static final int ID_TRANSFER_ATR_RESP = 0x08; 46 47 public static final int ID_POWER_SIM_OFF_REQ = 0x09; 48 public static final int ID_POWER_SIM_OFF_RESP = 0x0A; 49 50 public static final int ID_POWER_SIM_ON_REQ = 0x0B; 51 public static final int ID_POWER_SIM_ON_RESP = 0x0C; 52 53 public static final int ID_RESET_SIM_REQ = 0x0D; 54 public static final int ID_RESET_SIM_RESP = 0x0E; 55 56 public static final int ID_TRANSFER_CARD_READER_STATUS_REQ = 0x0F; 57 public static final int ID_TRANSFER_CARD_READER_STATUS_RESP = 0x10; 58 59 public static final int ID_STATUS_IND = 0x11; 60 public static final int ID_ERROR_RESP = 0x12; 61 62 public static final int ID_SET_TRANSPORT_PROTOCOL_REQ = 0x13; 63 public static final int ID_SET_TRANSPORT_PROTOCOL_RESP = 0x14; 64 65 /* Message IDs - RIL specific unsolicited */ 66 // First RIL message id 67 public static final int ID_RIL_BASE = 0x100; 68 // RIL_UNSOL_RIL_CONNECTED 69 public static final int ID_RIL_UNSOL_CONNECTED = 0x100; 70 // A disconnect ind from RIL will be converted after handled locally 71 public static final int ID_RIL_UNSOL_DISCONNECT_IND = 0x102; 72 // All others 73 public static final int ID_RIL_UNKNOWN = 0x1ff; 74 75 /* Message IDs - RIL specific solicited */ 76 public static final int ID_RIL_GET_SIM_STATUS_REQ = 0x200; // RIL_REQUEST_GET_SIM_STATUS 77 /* Test signals used to set the reference ril in test mode */ 78 public static final int ID_RIL_SIM_ACCESS_TEST_REQ = 0x201; // RIL_REQUEST_SIM_ACCESS_TEST 79 public static final int ID_RIL_SIM_ACCESS_TEST_RESP = 0x202; /* response for 80 RIL_REQUEST_SIM_ACCESS_TEST */ 81 82 /* Parameter IDs and lengths */ 83 public static final int PARAM_MAX_MSG_SIZE_ID = 0x00; 84 public static final int PARAM_MAX_MSG_SIZE_LENGTH = 2; 85 86 public static final int PARAM_CONNECTION_STATUS_ID = 0x01; 87 public static final int PARAM_CONNECTION_STATUS_LENGTH = 1; 88 89 public static final int PARAM_RESULT_CODE_ID = 0x02; 90 public static final int PARAM_RESULT_CODE_LENGTH = 1; 91 92 public static final int PARAM_DISCONNECT_TYPE_ID = 0x03; 93 public static final int PARAM_DISCONNECT_TYPE_LENGTH = 1; 94 95 public static final int PARAM_COMMAND_APDU_ID = 0x04; 96 97 public static final int PARAM_COMMAND_APDU7816_ID = 0x10; 98 99 public static final int PARAM_RESPONSE_APDU_ID = 0x05; 100 101 public static final int PARAM_ATR_ID = 0x06; 102 103 public static final int PARAM_CARD_READER_STATUS_ID = 0x07; 104 public static final int PARAM_CARD_READER_STATUS_LENGTH = 1; 105 106 public static final int PARAM_STATUS_CHANGE_ID = 0x08; 107 public static final int PARAM_STATUS_CHANGE_LENGTH = 1; 108 109 public static final int PARAM_TRANSPORT_PROTOCOL_ID = 0x09; 110 public static final int PARAM_TRANSPORT_PROTOCOL_LENGTH = 1; 111 112 /* Result codes */ 113 public static final int RESULT_OK = 0x00; 114 public static final int RESULT_ERROR_NO_REASON = 0x01; 115 public static final int RESULT_ERROR_CARD_NOT_ACCESSIBLE = 0x02; 116 public static final int RESULT_ERROR_CARD_POWERED_OFF = 0x03; 117 public static final int RESULT_ERROR_CARD_REMOVED = 0x04; 118 public static final int RESULT_ERROR_CARD_POWERED_ON = 0x05; 119 public static final int RESULT_ERROR_DATA_NOT_AVAILABLE = 0x06; 120 public static final int RESULT_ERROR_NOT_SUPPORTED = 0x07; 121 122 /* Connection Status codes */ 123 public static final int CON_STATUS_OK = 0x00; 124 public static final int CON_STATUS_ERROR_CONNECTION = 0x01; 125 public static final int CON_STATUS_ERROR_MAX_MSG_SIZE_UNSUPPORTED = 0x02; 126 public static final int CON_STATUS_ERROR_MAX_MSG_SIZE_TOO_SMALL = 0x03; 127 public static final int CON_STATUS_OK_ONGOING_CALL = 0x04; 128 129 /* Disconnection type */ 130 public static final int DISC_GRACEFULL = 0x00; 131 public static final int DISC_IMMEDIATE = 0x01; 132 public static final int DISC_FORCED = 0x100; // Used internal only 133 public static final int DISC_RFCOMM = 0x101; // Used internal only 134 135 /* Status Change */ 136 public static final int STATUS_UNKNOWN_ERROR = 0x00; 137 public static final int STATUS_CARD_RESET = 0x01; 138 public static final int STATUS_CARD_NOT_ACCESSIBLE = 0x02; 139 public static final int STATUS_CARD_REMOVED = 0x03; 140 public static final int STATUS_CARD_INSERTED = 0x04; 141 public static final int STATUS_RECOVERED = 0x05; 142 143 /* Transport Protocol */ 144 public static final int TRANS_PROTO_T0 = 0x00; 145 public static final int TRANS_PROTO_T1 = 0x01; 146 147 /* Test Mode */ 148 public static final int TEST_MODE_DISABLE = 0x00; 149 public static final int TEST_MODE_ENABLE = 0x01; 150 151 /* Used to detect uninitialized values */ 152 public static final int INVALID_VALUE = -1; 153 154 /* Stuff related to communicating with rild-bt */ 155 static final int RESPONSE_SOLICITED = 0; 156 static final int RESPONSE_UNSOLICITED = 1; 157 static AtomicInteger sNextSerial = new AtomicInteger(1); 158 159 // Map<rilSerial, RequestType> - HashTable is synchronized 160 private static Map<Integer, Integer> sOngoingRequests = new Hashtable<Integer, Integer>(); 161 private boolean mSendToRil = false; // set to true for messages that needs to go to the RIL 162 private boolean mClearRilQueue = false; /* set to true for messages that needs to cause the 163 sOngoingRequests to be cleared. */ 164 165 /* Instance members */ 166 private int mMsgType = INVALID_VALUE; // The SAP message ID 167 168 private int mMaxMsgSize = INVALID_VALUE; 169 private int mConnectionStatus = INVALID_VALUE; 170 private int mResultCode = INVALID_VALUE; 171 private int mDisconnectionType = INVALID_VALUE; 172 private int mCardReaderStatus = INVALID_VALUE; 173 private int mStatusChange = INVALID_VALUE; 174 private int mTransportProtocol = INVALID_VALUE; 175 private int mTestMode = INVALID_VALUE; 176 private byte[] mApdu = null; 177 private byte[] mApdu7816 = null; 178 private byte[] mApduResp = null; 179 private byte[] mAtr = null; 180 181 /** 182 * Create a SapMessage 183 * @param msgType the SAP message type 184 */ 185 public SapMessage(int msgType){ 186 this.mMsgType = msgType; 187 } 188 189 private static void resetPendingRilMessages() { 190 int numMessages = sOngoingRequests.size(); 191 if(numMessages != 0) { 192 Log.w(TAG, "Clearing message queue with size: " + numMessages); 193 sOngoingRequests.clear(); 194 } 195 } 196 197 public static int getNumPendingRilMessages() { 198 return sOngoingRequests.size(); 199 } 200 201 public int getMsgType() { 202 return mMsgType; 203 } 204 205 public void setMsgType(int msgType) { 206 this.mMsgType = msgType; 207 } 208 209 public int getMaxMsgSize() { 210 return mMaxMsgSize; 211 } 212 213 public void setMaxMsgSize(int maxMsgSize) { 214 this.mMaxMsgSize = maxMsgSize; 215 } 216 217 public int getConnectionStatus() { 218 return mConnectionStatus; 219 } 220 221 public void setConnectionStatus(int connectionStatus) { 222 this.mConnectionStatus = connectionStatus; 223 } 224 225 public int getResultCode() { 226 return mResultCode; 227 } 228 229 public void setResultCode(int resultCode) { 230 this.mResultCode = resultCode; 231 } 232 233 public int getDisconnectionType() { 234 return mDisconnectionType; 235 } 236 237 public void setDisconnectionType(int disconnectionType) { 238 this.mDisconnectionType = disconnectionType; 239 } 240 241 public int getCardReaderStatus() { 242 return mCardReaderStatus; 243 } 244 245 public void setCardReaderStatus(int cardReaderStatus) { 246 this.mCardReaderStatus = cardReaderStatus; 247 } 248 249 public int getStatusChange() { 250 return mStatusChange; 251 } 252 253 public void setStatusChange(int statusChange) { 254 this.mStatusChange = statusChange; 255 } 256 257 public int getTransportProtocol() { 258 return mTransportProtocol; 259 } 260 261 public void setTransportProtocol(int transportProtocol) { 262 this.mTransportProtocol = transportProtocol; 263 } 264 265 public byte[] getApdu() { 266 return mApdu; 267 } 268 269 public void setApdu(byte[] apdu) { 270 this.mApdu = apdu; 271 } 272 273 public byte[] getApdu7816() { 274 return mApdu7816; 275 } 276 277 public void setApdu7816(byte[] apdu) { 278 this.mApdu7816 = apdu; 279 } 280 281 public byte[] getApduResp() { 282 return mApduResp; 283 } 284 285 public void setApduResp(byte[] apduResp) { 286 this.mApduResp = apduResp; 287 } 288 289 public byte[] getAtr() { 290 return mAtr; 291 } 292 293 public void setAtr(byte[] atr) { 294 this.mAtr = atr; 295 } 296 297 public boolean getSendToRil() { 298 return mSendToRil; 299 } 300 301 public void setSendToRil(boolean sendToRil) { 302 this.mSendToRil = sendToRil; 303 } 304 305 public boolean getClearRilQueue() { 306 return mClearRilQueue; 307 } 308 309 public void setClearRilQueue(boolean clearRilQueue) { 310 this.mClearRilQueue = clearRilQueue; 311 } 312 313 public int getTestMode() { 314 return mTestMode; 315 } 316 317 public void setTestMode(int testMode) { 318 this.mTestMode = testMode; 319 } 320 321 private int getParamCount() { 322 int paramCount = 0; 323 if(mMaxMsgSize != INVALID_VALUE) 324 paramCount++; 325 if(mConnectionStatus != INVALID_VALUE) 326 paramCount++; 327 if(mResultCode != INVALID_VALUE) 328 paramCount++; 329 if(mDisconnectionType != INVALID_VALUE) 330 paramCount++; 331 if(mCardReaderStatus != INVALID_VALUE) 332 paramCount++; 333 if(mStatusChange != INVALID_VALUE) 334 paramCount++; 335 if(mTransportProtocol != INVALID_VALUE) 336 paramCount++; 337 if(mApdu != null) 338 paramCount++; 339 if(mApdu7816 != null) 340 paramCount++; 341 if(mApduResp != null) 342 paramCount++; 343 if(mAtr != null) 344 paramCount++; 345 return paramCount; 346 } 347 348 /** 349 * Construct a SapMessage based on the incoming rfcomm request. 350 * @param requestType The type of the request 351 * @param is the input stream to read the data from 352 * @return the resulting message, or null if an error occurs 353 */ 354 @SuppressWarnings("unused") 355 public static SapMessage readMessage(int requestType, InputStream is) { 356 SapMessage newMessage = new SapMessage(requestType); 357 358 /* Read in all the parameters (if any) */ 359 int paramCount; 360 try { 361 paramCount = is.read(); 362 skip(is, 2); // Skip the 2 padding bytes 363 if(paramCount > 0) { 364 if(VERBOSE) Log.i(TAG, "Parsing message with paramCount: " + paramCount); 365 if(newMessage.parseParameters(paramCount, is) == false) 366 return null; 367 } 368 } catch (IOException e) { 369 Log.w(TAG, e); 370 return null; 371 } 372 if(DEBUG) Log.i(TAG, "readMessage() Read message: " + getMsgTypeName(requestType)); 373 374 /* Validate parameters */ 375 switch(requestType) { 376 case ID_CONNECT_REQ: 377 if(newMessage.getMaxMsgSize() == INVALID_VALUE) { 378 Log.e(TAG, "Missing MaxMsgSize parameter in CONNECT_REQ"); 379 return null; 380 } 381 break; 382 case ID_TRANSFER_APDU_REQ: 383 if(newMessage.getApdu() == null && 384 newMessage.getApdu7816() == null) { 385 Log.e(TAG, "Missing Apdu parameter in TRANSFER_APDU_REQ"); 386 return null; 387 } 388 newMessage.setSendToRil(true); 389 break; 390 case ID_SET_TRANSPORT_PROTOCOL_REQ: 391 if(newMessage.getTransportProtocol() == INVALID_VALUE) { 392 Log.e(TAG, "Missing TransportProtocol parameter in SET_TRANSPORT_PROTOCOL_REQ"); 393 return null; 394 } 395 newMessage.setSendToRil(true); 396 break; 397 case ID_TRANSFER_ATR_REQ: /* No params */ 398 case ID_POWER_SIM_OFF_REQ: /* No params */ 399 case ID_POWER_SIM_ON_REQ: /* No params */ 400 case ID_RESET_SIM_REQ: /* No params */ 401 case ID_TRANSFER_CARD_READER_STATUS_REQ: /* No params */ 402 newMessage.setSendToRil(true); 403 break; 404 case ID_DISCONNECT_REQ: /* No params */ 405 break; 406 default: 407 if(TEST == false) { 408 Log.e(TAG, "Unknown request type"); 409 return null; 410 } 411 } 412 return newMessage; 413 } 414 415 /** 416 * Blocking read of an entire array of data. 417 * @param is the input stream to read from 418 * @param buffer the buffer to read into - the length of the buffer will 419 * determine how many bytes will be read. 420 */ 421 private static void read(InputStream is, byte[] buffer) throws IOException { 422 int bytesToRead = buffer.length; 423 int bytesRead = 0; 424 int tmpBytesRead; 425 while (bytesRead < bytesToRead) { 426 tmpBytesRead = is.read(buffer, bytesRead, bytesToRead-bytesRead); 427 if(tmpBytesRead == -1) 428 throw new IOException("EOS reached while reading a byte array."); 429 else 430 bytesRead += tmpBytesRead; 431 } 432 } 433 434 /** 435 * Skip a number of bytes in an InputStream. 436 * @param is the input stream 437 * @param count the number of bytes to skip 438 * @throws IOException In case of reaching EOF or a stream error 439 */ 440 private static void skip(InputStream is, int count) throws IOException { 441 for(int i = 0; i < count; i++) { 442 is.read(); // Do not use the InputStream.skip as it fails for some stream types 443 } 444 } 445 446 /** 447 * Read the parameters from the stream and update the relevant members. 448 * This function will ensure that all parameters are read from the stream, even 449 * if an error is detected. 450 * @param count the number of parameters to read 451 * @param is the input stream 452 * @return True if all parameters were successfully parsed, False if an error were detected. 453 * @throws IOException 454 */ 455 private boolean parseParameters(int count, InputStream is) throws IOException { 456 int paramId; 457 int paramLength; 458 boolean success = true; 459 int skipLen = 0; 460 461 for(int i = 0; i < count; i++) { 462 paramId = is.read(); 463 is.read(); // Skip the reserved byte 464 paramLength = is.read(); 465 paramLength = paramLength << 8 | is.read(); 466 467 // As per SAP spec padding should be 0-3 bytes 468 if ((paramLength % 4) != 0) 469 skipLen = 4 - (paramLength % 4); 470 471 if(VERBOSE) Log.i(TAG, "parsing paramId: " + paramId + " with length: " + paramLength); 472 switch(paramId) { 473 case PARAM_MAX_MSG_SIZE_ID: 474 if(paramLength != PARAM_MAX_MSG_SIZE_LENGTH) { 475 Log.e(TAG, "Received PARAM_MAX_MSG_SIZE with wrong length: " + 476 paramLength + " skipping this parameter."); 477 skip(is, paramLength + skipLen); 478 success = false; 479 } else { 480 mMaxMsgSize = is.read(); 481 mMaxMsgSize = mMaxMsgSize << 8 | is.read(); 482 skip(is, 4 - PARAM_MAX_MSG_SIZE_LENGTH); 483 } 484 break; 485 case PARAM_COMMAND_APDU_ID: 486 mApdu = new byte[paramLength]; 487 read(is, mApdu); 488 skip(is, skipLen); 489 break; 490 case PARAM_COMMAND_APDU7816_ID: 491 mApdu7816 = new byte[paramLength]; 492 read(is, mApdu7816); 493 skip(is, skipLen); 494 break; 495 case PARAM_TRANSPORT_PROTOCOL_ID: 496 if(paramLength != PARAM_TRANSPORT_PROTOCOL_LENGTH) { 497 Log.e(TAG, "Received PARAM_TRANSPORT_PROTOCOL with wrong length: " + 498 paramLength + " skipping this parameter."); 499 skip(is, paramLength + skipLen); 500 success = false; 501 } else { 502 mTransportProtocol = is.read(); 503 skip(is, 4 - PARAM_TRANSPORT_PROTOCOL_LENGTH); 504 } 505 break; 506 case PARAM_CONNECTION_STATUS_ID: 507 // not needed - server -> client 508 if(TEST) { 509 if(paramLength != PARAM_CONNECTION_STATUS_LENGTH) { 510 Log.e(TAG, "Received PARAM_CONNECTION_STATUS with wrong length: " + 511 paramLength + " skipping this parameter."); 512 skip(is, paramLength + skipLen); 513 success = false; 514 } else { 515 mConnectionStatus = is.read(); 516 skip(is, 4 - PARAM_CONNECTION_STATUS_LENGTH); 517 } 518 break; 519 } // Fall through if TEST == false 520 case PARAM_CARD_READER_STATUS_ID: 521 // not needed - server -> client 522 if(TEST) { 523 if(paramLength != PARAM_CARD_READER_STATUS_LENGTH) { 524 Log.e(TAG, "Received PARAM_CARD_READER_STATUS with wrong length: " + 525 paramLength + " skipping this parameter."); 526 skip(is, paramLength + skipLen); 527 success = false; 528 } else { 529 mCardReaderStatus = is.read(); 530 skip(is, 4 - PARAM_CARD_READER_STATUS_LENGTH); 531 } 532 break; 533 } // Fall through if TEST == false 534 case PARAM_STATUS_CHANGE_ID: 535 // not needed - server -> client 536 if(TEST) { 537 if(paramLength != PARAM_STATUS_CHANGE_LENGTH) { 538 Log.e(TAG, "Received PARAM_STATUS_CHANGE with wrong length: " + 539 paramLength + " skipping this parameter."); 540 skip(is, paramLength + skipLen); 541 success = false; 542 } else { 543 mStatusChange = is.read(); 544 skip(is, 4 - PARAM_STATUS_CHANGE_LENGTH); 545 } 546 break; 547 } // Fall through if TEST == false 548 case PARAM_RESULT_CODE_ID: 549 // not needed - server -> client 550 if(TEST) { 551 if(paramLength != PARAM_RESULT_CODE_LENGTH) { 552 Log.e(TAG, "Received PARAM_RESULT_CODE with wrong length: " + 553 paramLength + " skipping this parameter."); 554 skip(is, paramLength + skipLen); 555 success = false; 556 } else { 557 mResultCode = is.read(); 558 skip(is, 4 - PARAM_RESULT_CODE_LENGTH); 559 } 560 break; 561 } // Fall through if TEST == false 562 case PARAM_DISCONNECT_TYPE_ID: 563 // not needed - server -> client 564 if(TEST) { 565 if(paramLength != PARAM_DISCONNECT_TYPE_LENGTH) { 566 Log.e(TAG, "Received PARAM_DISCONNECT_TYPE_ID with wrong length: " + 567 paramLength + " skipping this parameter."); 568 skip(is, paramLength + skipLen); 569 success = false; 570 } else { 571 mDisconnectionType = is.read(); 572 skip(is, 4 - PARAM_DISCONNECT_TYPE_LENGTH); 573 } 574 break; 575 } // Fall through if TEST == false 576 case PARAM_RESPONSE_APDU_ID: 577 // not needed - server -> client 578 if(TEST) { 579 mApduResp = new byte[paramLength]; 580 read(is, mApduResp); 581 skip(is, skipLen); 582 break; 583 } // Fall through if TEST == false 584 case PARAM_ATR_ID: 585 // not needed - server -> client 586 if(TEST) { 587 mAtr = new byte[paramLength]; 588 read(is, mAtr); 589 skip(is, skipLen); 590 break; 591 } // Fall through if TEST == false 592 default: 593 Log.e(TAG, "Received unknown parameter ID: " + paramId + " length: " + 594 paramLength + " skipping this parameter."); 595 skip(is, paramLength + skipLen); 596 } 597 } 598 return success; 599 } 600 601 /** 602 * Writes a single value parameter of 1 or 2 bytes in length. 603 * @param os The BufferedOutputStream to write to. 604 * @param id The Parameter ID 605 * @param value The parameter value 606 * @param length The length of the parameter value 607 * @throws IOException if the write to os fails 608 */ 609 private static void writeParameter(OutputStream os, int id, int value, int length) 610 throws IOException { 611 612 /* Parameter Header*/ 613 os.write(id); 614 os.write(0); 615 os.write(0); 616 os.write(length); 617 618 switch(length) { 619 case 1: 620 os.write(value & 0xff); 621 os.write(0); // Padding 622 os.write(0); // Padding 623 os.write(0); // padding 624 break; 625 case 2: 626 os.write((value >> 8) & 0xff); 627 os.write(value & 0xff); 628 os.write(0); // Padding 629 os.write(0); // padding 630 break; 631 default: 632 throw new IOException("Unable to write value of length: " + length); 633 } 634 } 635 636 /** 637 * Writes a byte[] parameter of any length. 638 * @param os The BufferedOutputStream to write to. 639 * @param id The Parameter ID 640 * @param value The byte array to write, the length will be extracted from the array. 641 * @throws IOException if the write to os fails 642 */ 643 private static void writeParameter(OutputStream os, int id, byte[] value) throws IOException { 644 645 /* Parameter Header*/ 646 os.write(id); 647 os.write(0); // reserved 648 os.write((value.length >> 8) & 0xff); 649 os.write(value.length & 0xff); 650 651 /* Payload */ 652 os.write(value); 653 if (value.length % 4 != 0) { 654 for (int i = 0; i < (4 - (value.length % 4)); ++i) { 655 os.write(0); // Padding 656 } 657 } 658 } 659 660 public void write(OutputStream os) throws IOException { 661 /* Write the header */ 662 os.write(mMsgType); 663 os.write(getParamCount()); 664 os.write(0); // padding 665 os.write(0); // padding 666 667 /* write the parameters */ 668 if(mConnectionStatus != INVALID_VALUE) { 669 writeParameter(os,PARAM_CONNECTION_STATUS_ID, mConnectionStatus, 670 PARAM_CONNECTION_STATUS_LENGTH); 671 } 672 if(mMaxMsgSize != INVALID_VALUE) { 673 writeParameter(os, PARAM_MAX_MSG_SIZE_ID, mMaxMsgSize, 674 PARAM_MAX_MSG_SIZE_LENGTH); 675 } 676 if(mResultCode != INVALID_VALUE) { 677 writeParameter(os, PARAM_RESULT_CODE_ID, mResultCode, 678 PARAM_RESULT_CODE_LENGTH); 679 } 680 if(mDisconnectionType != INVALID_VALUE && TEST) { 681 writeParameter(os, PARAM_DISCONNECT_TYPE_ID, mDisconnectionType, 682 PARAM_DISCONNECT_TYPE_LENGTH); 683 } 684 if(mCardReaderStatus != INVALID_VALUE) { 685 writeParameter(os, PARAM_CARD_READER_STATUS_ID, mCardReaderStatus, 686 PARAM_CARD_READER_STATUS_LENGTH); 687 } 688 if(mStatusChange != INVALID_VALUE) { 689 writeParameter(os, PARAM_STATUS_CHANGE_ID, mStatusChange, 690 PARAM_STATUS_CHANGE_LENGTH); 691 } 692 if(mTransportProtocol != INVALID_VALUE && TEST) { 693 writeParameter(os, PARAM_TRANSPORT_PROTOCOL_ID, mTransportProtocol, 694 PARAM_TRANSPORT_PROTOCOL_LENGTH); 695 } 696 if(mApdu != null && TEST) { 697 writeParameter(os, PARAM_COMMAND_APDU_ID, mApdu); 698 } 699 if(mApdu7816 != null && TEST) { 700 writeParameter(os, PARAM_COMMAND_APDU7816_ID, mApdu7816); 701 } 702 if(mApduResp != null) { 703 writeParameter(os, PARAM_RESPONSE_APDU_ID, mApduResp); 704 } 705 if(mAtr != null) { 706 writeParameter(os, PARAM_ATR_ID, mAtr); 707 } 708 } 709 710 /*************************************************************************** 711 * RILD Interface message conversion functions. 712 ***************************************************************************/ 713 714 /** 715 * We use this function to 716 * @param length 717 * @param rawOut 718 * @throws IOException 719 */ 720 private void writeLength(int length, CodedOutputStreamMicro out) throws IOException { 721 byte[] dataLength = new byte[4]; 722 dataLength[0] = dataLength[1] = 0; 723 dataLength[2] = (byte)((length >> 8) & 0xff); 724 dataLength[3] = (byte)((length) & 0xff); 725 out.writeRawBytes(dataLength); 726 } 727 /** 728 * Write this SAP message as a rild compatible protobuf message. 729 * Solicited Requests are formed as follows: 730 * int type - the rild-bt type 731 * int serial - an number incrementing for each message. 732 */ 733 public void writeReqToStream(CodedOutputStreamMicro out) throws IOException { 734 735 int rilSerial = sNextSerial.getAndIncrement(); 736 SapApi.MsgHeader msg = new MsgHeader(); 737 /* Common variables for all requests */ 738 msg.setToken(rilSerial); 739 msg.setType(SapApi.REQUEST); 740 msg.setError(SapApi.RIL_E_UNUSED); 741 742 switch(mMsgType) { 743 case ID_CONNECT_REQ: 744 { 745 SapApi.RIL_SIM_SAP_CONNECT_REQ reqMsg = new RIL_SIM_SAP_CONNECT_REQ(); 746 reqMsg.setMaxMessageSize(mMaxMsgSize); 747 msg.setId(SapApi.RIL_SIM_SAP_CONNECT); 748 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 749 writeLength(msg.getSerializedSize(), out); 750 msg.writeTo(out); 751 break; 752 } 753 case ID_DISCONNECT_REQ: 754 { 755 SapApi.RIL_SIM_SAP_DISCONNECT_REQ reqMsg = new RIL_SIM_SAP_DISCONNECT_REQ(); 756 msg.setId(SapApi.RIL_SIM_SAP_DISCONNECT); 757 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 758 writeLength(msg.getSerializedSize(), out); 759 msg.writeTo(out); 760 break; 761 } 762 case ID_TRANSFER_APDU_REQ: 763 { 764 SapApi.RIL_SIM_SAP_APDU_REQ reqMsg = new RIL_SIM_SAP_APDU_REQ(); 765 msg.setId(SapApi.RIL_SIM_SAP_APDU); 766 if(mApdu != null) { 767 reqMsg.setType(SapApi.RIL_SIM_SAP_APDU_REQ.RIL_TYPE_APDU); 768 reqMsg.setCommand(ByteStringMicro.copyFrom(mApdu)); 769 } else if (mApdu7816 != null) { 770 reqMsg.setType(SapApi.RIL_SIM_SAP_APDU_REQ.RIL_TYPE_APDU7816); 771 reqMsg.setCommand(ByteStringMicro.copyFrom(mApdu7816)); 772 } else { 773 Log.e(TAG, "Missing Apdu parameter in TRANSFER_APDU_REQ"); 774 throw new IllegalArgumentException(); 775 } 776 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 777 writeLength(msg.getSerializedSize(), out); 778 msg.writeTo(out); 779 break; 780 } 781 case ID_SET_TRANSPORT_PROTOCOL_REQ: 782 { 783 SapApi.RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ reqMsg = 784 new RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ(); 785 msg.setId(SapApi.RIL_SIM_SAP_SET_TRANSFER_PROTOCOL); 786 787 if(mTransportProtocol == TRANS_PROTO_T0) { 788 reqMsg.setProtocol(SapApi.RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ.t0); 789 } else if(mTransportProtocol == TRANS_PROTO_T1) { 790 reqMsg.setProtocol(SapApi.RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ.t1); 791 } else { 792 Log.e(TAG, "Missing or invalid TransportProtocol parameter in"+ 793 " SET_TRANSPORT_PROTOCOL_REQ: "+ mTransportProtocol ); 794 throw new IllegalArgumentException(); 795 } 796 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 797 writeLength(msg.getSerializedSize(), out); 798 msg.writeTo(out); 799 break; 800 } 801 case ID_TRANSFER_ATR_REQ: 802 { 803 SapApi.RIL_SIM_SAP_TRANSFER_ATR_REQ reqMsg = new RIL_SIM_SAP_TRANSFER_ATR_REQ(); 804 msg.setId(SapApi.RIL_SIM_SAP_TRANSFER_ATR); 805 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 806 writeLength(msg.getSerializedSize(), out); 807 msg.writeTo(out); 808 break; 809 } 810 case ID_POWER_SIM_OFF_REQ: 811 { 812 SapApi.RIL_SIM_SAP_POWER_REQ reqMsg = new RIL_SIM_SAP_POWER_REQ(); 813 msg.setId(SapApi.RIL_SIM_SAP_POWER); 814 reqMsg.setState(false); 815 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 816 writeLength(msg.getSerializedSize(), out); 817 msg.writeTo(out); 818 break; 819 } 820 case ID_POWER_SIM_ON_REQ: 821 { 822 SapApi.RIL_SIM_SAP_POWER_REQ reqMsg = new RIL_SIM_SAP_POWER_REQ(); 823 msg.setId(SapApi.RIL_SIM_SAP_POWER); 824 reqMsg.setState(true); 825 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 826 writeLength(msg.getSerializedSize(), out); 827 msg.writeTo(out); 828 break; 829 } 830 case ID_RESET_SIM_REQ: 831 { 832 SapApi.RIL_SIM_SAP_RESET_SIM_REQ reqMsg = new RIL_SIM_SAP_RESET_SIM_REQ(); 833 msg.setId(SapApi.RIL_SIM_SAP_RESET_SIM); 834 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 835 writeLength(msg.getSerializedSize(), out); 836 msg.writeTo(out); 837 break; 838 } 839 case ID_TRANSFER_CARD_READER_STATUS_REQ: 840 { 841 SapApi.RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ reqMsg = 842 new RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ(); 843 msg.setId(SapApi.RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS); 844 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 845 writeLength(msg.getSerializedSize(), out); 846 msg.writeTo(out); 847 break; 848 } 849 default: 850 if(TEST == false) { 851 Log.e(TAG, "Unknown request type"); 852 throw new IllegalArgumentException(); 853 } 854 } 855 /* Update the ongoing requests queue */ 856 if(mClearRilQueue == true) { 857 resetPendingRilMessages(); 858 } 859 // No need to synchronize this, as the HashList is already doing this. 860 sOngoingRequests.put(rilSerial, mMsgType); 861 out.flush(); 862 } 863 864 public static SapMessage newInstance(MsgHeader msg) throws IOException { 865 return new SapMessage(msg); 866 } 867 868 private SapMessage(MsgHeader msg) throws IOException { 869 // All header members are "required" hence the hasXxxx() is not needed for those 870 try{ 871 switch(msg.getType()){ 872 case SapApi.UNSOL_RESPONSE: 873 createUnsolicited(msg); 874 break; 875 case SapApi.RESPONSE: 876 createSolicited(msg); 877 break; 878 default: 879 throw new IOException("Wrong msg header received: Type: " + msg.getType()); 880 } 881 } catch (InvalidProtocolBufferMicroException e) { 882 Log.w(TAG, "Error occured parsing a RIL message", e); 883 throw new IOException("Error occured parsing a RIL message"); 884 } 885 } 886 887 private void createUnsolicited(MsgHeader msg) 888 throws IOException, InvalidProtocolBufferMicroException { 889 switch(msg.getId()) { 890// TODO: 891// Not sure when we use these? case RIL_UNSOL_RIL_CONNECTED: 892// if(VERBOSE) Log.i(TAG, "RIL_UNSOL_RIL_CONNECTED received, ignoring"); 893// msgType = ID_RIL_UNSOL_CONNECTED; 894// break; 895 case SapApi.RIL_SIM_SAP_STATUS: 896 { 897 if(VERBOSE) Log.i(TAG, "RIL_SIM_SAP_STATUS_IND received"); 898 RIL_SIM_SAP_STATUS_IND indMsg = 899 RIL_SIM_SAP_STATUS_IND.parseFrom(msg.getPayload().toByteArray()); 900 mMsgType = ID_STATUS_IND; 901 if(indMsg.hasStatusChange()) { 902 setStatusChange(indMsg.getStatusChange()); 903 if(VERBOSE) Log.i(TAG, "RIL_UNSOL_SIM_SAP_STATUS_IND received value = " 904 + mStatusChange); 905 } else { 906 if(VERBOSE) Log.i(TAG, "Wrong number of parameters in SAP_STATUS_IND, ignoring..."); 907 mMsgType = ID_RIL_UNKNOWN; 908 } 909 break; 910 } 911 case SapApi.RIL_SIM_SAP_DISCONNECT: 912 { 913 if(VERBOSE) Log.i(TAG, "RIL_SIM_SAP_DISCONNECT_IND received"); 914 915 RIL_SIM_SAP_DISCONNECT_IND indMsg = 916 RIL_SIM_SAP_DISCONNECT_IND.parseFrom(msg.getPayload().toByteArray()); 917 mMsgType = ID_RIL_UNSOL_DISCONNECT_IND; // don't use ID_DISCONNECT_IND; 918 if(indMsg.hasDisconnectType()) { 919 setDisconnectionType(indMsg.getDisconnectType()); 920 if(VERBOSE) Log.i(TAG, "RIL_UNSOL_SIM_SAP_STATUS_IND received value = " 921 + mDisconnectionType); 922 } else { 923 if(VERBOSE) Log.i(TAG, "Wrong number of parameters in SAP_STATUS_IND, ignoring..."); 924 mMsgType = ID_RIL_UNKNOWN; 925 } 926 break; 927 } 928 default: 929 if(VERBOSE) Log.i(TAG, "Unused unsolicited message received, ignoring: " + msg.getId()); 930 mMsgType = ID_RIL_UNKNOWN; 931 } 932 } 933 934 private void createSolicited(MsgHeader msg) throws IOException, 935 InvalidProtocolBufferMicroException{ 936 /* re-evaluate if we should just ignore these - we could simply catch the exception? */ 937 if(msg.hasToken() == false) throw new IOException("Token is missing"); 938 if(msg.hasError() == false) throw new IOException("Error code is missing"); 939 int serial = msg.getToken(); 940 int error = msg.getError(); 941 Integer reqType = null; 942 reqType = sOngoingRequests.remove(serial); 943 if(VERBOSE) Log.i(TAG, "RIL SOLICITED serial: " + serial + ", error: " + error 944 + " SapReqType: " + ((reqType== null)?"null":getMsgTypeName(reqType))); 945 946 if(reqType == null) { 947 /* This can happen if we get a resp. for a canceled request caused by a power off, 948 * reset or disconnect 949 */ 950 Log.w(TAG, "Solicited response received on a command not initiated - ignoring."); 951 return; 952 } 953 mResultCode = mapRilErrorCode(error); 954 955 switch(reqType) { 956 case ID_CONNECT_REQ: 957 { 958 RIL_SIM_SAP_CONNECT_RSP resMsg = 959 RIL_SIM_SAP_CONNECT_RSP.parseFrom(msg.getPayload().toByteArray()); 960 mMsgType = ID_CONNECT_RESP; 961 if(resMsg.hasMaxMessageSize()) { 962 mMaxMsgSize = resMsg.getMaxMessageSize(); 963 964 } 965 switch(resMsg.getResponse()) { 966 case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SUCCESS: 967 mConnectionStatus = CON_STATUS_OK; 968 break; 969 case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SAP_CONNECT_OK_CALL_ONGOING: 970 mConnectionStatus = CON_STATUS_OK_ONGOING_CALL; 971 break; 972 case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SAP_CONNECT_FAILURE: 973 mConnectionStatus = CON_STATUS_ERROR_CONNECTION; 974 break; 975 case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SAP_MSG_SIZE_TOO_LARGE: 976 mConnectionStatus = CON_STATUS_ERROR_MAX_MSG_SIZE_UNSUPPORTED; 977 break; 978 case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SAP_MSG_SIZE_TOO_SMALL: 979 mConnectionStatus = CON_STATUS_ERROR_MAX_MSG_SIZE_TOO_SMALL; 980 break; 981 default: 982 mConnectionStatus = CON_STATUS_ERROR_CONNECTION; // Cannot happen! 983 break; 984 } 985 mResultCode = INVALID_VALUE; 986 if(VERBOSE) Log.v(TAG, " ID_CONNECT_REQ: mMaxMsgSize: " + mMaxMsgSize 987 + " mConnectionStatus: " + mConnectionStatus); 988 break; 989 } 990 case ID_DISCONNECT_REQ: 991 mMsgType = ID_DISCONNECT_RESP; 992 mResultCode = INVALID_VALUE; 993 break; 994 case ID_TRANSFER_APDU_REQ: 995 { 996 RIL_SIM_SAP_APDU_RSP resMsg = 997 RIL_SIM_SAP_APDU_RSP.parseFrom(msg.getPayload().toByteArray()); 998 mMsgType = ID_TRANSFER_APDU_RESP; 999 switch(resMsg.getResponse()) { 1000 case RIL_SIM_SAP_APDU_RSP.RIL_E_SUCCESS: 1001 mResultCode = RESULT_OK; 1002 /* resMsg.getType is unused as the client knows the type of request used. */ 1003 if(resMsg.hasApduResponse()){ 1004 mApduResp = resMsg.getApduResponse().toByteArray(); 1005 } 1006 break; 1007 case RIL_SIM_SAP_APDU_RSP.RIL_E_GENERIC_FAILURE: 1008 mResultCode = RESULT_ERROR_NO_REASON; 1009 break; 1010 case RIL_SIM_SAP_APDU_RSP.RIL_E_SIM_ABSENT: 1011 mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; 1012 break; 1013 case RIL_SIM_SAP_APDU_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: 1014 mResultCode = RESULT_ERROR_CARD_POWERED_OFF; 1015 break; 1016 case RIL_SIM_SAP_APDU_RSP.RIL_E_SIM_NOT_READY: 1017 mResultCode = RESULT_ERROR_CARD_REMOVED; 1018 break; 1019 default: 1020 mResultCode = RESULT_ERROR_NO_REASON; 1021 break; 1022 } 1023 break; 1024 } 1025 case ID_SET_TRANSPORT_PROTOCOL_REQ: 1026 { 1027 RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP resMsg = 1028 RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.parseFrom( 1029 msg.getPayload().toByteArray()); 1030 mMsgType = ID_SET_TRANSPORT_PROTOCOL_RESP; 1031 switch(resMsg.getResponse()) { 1032 case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_SUCCESS: 1033 mResultCode = RESULT_OK; 1034 break; 1035 case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_GENERIC_FAILURE: 1036 mResultCode = RESULT_ERROR_NOT_SUPPORTED; 1037 break; 1038 case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_SIM_ABSENT: 1039 mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; 1040 break; 1041 case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: 1042 mResultCode = RESULT_ERROR_CARD_POWERED_OFF; 1043 break; 1044 case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_SIM_NOT_READY: 1045 mResultCode = RESULT_ERROR_CARD_REMOVED; 1046 break; 1047 default: 1048 mResultCode = RESULT_ERROR_NOT_SUPPORTED; 1049 break; 1050 } 1051 break; 1052 } 1053 case ID_TRANSFER_ATR_REQ: 1054 { 1055 RIL_SIM_SAP_TRANSFER_ATR_RSP resMsg = 1056 RIL_SIM_SAP_TRANSFER_ATR_RSP.parseFrom(msg.getPayload().toByteArray()); 1057 mMsgType =ID_TRANSFER_ATR_RESP; 1058 if(resMsg.hasAtr()) { 1059 mAtr = resMsg.getAtr().toByteArray(); 1060 } 1061 switch(resMsg.getResponse()) { 1062 case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SUCCESS: 1063 mResultCode = RESULT_OK; 1064 break; 1065 case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_GENERIC_FAILURE: 1066 mResultCode = RESULT_ERROR_NO_REASON; 1067 break; 1068 case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SIM_ABSENT: 1069 mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; 1070 break; 1071 case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: 1072 mResultCode = RESULT_ERROR_CARD_POWERED_OFF; 1073 break; 1074 case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SIM_ALREADY_POWERED_ON: 1075 mResultCode = RESULT_ERROR_CARD_POWERED_ON; 1076 break; 1077 case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SIM_DATA_NOT_AVAILABLE: 1078 mResultCode = RESULT_ERROR_DATA_NOT_AVAILABLE; 1079 break; 1080 default: 1081 mResultCode = RESULT_ERROR_NO_REASON; 1082 break; 1083 } 1084 break; 1085 } 1086 case ID_POWER_SIM_OFF_REQ: 1087 { 1088 RIL_SIM_SAP_POWER_RSP resMsg = 1089 RIL_SIM_SAP_POWER_RSP.parseFrom(msg.getPayload().toByteArray()); 1090 mMsgType = ID_POWER_SIM_OFF_RESP; 1091 switch(resMsg.getResponse()) { 1092 case RIL_SIM_SAP_POWER_RSP.RIL_E_SUCCESS: 1093 mResultCode = RESULT_OK; 1094 break; 1095 case RIL_SIM_SAP_POWER_RSP.RIL_E_GENERIC_FAILURE: 1096 mResultCode = RESULT_ERROR_NO_REASON; 1097 break; 1098 case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ABSENT: 1099 mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; 1100 break; 1101 case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: 1102 mResultCode = RESULT_ERROR_CARD_POWERED_OFF; 1103 break; 1104 case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ALREADY_POWERED_ON: 1105 mResultCode = RESULT_ERROR_CARD_POWERED_ON; 1106 break; 1107 default: 1108 mResultCode = RESULT_ERROR_NO_REASON; 1109 break; 1110 } 1111 break; 1112 } 1113 case ID_POWER_SIM_ON_REQ: 1114 { 1115 RIL_SIM_SAP_POWER_RSP resMsg = 1116 RIL_SIM_SAP_POWER_RSP.parseFrom(msg.getPayload().toByteArray()); 1117 mMsgType = ID_POWER_SIM_ON_RESP; 1118 switch(resMsg.getResponse()) { 1119 case RIL_SIM_SAP_POWER_RSP.RIL_E_SUCCESS: 1120 mResultCode = RESULT_OK; 1121 break; 1122 case RIL_SIM_SAP_POWER_RSP.RIL_E_GENERIC_FAILURE: 1123 mResultCode = RESULT_ERROR_NO_REASON; 1124 break; 1125 case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ABSENT: 1126 mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; 1127 break; 1128 case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: 1129 mResultCode = RESULT_ERROR_CARD_POWERED_OFF; 1130 break; 1131 case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ALREADY_POWERED_ON: 1132 mResultCode = RESULT_ERROR_CARD_POWERED_ON; 1133 break; 1134 default: 1135 mResultCode = RESULT_ERROR_NO_REASON; 1136 break; 1137 } 1138 break; 1139 } 1140 case ID_RESET_SIM_REQ: 1141 { 1142 RIL_SIM_SAP_RESET_SIM_RSP resMsg = 1143 RIL_SIM_SAP_RESET_SIM_RSP.parseFrom(msg.getPayload().toByteArray()); 1144 mMsgType = ID_RESET_SIM_RESP; 1145 switch(resMsg.getResponse()) { 1146 case RIL_SIM_SAP_RESET_SIM_RSP.RIL_E_SUCCESS: 1147 mResultCode = RESULT_OK; 1148 break; 1149 case RIL_SIM_SAP_RESET_SIM_RSP.RIL_E_GENERIC_FAILURE: 1150 mResultCode = RESULT_ERROR_NO_REASON; 1151 break; 1152 case RIL_SIM_SAP_RESET_SIM_RSP.RIL_E_SIM_ABSENT: 1153 mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; 1154 break; 1155 case RIL_SIM_SAP_RESET_SIM_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: 1156 mResultCode = RESULT_ERROR_CARD_POWERED_OFF; 1157 break; 1158 default: 1159 mResultCode = RESULT_ERROR_NO_REASON; 1160 break; 1161 } 1162 break; 1163 } 1164 case ID_TRANSFER_CARD_READER_STATUS_REQ: 1165 { 1166 RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP resMsg = 1167 RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP.parseFrom( 1168 msg.getPayload().toByteArray()); 1169 mMsgType = ID_TRANSFER_CARD_READER_STATUS_RESP; 1170 switch(resMsg.getResponse()) { 1171 case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP.RIL_E_SUCCESS: 1172 mResultCode = RESULT_OK; 1173 if(resMsg.hasCardReaderStatus()) { 1174 mCardReaderStatus = resMsg.getCardReaderStatus(); 1175 } else { 1176 mResultCode = RESULT_ERROR_DATA_NOT_AVAILABLE; 1177 } 1178 break; 1179 case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP.RIL_E_GENERIC_FAILURE: 1180 mResultCode = RESULT_ERROR_NO_REASON; 1181 break; 1182 case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP.RIL_E_SIM_DATA_NOT_AVAILABLE: 1183 mResultCode = RESULT_ERROR_DATA_NOT_AVAILABLE; 1184 break; 1185 default: 1186 mResultCode = RESULT_ERROR_NO_REASON; 1187 break; 1188 } 1189 break; 1190 } 1191 1192 case ID_RIL_SIM_ACCESS_TEST_REQ: // TODO: implement in RILD 1193 mMsgType = ID_RIL_SIM_ACCESS_TEST_RESP; 1194 break; 1195 default: 1196 Log.e(TAG, "Unknown request type: " + reqType); 1197 1198 } 1199 } 1200 1201 1202 1203 /* Map from RIL header error codes to SAP error codes */ 1204 private static int mapRilErrorCode(int rilErrorCode) { 1205 switch(rilErrorCode) { 1206 case SapApi.RIL_E_SUCCESS: 1207 return RESULT_OK; 1208 case SapApi.RIL_E_CANCELLED: 1209 return RESULT_ERROR_NO_REASON; 1210 case SapApi.RIL_E_GENERIC_FAILURE: 1211 return RESULT_ERROR_NO_REASON; 1212 case SapApi.RIL_E_RADIO_NOT_AVAILABLE: 1213 return RESULT_ERROR_CARD_NOT_ACCESSIBLE; 1214 case SapApi.RIL_E_INVALID_PARAMETER: 1215 return RESULT_ERROR_NO_REASON; 1216 case SapApi.RIL_E_REQUEST_NOT_SUPPORTED: 1217 return RESULT_ERROR_NOT_SUPPORTED; 1218 default: 1219 return RESULT_ERROR_NO_REASON; 1220 } 1221 } 1222 1223 1224 1225 public static String getMsgTypeName(int msgType) { 1226 if(TEST || VERBOSE) { 1227 switch (msgType) 1228 { 1229 case ID_CONNECT_REQ: return "ID_CONNECT_REQ"; 1230 case ID_CONNECT_RESP: return "ID_CONNECT_RESP"; 1231 case ID_DISCONNECT_REQ: return "ID_DISCONNECT_REQ"; 1232 case ID_DISCONNECT_RESP: return "ID_DISCONNECT_RESP"; 1233 case ID_DISCONNECT_IND: return "ID_DISCONNECT_IND"; 1234 case ID_TRANSFER_APDU_REQ: return "ID_TRANSFER_APDU_REQ"; 1235 case ID_TRANSFER_APDU_RESP: return "ID_TRANSFER_APDU_RESP"; 1236 case ID_TRANSFER_ATR_REQ: return "ID_TRANSFER_ATR_REQ"; 1237 case ID_TRANSFER_ATR_RESP: return "ID_TRANSFER_ATR_RESP"; 1238 case ID_POWER_SIM_OFF_REQ: return "ID_POWER_SIM_OFF_REQ"; 1239 case ID_POWER_SIM_OFF_RESP: return "ID_POWER_SIM_OFF_RESP"; 1240 case ID_POWER_SIM_ON_REQ: return "ID_POWER_SIM_ON_REQ"; 1241 case ID_POWER_SIM_ON_RESP: return "ID_POWER_SIM_ON_RESP"; 1242 case ID_RESET_SIM_REQ: return "ID_RESET_SIM_REQ"; 1243 case ID_RESET_SIM_RESP: return "ID_RESET_SIM_RESP"; 1244 case ID_TRANSFER_CARD_READER_STATUS_REQ: 1245 return "ID_TRANSFER_CARD_READER_STATUS_REQ"; 1246 case ID_TRANSFER_CARD_READER_STATUS_RESP: 1247 return "ID_TRANSFER_CARD_READER_STATUS_RESP"; 1248 case ID_STATUS_IND: return "ID_STATUS_IND"; 1249 case ID_ERROR_RESP: return "ID_ERROR_RESP"; 1250 case ID_SET_TRANSPORT_PROTOCOL_REQ: return "ID_SET_TRANSPORT_PROTOCOL_REQ"; 1251 case ID_SET_TRANSPORT_PROTOCOL_RESP: return "ID_SET_TRANSPORT_PROTOCOL_RESP"; 1252 case ID_RIL_UNSOL_CONNECTED: return "ID_RIL_UNSOL_CONNECTED"; 1253 case ID_RIL_UNKNOWN: return "ID_RIL_UNKNOWN"; 1254 case ID_RIL_GET_SIM_STATUS_REQ: return "ID_RIL_GET_SIM_STATUS_REQ"; 1255 case ID_RIL_SIM_ACCESS_TEST_REQ: return "ID_RIL_SIM_ACCESS_TEST_REQ"; 1256 case ID_RIL_SIM_ACCESS_TEST_RESP: return "ID_RIL_SIM_ACCESS_TEST_RESP"; 1257 default: return "Unknown Message Type (" + msgType + ")"; 1258 } 1259 } else { 1260 return null; 1261 } 1262 } 1263} 1264