1 package com.android.bluetooth.sap; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.io.OutputStream; 6 import java.security.InvalidParameterException; 7 import java.util.Arrays; 8 import java.util.Hashtable; 9 import java.util.Map; 10 import java.util.concurrent.atomic.AtomicInteger; 11 12 import org.android.btsap.SapApi; 13 import org.android.btsap.SapApi.*; 14 import com.google.protobuf.micro.*; 15 16 import android.os.Parcel; 17 import android.os.Parcelable; 18 import android.util.Log; 19 20 /** 21 * SapMessage is used for incoming and outgoing messages. 22 * 23 * For incoming messages 24 * 25 */ 26 public 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 for(int i = 0; i < count; i++) { 460 paramId = is.read(); 461 is.read(); // Skip the reserved byte 462 paramLength = is.read(); 463 paramLength = paramLength << 8 | is.read(); 464 if(VERBOSE) Log.i(TAG, "parsing paramId: " + paramId + " with length: " + paramLength); 465 switch(paramId) { 466 case PARAM_MAX_MSG_SIZE_ID: 467 if(paramLength != PARAM_MAX_MSG_SIZE_LENGTH) { 468 Log.e(TAG, "Received PARAM_MAX_MSG_SIZE with wrong length: " + 469 paramLength + " skipping this parameter."); 470 skip(is, paramLength + (4 - (paramLength % 4))); 471 success = false; 472 } else { 473 mMaxMsgSize = is.read(); 474 mMaxMsgSize = mMaxMsgSize << 8 | is.read(); 475 skip(is, 4 - PARAM_MAX_MSG_SIZE_LENGTH); 476 } 477 break; 478 case PARAM_COMMAND_APDU_ID: 479 mApdu = new byte[paramLength]; 480 read(is, mApdu); 481 skip(is, 4 - (paramLength % 4)); 482 break; 483 case PARAM_COMMAND_APDU7816_ID: 484 mApdu7816 = new byte[paramLength]; 485 read(is, mApdu7816); 486 skip(is, 4 - (paramLength % 4)); 487 break; 488 case PARAM_TRANSPORT_PROTOCOL_ID: 489 if(paramLength != PARAM_TRANSPORT_PROTOCOL_LENGTH) { 490 Log.e(TAG, "Received PARAM_TRANSPORT_PROTOCOL with wrong length: " + 491 paramLength + " skipping this parameter."); 492 skip(is, paramLength + (4 - (paramLength % 4))); 493 success = false; 494 } else { 495 mTransportProtocol = is.read(); 496 skip(is, 4 - PARAM_TRANSPORT_PROTOCOL_LENGTH); 497 } 498 break; 499 case PARAM_CONNECTION_STATUS_ID: 500 // not needed - server -> client 501 if(TEST) { 502 if(paramLength != PARAM_CONNECTION_STATUS_LENGTH) { 503 Log.e(TAG, "Received PARAM_CONNECTION_STATUS with wrong length: " + 504 paramLength + " skipping this parameter."); 505 skip(is, paramLength + (4 - (paramLength % 4))); 506 success = false; 507 } else { 508 mConnectionStatus = is.read(); 509 skip(is, 4 - PARAM_CONNECTION_STATUS_LENGTH); 510 } 511 break; 512 } // Fall through if TEST == false 513 case PARAM_CARD_READER_STATUS_ID: 514 // not needed - server -> client 515 if(TEST) { 516 if(paramLength != PARAM_CARD_READER_STATUS_LENGTH) { 517 Log.e(TAG, "Received PARAM_CARD_READER_STATUS with wrong length: " + 518 paramLength + " skipping this parameter."); 519 skip(is, paramLength + (4 - (paramLength % 4))); 520 success = false; 521 } else { 522 mCardReaderStatus = is.read(); 523 skip(is, 4 - PARAM_CARD_READER_STATUS_LENGTH); 524 } 525 break; 526 } // Fall through if TEST == false 527 case PARAM_STATUS_CHANGE_ID: 528 // not needed - server -> client 529 if(TEST) { 530 if(paramLength != PARAM_STATUS_CHANGE_LENGTH) { 531 Log.e(TAG, "Received PARAM_STATUS_CHANGE with wrong length: " + 532 paramLength + " skipping this parameter."); 533 skip(is, paramLength + (4 - (paramLength % 4))); 534 success = false; 535 } else { 536 mStatusChange = is.read(); 537 skip(is, 4 - PARAM_STATUS_CHANGE_LENGTH); 538 } 539 break; 540 } // Fall through if TEST == false 541 case PARAM_RESULT_CODE_ID: 542 // not needed - server -> client 543 if(TEST) { 544 if(paramLength != PARAM_RESULT_CODE_LENGTH) { 545 Log.e(TAG, "Received PARAM_RESULT_CODE with wrong length: " + 546 paramLength + " skipping this parameter."); 547 skip(is, paramLength + (4 - (paramLength % 4))); 548 success = false; 549 } else { 550 mResultCode = is.read(); 551 skip(is, 4 - PARAM_RESULT_CODE_LENGTH); 552 } 553 break; 554 } // Fall through if TEST == false 555 case PARAM_DISCONNECT_TYPE_ID: 556 // not needed - server -> client 557 if(TEST) { 558 if(paramLength != PARAM_DISCONNECT_TYPE_LENGTH) { 559 Log.e(TAG, "Received PARAM_DISCONNECT_TYPE_ID with wrong length: " + 560 paramLength + " skipping this parameter."); 561 skip(is, paramLength + (4 - (paramLength % 4))); 562 success = false; 563 } else { 564 mDisconnectionType = is.read(); 565 skip(is, 4 - PARAM_DISCONNECT_TYPE_LENGTH); 566 } 567 break; 568 } // Fall through if TEST == false 569 case PARAM_RESPONSE_APDU_ID: 570 // not needed - server -> client 571 if(TEST) { 572 mApduResp = new byte[paramLength]; 573 read(is, mApduResp); 574 skip(is, 4 - (paramLength % 4)); 575 break; 576 } // Fall through if TEST == false 577 case PARAM_ATR_ID: 578 // not needed - server -> client 579 if(TEST) { 580 mAtr = new byte[paramLength]; 581 read(is, mAtr); 582 skip(is, 4 - (paramLength % 4)); 583 break; 584 } // Fall through if TEST == false 585 default: 586 Log.e(TAG, "Received unknown parameter ID: " + paramId + " length: " + 587 paramLength + " skipping this parameter."); 588 skip(is, paramLength + (4 - (paramLength % 4))); 589 } 590 } 591 return success; 592 } 593 594 /** 595 * Writes a single value parameter of 1 or 2 bytes in length. 596 * @param os The BufferedOutputStream to write to. 597 * @param id The Parameter ID 598 * @param value The parameter value 599 * @param length The length of the parameter value 600 * @throws IOException if the write to os fails 601 */ 602 private static void writeParameter(OutputStream os, int id, int value, int length) 603 throws IOException { 604 605 /* Parameter Header*/ 606 os.write(id); 607 os.write(0); 608 os.write(0); 609 os.write(length); 610 611 switch(length) { 612 case 1: 613 os.write(value & 0xff); 614 os.write(0); // Padding 615 os.write(0); // Padding 616 os.write(0); // padding 617 break; 618 case 2: 619 os.write((value >> 8) & 0xff); 620 os.write(value & 0xff); 621 os.write(0); // Padding 622 os.write(0); // padding 623 break; 624 default: 625 throw new IOException("Unable to write value of length: " + length); 626 } 627 } 628 629 /** 630 * Writes a byte[] parameter of any length. 631 * @param os The BufferedOutputStream to write to. 632 * @param id The Parameter ID 633 * @param value The byte array to write, the length will be extracted from the array. 634 * @throws IOException if the write to os fails 635 */ 636 private static void writeParameter(OutputStream os, int id, byte[] value) throws IOException { 637 638 /* Parameter Header*/ 639 os.write(id); 640 os.write(0); // reserved 641 os.write((value.length >> 8) & 0xff); 642 os.write(value.length & 0xff); 643 644 /* Payload */ 645 os.write(value); 646 for(int i = 0, n = 4 - (value.length % 4) ; i < n; i++) { 647 os.write(0); // Padding 648 } 649 } 650 651 public void write(OutputStream os) throws IOException { 652 /* Write the header */ 653 os.write(mMsgType); 654 os.write(getParamCount()); 655 os.write(0); // padding 656 os.write(0); // padding 657 658 /* write the parameters */ 659 if(mConnectionStatus != INVALID_VALUE) { 660 writeParameter(os,PARAM_CONNECTION_STATUS_ID, mConnectionStatus, 661 PARAM_CONNECTION_STATUS_LENGTH); 662 } 663 if(mMaxMsgSize != INVALID_VALUE) { 664 writeParameter(os, PARAM_MAX_MSG_SIZE_ID, mMaxMsgSize, 665 PARAM_MAX_MSG_SIZE_LENGTH); 666 } 667 if(mResultCode != INVALID_VALUE) { 668 writeParameter(os, PARAM_RESULT_CODE_ID, mResultCode, 669 PARAM_RESULT_CODE_LENGTH); 670 } 671 if(mDisconnectionType != INVALID_VALUE && TEST) { 672 writeParameter(os, PARAM_DISCONNECT_TYPE_ID, mDisconnectionType, 673 PARAM_DISCONNECT_TYPE_LENGTH); 674 } 675 if(mCardReaderStatus != INVALID_VALUE) { 676 writeParameter(os, PARAM_CARD_READER_STATUS_ID, mCardReaderStatus, 677 PARAM_CARD_READER_STATUS_LENGTH); 678 } 679 if(mStatusChange != INVALID_VALUE) { 680 writeParameter(os, PARAM_STATUS_CHANGE_ID, mStatusChange, 681 PARAM_STATUS_CHANGE_LENGTH); 682 } 683 if(mTransportProtocol != INVALID_VALUE && TEST) { 684 writeParameter(os, PARAM_TRANSPORT_PROTOCOL_ID, mTransportProtocol, 685 PARAM_TRANSPORT_PROTOCOL_LENGTH); 686 } 687 if(mApdu != null && TEST) { 688 writeParameter(os, PARAM_COMMAND_APDU_ID, mApdu); 689 } 690 if(mApdu7816 != null && TEST) { 691 writeParameter(os, PARAM_COMMAND_APDU7816_ID, mApdu7816); 692 } 693 if(mApduResp != null) { 694 writeParameter(os, PARAM_RESPONSE_APDU_ID, mApduResp); 695 } 696 if(mAtr != null) { 697 writeParameter(os, PARAM_ATR_ID, mAtr); 698 } 699 } 700 701 /*************************************************************************** 702 * RILD Interface message conversion functions. 703 ***************************************************************************/ 704 705 /** 706 * We use this function to 707 * @param length 708 * @param rawOut 709 * @throws IOException 710 */ 711 private void writeLength(int length, CodedOutputStreamMicro out) throws IOException { 712 byte[] dataLength = new byte[4]; 713 dataLength[0] = dataLength[1] = 0; 714 dataLength[2] = (byte)((length >> 8) & 0xff); 715 dataLength[3] = (byte)((length) & 0xff); 716 out.writeRawBytes(dataLength); 717 } 718 /** 719 * Write this SAP message as a rild compatible protobuf message. 720 * Solicited Requests are formed as follows: 721 * int type - the rild-bt type 722 * int serial - an number incrementing for each message. 723 */ 724 public void writeReqToStream(CodedOutputStreamMicro out) throws IOException { 725 726 int rilSerial = sNextSerial.getAndIncrement(); 727 SapApi.MsgHeader msg = new MsgHeader(); 728 /* Common variables for all requests */ 729 msg.setToken(rilSerial); 730 msg.setType(SapApi.REQUEST); 731 msg.setError(SapApi.RIL_E_UNUSED); 732 733 switch(mMsgType) { 734 case ID_CONNECT_REQ: 735 { 736 SapApi.RIL_SIM_SAP_CONNECT_REQ reqMsg = new RIL_SIM_SAP_CONNECT_REQ(); 737 reqMsg.setMaxMessageSize(mMaxMsgSize); 738 msg.setId(SapApi.RIL_SIM_SAP_CONNECT); 739 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 740 writeLength(msg.getSerializedSize(), out); 741 msg.writeTo(out); 742 break; 743 } 744 case ID_DISCONNECT_REQ: 745 { 746 SapApi.RIL_SIM_SAP_DISCONNECT_REQ reqMsg = new RIL_SIM_SAP_DISCONNECT_REQ(); 747 msg.setId(SapApi.RIL_SIM_SAP_DISCONNECT); 748 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 749 writeLength(msg.getSerializedSize(), out); 750 msg.writeTo(out); 751 break; 752 } 753 case ID_TRANSFER_APDU_REQ: 754 { 755 SapApi.RIL_SIM_SAP_APDU_REQ reqMsg = new RIL_SIM_SAP_APDU_REQ(); 756 msg.setId(SapApi.RIL_SIM_SAP_APDU); 757 if(mApdu != null) { 758 reqMsg.setType(SapApi.RIL_SIM_SAP_APDU_REQ.RIL_TYPE_APDU); 759 reqMsg.setCommand(ByteStringMicro.copyFrom(mApdu)); 760 } else if (mApdu7816 != null) { 761 reqMsg.setType(SapApi.RIL_SIM_SAP_APDU_REQ.RIL_TYPE_APDU7816); 762 reqMsg.setCommand(ByteStringMicro.copyFrom(mApdu7816)); 763 } else { 764 Log.e(TAG, "Missing Apdu parameter in TRANSFER_APDU_REQ"); 765 throw new IllegalArgumentException(); 766 } 767 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 768 writeLength(msg.getSerializedSize(), out); 769 msg.writeTo(out); 770 break; 771 } 772 case ID_SET_TRANSPORT_PROTOCOL_REQ: 773 { 774 SapApi.RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ reqMsg = 775 new RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ(); 776 msg.setId(SapApi.RIL_SIM_SAP_SET_TRANSFER_PROTOCOL); 777 778 if(mTransportProtocol == TRANS_PROTO_T0) { 779 reqMsg.setProtocol(SapApi.RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ.t0); 780 } else if(mTransportProtocol == TRANS_PROTO_T1) { 781 reqMsg.setProtocol(SapApi.RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ.t1); 782 } else { 783 Log.e(TAG, "Missing or invalid TransportProtocol parameter in"+ 784 " SET_TRANSPORT_PROTOCOL_REQ: "+ mTransportProtocol ); 785 throw new IllegalArgumentException(); 786 } 787 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 788 writeLength(msg.getSerializedSize(), out); 789 msg.writeTo(out); 790 break; 791 } 792 case ID_TRANSFER_ATR_REQ: 793 { 794 SapApi.RIL_SIM_SAP_TRANSFER_ATR_REQ reqMsg = new RIL_SIM_SAP_TRANSFER_ATR_REQ(); 795 msg.setId(SapApi.RIL_SIM_SAP_TRANSFER_ATR); 796 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 797 writeLength(msg.getSerializedSize(), out); 798 msg.writeTo(out); 799 break; 800 } 801 case ID_POWER_SIM_OFF_REQ: 802 { 803 SapApi.RIL_SIM_SAP_POWER_REQ reqMsg = new RIL_SIM_SAP_POWER_REQ(); 804 msg.setId(SapApi.RIL_SIM_SAP_POWER); 805 reqMsg.setState(false); 806 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 807 writeLength(msg.getSerializedSize(), out); 808 msg.writeTo(out); 809 break; 810 } 811 case ID_POWER_SIM_ON_REQ: 812 { 813 SapApi.RIL_SIM_SAP_POWER_REQ reqMsg = new RIL_SIM_SAP_POWER_REQ(); 814 msg.setId(SapApi.RIL_SIM_SAP_POWER); 815 reqMsg.setState(true); 816 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 817 writeLength(msg.getSerializedSize(), out); 818 msg.writeTo(out); 819 break; 820 } 821 case ID_RESET_SIM_REQ: 822 { 823 SapApi.RIL_SIM_SAP_RESET_SIM_REQ reqMsg = new RIL_SIM_SAP_RESET_SIM_REQ(); 824 msg.setId(SapApi.RIL_SIM_SAP_RESET_SIM); 825 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 826 writeLength(msg.getSerializedSize(), out); 827 msg.writeTo(out); 828 break; 829 } 830 case ID_TRANSFER_CARD_READER_STATUS_REQ: 831 { 832 SapApi.RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ reqMsg = 833 new RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ(); 834 msg.setId(SapApi.RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS); 835 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 836 writeLength(msg.getSerializedSize(), out); 837 msg.writeTo(out); 838 break; 839 } 840 default: 841 if(TEST == false) { 842 Log.e(TAG, "Unknown request type"); 843 throw new IllegalArgumentException(); 844 } 845 } 846 /* Update the ongoing requests queue */ 847 if(mClearRilQueue == true) { 848 resetPendingRilMessages(); 849 } 850 // No need to synchronize this, as the HashList is already doing this. 851 sOngoingRequests.put(rilSerial, mMsgType); 852 out.flush(); 853 } 854 855 public static SapMessage newInstance(MsgHeader msg) throws IOException { 856 return new SapMessage(msg); 857 } 858 859 private SapMessage(MsgHeader msg) throws IOException { 860 // All header members are "required" hence the hasXxxx() is not needed for those 861 try{ 862 switch(msg.getType()){ 863 case SapApi.UNSOL_RESPONSE: 864 createUnsolicited(msg); 865 break; 866 case SapApi.RESPONSE: 867 createSolicited(msg); 868 break; 869 default: 870 throw new IOException("Wrong msg header received: Type: " + msg.getType()); 871 } 872 } catch (InvalidProtocolBufferMicroException e) { 873 Log.w(TAG, "Error occured parsing a RIL message", e); 874 throw new IOException("Error occured parsing a RIL message"); 875 } 876 } 877 878 private void createUnsolicited(MsgHeader msg) 879 throws IOException, InvalidProtocolBufferMicroException { 880 switch(msg.getId()) { 881 // TODO: 882 // Not sure when we use these? case RIL_UNSOL_RIL_CONNECTED: 883 // if(VERBOSE) Log.i(TAG, "RIL_UNSOL_RIL_CONNECTED received, ignoring"); 884 // msgType = ID_RIL_UNSOL_CONNECTED; 885 // break; 886 case SapApi.RIL_SIM_SAP_STATUS: 887 { 888 if(VERBOSE) Log.i(TAG, "RIL_SIM_SAP_STATUS_IND received"); 889 RIL_SIM_SAP_STATUS_IND indMsg = 890 RIL_SIM_SAP_STATUS_IND.parseFrom(msg.getPayload().toByteArray()); 891 mMsgType = ID_STATUS_IND; 892 if(indMsg.hasStatusChange()) { 893 setStatusChange(indMsg.getStatusChange()); 894 if(VERBOSE) Log.i(TAG, "RIL_UNSOL_SIM_SAP_STATUS_IND received value = " 895 + mStatusChange); 896 } else { 897 if(VERBOSE) Log.i(TAG, "Wrong number of parameters in SAP_STATUS_IND, ignoring..."); 898 mMsgType = ID_RIL_UNKNOWN; 899 } 900 break; 901 } 902 case SapApi.RIL_SIM_SAP_DISCONNECT: 903 { 904 if(VERBOSE) Log.i(TAG, "RIL_SIM_SAP_DISCONNECT_IND received"); 905 906 RIL_SIM_SAP_DISCONNECT_IND indMsg = 907 RIL_SIM_SAP_DISCONNECT_IND.parseFrom(msg.getPayload().toByteArray()); 908 mMsgType = ID_RIL_UNSOL_DISCONNECT_IND; // don't use ID_DISCONNECT_IND; 909 if(indMsg.hasDisconnectType()) { 910 setDisconnectionType(indMsg.getDisconnectType()); 911 if(VERBOSE) Log.i(TAG, "RIL_UNSOL_SIM_SAP_STATUS_IND received value = " 912 + mDisconnectionType); 913 } else { 914 if(VERBOSE) Log.i(TAG, "Wrong number of parameters in SAP_STATUS_IND, ignoring..."); 915 mMsgType = ID_RIL_UNKNOWN; 916 } 917 break; 918 } 919 default: 920 if(VERBOSE) Log.i(TAG, "Unused unsolicited message received, ignoring: " + msg.getId()); 921 mMsgType = ID_RIL_UNKNOWN; 922 } 923 } 924 925 private void createSolicited(MsgHeader msg) throws IOException, 926 InvalidProtocolBufferMicroException{ 927 /* re-evaluate if we should just ignore these - we could simply catch the exception? */ 928 if(msg.hasToken() == false) throw new IOException("Token is missing"); 929 if(msg.hasError() == false) throw new IOException("Error code is missing"); 930 int serial = msg.getToken(); 931 int error = msg.getError(); 932 Integer reqType = null; 933 reqType = sOngoingRequests.remove(serial); 934 if(VERBOSE) Log.i(TAG, "RIL SOLICITED serial: " + serial + ", error: " + error 935 + " SapReqType: " + ((reqType== null)?"null":getMsgTypeName(reqType))); 936 937 if(reqType == null) { 938 /* This can happen if we get a resp. for a canceled request caused by a power off, 939 * reset or disconnect 940 */ 941 Log.w(TAG, "Solicited response received on a command not initiated - ignoring."); 942 return; 943 } 944 mResultCode = mapRilErrorCode(error); 945 946 switch(reqType) { 947 case ID_CONNECT_REQ: 948 { 949 RIL_SIM_SAP_CONNECT_RSP resMsg = 950 RIL_SIM_SAP_CONNECT_RSP.parseFrom(msg.getPayload().toByteArray()); 951 mMsgType = ID_CONNECT_RESP; 952 if(resMsg.hasMaxMessageSize()) { 953 mMaxMsgSize = resMsg.getMaxMessageSize(); 954 955 } 956 switch(resMsg.getResponse()) { 957 case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SUCCESS: 958 mConnectionStatus = CON_STATUS_OK; 959 break; 960 case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SAP_CONNECT_OK_CALL_ONGOING: 961 mConnectionStatus = CON_STATUS_OK_ONGOING_CALL; 962 break; 963 case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SAP_CONNECT_FAILURE: 964 mConnectionStatus = CON_STATUS_ERROR_CONNECTION; 965 break; 966 case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SAP_MSG_SIZE_TOO_LARGE: 967 mConnectionStatus = CON_STATUS_ERROR_MAX_MSG_SIZE_UNSUPPORTED; 968 break; 969 case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SAP_MSG_SIZE_TOO_SMALL: 970 mConnectionStatus = CON_STATUS_ERROR_MAX_MSG_SIZE_TOO_SMALL; 971 break; 972 default: 973 mConnectionStatus = CON_STATUS_ERROR_CONNECTION; // Cannot happen! 974 break; 975 } 976 mResultCode = INVALID_VALUE; 977 if(VERBOSE) Log.v(TAG, " ID_CONNECT_REQ: mMaxMsgSize: " + mMaxMsgSize 978 + " mConnectionStatus: " + mConnectionStatus); 979 break; 980 } 981 case ID_DISCONNECT_REQ: 982 mMsgType = ID_DISCONNECT_RESP; 983 mResultCode = INVALID_VALUE; 984 break; 985 case ID_TRANSFER_APDU_REQ: 986 { 987 RIL_SIM_SAP_APDU_RSP resMsg = 988 RIL_SIM_SAP_APDU_RSP.parseFrom(msg.getPayload().toByteArray()); 989 mMsgType = ID_TRANSFER_APDU_RESP; 990 switch(resMsg.getResponse()) { 991 case RIL_SIM_SAP_APDU_RSP.RIL_E_SUCCESS: 992 mResultCode = RESULT_OK; 993 /* resMsg.getType is unused as the client knows the type of request used. */ 994 if(resMsg.hasApduResponse()){ 995 mApduResp = resMsg.getApduResponse().toByteArray(); 996 } 997 break; 998 case RIL_SIM_SAP_APDU_RSP.RIL_E_GENERIC_FAILURE: 999 mResultCode = RESULT_ERROR_NO_REASON; 1000 break; 1001 case RIL_SIM_SAP_APDU_RSP.RIL_E_SIM_ABSENT: 1002 mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; 1003 break; 1004 case RIL_SIM_SAP_APDU_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: 1005 mResultCode = RESULT_ERROR_CARD_POWERED_OFF; 1006 break; 1007 case RIL_SIM_SAP_APDU_RSP.RIL_E_SIM_NOT_READY: 1008 mResultCode = RESULT_ERROR_CARD_REMOVED; 1009 break; 1010 default: 1011 mResultCode = RESULT_ERROR_NO_REASON; 1012 break; 1013 } 1014 break; 1015 } 1016 case ID_SET_TRANSPORT_PROTOCOL_REQ: 1017 { 1018 RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP resMsg = 1019 RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.parseFrom( 1020 msg.getPayload().toByteArray()); 1021 mMsgType = ID_SET_TRANSPORT_PROTOCOL_RESP; 1022 switch(resMsg.getResponse()) { 1023 case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_SUCCESS: 1024 mResultCode = RESULT_OK; 1025 break; 1026 case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_GENERIC_FAILURE: 1027 mResultCode = RESULT_ERROR_NOT_SUPPORTED; 1028 break; 1029 case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_SIM_ABSENT: 1030 mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; 1031 break; 1032 case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: 1033 mResultCode = RESULT_ERROR_CARD_POWERED_OFF; 1034 break; 1035 case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_SIM_NOT_READY: 1036 mResultCode = RESULT_ERROR_CARD_REMOVED; 1037 break; 1038 default: 1039 mResultCode = RESULT_ERROR_NOT_SUPPORTED; 1040 break; 1041 } 1042 break; 1043 } 1044 case ID_TRANSFER_ATR_REQ: 1045 { 1046 RIL_SIM_SAP_TRANSFER_ATR_RSP resMsg = 1047 RIL_SIM_SAP_TRANSFER_ATR_RSP.parseFrom(msg.getPayload().toByteArray()); 1048 mMsgType =ID_TRANSFER_ATR_RESP; 1049 if(resMsg.hasAtr()) { 1050 mAtr = resMsg.getAtr().toByteArray(); 1051 } 1052 switch(resMsg.getResponse()) { 1053 case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SUCCESS: 1054 mResultCode = RESULT_OK; 1055 break; 1056 case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_GENERIC_FAILURE: 1057 mResultCode = RESULT_ERROR_NO_REASON; 1058 break; 1059 case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SIM_ABSENT: 1060 mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; 1061 break; 1062 case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: 1063 mResultCode = RESULT_ERROR_CARD_POWERED_OFF; 1064 break; 1065 case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SIM_ALREADY_POWERED_ON: 1066 mResultCode = RESULT_ERROR_CARD_POWERED_ON; 1067 break; 1068 case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SIM_DATA_NOT_AVAILABLE: 1069 mResultCode = RESULT_ERROR_DATA_NOT_AVAILABLE; 1070 break; 1071 default: 1072 mResultCode = RESULT_ERROR_NO_REASON; 1073 break; 1074 } 1075 break; 1076 } 1077 case ID_POWER_SIM_OFF_REQ: 1078 { 1079 RIL_SIM_SAP_POWER_RSP resMsg = 1080 RIL_SIM_SAP_POWER_RSP.parseFrom(msg.getPayload().toByteArray()); 1081 mMsgType = ID_POWER_SIM_OFF_RESP; 1082 switch(resMsg.getResponse()) { 1083 case RIL_SIM_SAP_POWER_RSP.RIL_E_SUCCESS: 1084 mResultCode = RESULT_OK; 1085 break; 1086 case RIL_SIM_SAP_POWER_RSP.RIL_E_GENERIC_FAILURE: 1087 mResultCode = RESULT_ERROR_NO_REASON; 1088 break; 1089 case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ABSENT: 1090 mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; 1091 break; 1092 case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: 1093 mResultCode = RESULT_ERROR_CARD_POWERED_OFF; 1094 break; 1095 case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ALREADY_POWERED_ON: 1096 mResultCode = RESULT_ERROR_CARD_POWERED_ON; 1097 break; 1098 default: 1099 mResultCode = RESULT_ERROR_NO_REASON; 1100 break; 1101 } 1102 break; 1103 } 1104 case ID_POWER_SIM_ON_REQ: 1105 { 1106 RIL_SIM_SAP_POWER_RSP resMsg = 1107 RIL_SIM_SAP_POWER_RSP.parseFrom(msg.getPayload().toByteArray()); 1108 mMsgType = ID_POWER_SIM_ON_RESP; 1109 switch(resMsg.getResponse()) { 1110 case RIL_SIM_SAP_POWER_RSP.RIL_E_SUCCESS: 1111 mResultCode = RESULT_OK; 1112 break; 1113 case RIL_SIM_SAP_POWER_RSP.RIL_E_GENERIC_FAILURE: 1114 mResultCode = RESULT_ERROR_NO_REASON; 1115 break; 1116 case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ABSENT: 1117 mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; 1118 break; 1119 case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: 1120 mResultCode = RESULT_ERROR_CARD_POWERED_OFF; 1121 break; 1122 case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ALREADY_POWERED_ON: 1123 mResultCode = RESULT_ERROR_CARD_POWERED_ON; 1124 break; 1125 default: 1126 mResultCode = RESULT_ERROR_NO_REASON; 1127 break; 1128 } 1129 break; 1130 } 1131 case ID_RESET_SIM_REQ: 1132 { 1133 RIL_SIM_SAP_RESET_SIM_RSP resMsg = 1134 RIL_SIM_SAP_RESET_SIM_RSP.parseFrom(msg.getPayload().toByteArray()); 1135 mMsgType = ID_RESET_SIM_RESP; 1136 switch(resMsg.getResponse()) { 1137 case RIL_SIM_SAP_RESET_SIM_RSP.RIL_E_SUCCESS: 1138 mResultCode = RESULT_OK; 1139 break; 1140 case RIL_SIM_SAP_RESET_SIM_RSP.RIL_E_GENERIC_FAILURE: 1141 mResultCode = RESULT_ERROR_NO_REASON; 1142 break; 1143 case RIL_SIM_SAP_RESET_SIM_RSP.RIL_E_SIM_ABSENT: 1144 mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; 1145 break; 1146 case RIL_SIM_SAP_RESET_SIM_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: 1147 mResultCode = RESULT_ERROR_CARD_POWERED_OFF; 1148 break; 1149 default: 1150 mResultCode = RESULT_ERROR_NO_REASON; 1151 break; 1152 } 1153 break; 1154 } 1155 case ID_TRANSFER_CARD_READER_STATUS_REQ: 1156 { 1157 RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP resMsg = 1158 RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP.parseFrom( 1159 msg.getPayload().toByteArray()); 1160 mMsgType = ID_TRANSFER_CARD_READER_STATUS_RESP; 1161 switch(resMsg.getResponse()) { 1162 case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP.RIL_E_SUCCESS: 1163 mResultCode = RESULT_OK; 1164 if(resMsg.hasCardReaderStatus()) { 1165 mCardReaderStatus = resMsg.getCardReaderStatus(); 1166 } else { 1167 mResultCode = RESULT_ERROR_DATA_NOT_AVAILABLE; 1168 } 1169 break; 1170 case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP.RIL_E_GENERIC_FAILURE: 1171 mResultCode = RESULT_ERROR_NO_REASON; 1172 break; 1173 case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP.RIL_E_SIM_DATA_NOT_AVAILABLE: 1174 mResultCode = RESULT_ERROR_DATA_NOT_AVAILABLE; 1175 break; 1176 default: 1177 mResultCode = RESULT_ERROR_NO_REASON; 1178 break; 1179 } 1180 break; 1181 } 1182 1183 case ID_RIL_SIM_ACCESS_TEST_REQ: // TODO: implement in RILD 1184 mMsgType = ID_RIL_SIM_ACCESS_TEST_RESP; 1185 break; 1186 default: 1187 Log.e(TAG, "Unknown request type: " + reqType); 1188 1189 } 1190 } 1191 1192 1193 1194 /* Map from RIL header error codes to SAP error codes */ 1195 private static int mapRilErrorCode(int rilErrorCode) { 1196 switch(rilErrorCode) { 1197 case SapApi.RIL_E_SUCCESS: 1198 return RESULT_OK; 1199 case SapApi.RIL_E_CANCELLED: 1200 return RESULT_ERROR_NO_REASON; 1201 case SapApi.RIL_E_GENERIC_FAILURE: 1202 return RESULT_ERROR_NO_REASON; 1203 case SapApi.RIL_E_RADIO_NOT_AVAILABLE: 1204 return RESULT_ERROR_CARD_NOT_ACCESSIBLE; 1205 case SapApi.RIL_E_INVALID_PARAMETER: 1206 return RESULT_ERROR_NO_REASON; 1207 case SapApi.RIL_E_REQUEST_NOT_SUPPORTED: 1208 return RESULT_ERROR_NOT_SUPPORTED; 1209 default: 1210 return RESULT_ERROR_NO_REASON; 1211 } 1212 } 1213 1214 1215 1216 public static String getMsgTypeName(int msgType) { 1217 if(TEST || VERBOSE) { 1218 switch (msgType) 1219 { 1220 case ID_CONNECT_REQ: return "ID_CONNECT_REQ"; 1221 case ID_CONNECT_RESP: return "ID_CONNECT_RESP"; 1222 case ID_DISCONNECT_REQ: return "ID_DISCONNECT_REQ"; 1223 case ID_DISCONNECT_RESP: return "ID_DISCONNECT_RESP"; 1224 case ID_DISCONNECT_IND: return "ID_DISCONNECT_IND"; 1225 case ID_TRANSFER_APDU_REQ: return "ID_TRANSFER_APDU_REQ"; 1226 case ID_TRANSFER_APDU_RESP: return "ID_TRANSFER_APDU_RESP"; 1227 case ID_TRANSFER_ATR_REQ: return "ID_TRANSFER_ATR_REQ"; 1228 case ID_TRANSFER_ATR_RESP: return "ID_TRANSFER_ATR_RESP"; 1229 case ID_POWER_SIM_OFF_REQ: return "ID_POWER_SIM_OFF_REQ"; 1230 case ID_POWER_SIM_OFF_RESP: return "ID_POWER_SIM_OFF_RESP"; 1231 case ID_POWER_SIM_ON_REQ: return "ID_POWER_SIM_ON_REQ"; 1232 case ID_POWER_SIM_ON_RESP: return "ID_POWER_SIM_ON_RESP"; 1233 case ID_RESET_SIM_REQ: return "ID_RESET_SIM_REQ"; 1234 case ID_RESET_SIM_RESP: return "ID_RESET_SIM_RESP"; 1235 case ID_TRANSFER_CARD_READER_STATUS_REQ: 1236 return "ID_TRANSFER_CARD_READER_STATUS_REQ"; 1237 case ID_TRANSFER_CARD_READER_STATUS_RESP: 1238 return "ID_TRANSFER_CARD_READER_STATUS_RESP"; 1239 case ID_STATUS_IND: return "ID_STATUS_IND"; 1240 case ID_ERROR_RESP: return "ID_ERROR_RESP"; 1241 case ID_SET_TRANSPORT_PROTOCOL_REQ: return "ID_SET_TRANSPORT_PROTOCOL_REQ"; 1242 case ID_SET_TRANSPORT_PROTOCOL_RESP: return "ID_SET_TRANSPORT_PROTOCOL_RESP"; 1243 case ID_RIL_UNSOL_CONNECTED: return "ID_RIL_UNSOL_CONNECTED"; 1244 case ID_RIL_UNKNOWN: return "ID_RIL_UNKNOWN"; 1245 case ID_RIL_GET_SIM_STATUS_REQ: return "ID_RIL_GET_SIM_STATUS_REQ"; 1246 case ID_RIL_SIM_ACCESS_TEST_REQ: return "ID_RIL_SIM_ACCESS_TEST_REQ"; 1247 case ID_RIL_SIM_ACCESS_TEST_RESP: return "ID_RIL_SIM_ACCESS_TEST_RESP"; 1248 default: return "Unknown Message Type (" + msgType + ")"; 1249 } 1250 } else { 1251 return null; 1252 } 1253 } 1254 } 1255