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