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 = false; 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 */ SapMessage(int msgType)185 public SapMessage(int msgType){ 186 this.mMsgType = msgType; 187 } 188 resetPendingRilMessages()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 getNumPendingRilMessages()197 public static int getNumPendingRilMessages() { 198 return sOngoingRequests.size(); 199 } 200 getMsgType()201 public int getMsgType() { 202 return mMsgType; 203 } 204 setMsgType(int msgType)205 public void setMsgType(int msgType) { 206 this.mMsgType = msgType; 207 } 208 getMaxMsgSize()209 public int getMaxMsgSize() { 210 return mMaxMsgSize; 211 } 212 setMaxMsgSize(int maxMsgSize)213 public void setMaxMsgSize(int maxMsgSize) { 214 this.mMaxMsgSize = maxMsgSize; 215 } 216 getConnectionStatus()217 public int getConnectionStatus() { 218 return mConnectionStatus; 219 } 220 setConnectionStatus(int connectionStatus)221 public void setConnectionStatus(int connectionStatus) { 222 this.mConnectionStatus = connectionStatus; 223 } 224 getResultCode()225 public int getResultCode() { 226 return mResultCode; 227 } 228 setResultCode(int resultCode)229 public void setResultCode(int resultCode) { 230 this.mResultCode = resultCode; 231 } 232 getDisconnectionType()233 public int getDisconnectionType() { 234 return mDisconnectionType; 235 } 236 setDisconnectionType(int disconnectionType)237 public void setDisconnectionType(int disconnectionType) { 238 this.mDisconnectionType = disconnectionType; 239 } 240 getCardReaderStatus()241 public int getCardReaderStatus() { 242 return mCardReaderStatus; 243 } 244 setCardReaderStatus(int cardReaderStatus)245 public void setCardReaderStatus(int cardReaderStatus) { 246 this.mCardReaderStatus = cardReaderStatus; 247 } 248 getStatusChange()249 public int getStatusChange() { 250 return mStatusChange; 251 } 252 setStatusChange(int statusChange)253 public void setStatusChange(int statusChange) { 254 this.mStatusChange = statusChange; 255 } 256 getTransportProtocol()257 public int getTransportProtocol() { 258 return mTransportProtocol; 259 } 260 setTransportProtocol(int transportProtocol)261 public void setTransportProtocol(int transportProtocol) { 262 this.mTransportProtocol = transportProtocol; 263 } 264 getApdu()265 public byte[] getApdu() { 266 return mApdu; 267 } 268 setApdu(byte[] apdu)269 public void setApdu(byte[] apdu) { 270 this.mApdu = apdu; 271 } 272 getApdu7816()273 public byte[] getApdu7816() { 274 return mApdu7816; 275 } 276 setApdu7816(byte[] apdu)277 public void setApdu7816(byte[] apdu) { 278 this.mApdu7816 = apdu; 279 } 280 getApduResp()281 public byte[] getApduResp() { 282 return mApduResp; 283 } 284 setApduResp(byte[] apduResp)285 public void setApduResp(byte[] apduResp) { 286 this.mApduResp = apduResp; 287 } 288 getAtr()289 public byte[] getAtr() { 290 return mAtr; 291 } 292 setAtr(byte[] atr)293 public void setAtr(byte[] atr) { 294 this.mAtr = atr; 295 } 296 getSendToRil()297 public boolean getSendToRil() { 298 return mSendToRil; 299 } 300 setSendToRil(boolean sendToRil)301 public void setSendToRil(boolean sendToRil) { 302 this.mSendToRil = sendToRil; 303 } 304 getClearRilQueue()305 public boolean getClearRilQueue() { 306 return mClearRilQueue; 307 } 308 setClearRilQueue(boolean clearRilQueue)309 public void setClearRilQueue(boolean clearRilQueue) { 310 this.mClearRilQueue = clearRilQueue; 311 } 312 getTestMode()313 public int getTestMode() { 314 return mTestMode; 315 } 316 setTestMode(int testMode)317 public void setTestMode(int testMode) { 318 this.mTestMode = testMode; 319 } 320 getParamCount()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") readMessage(int requestType, InputStream is)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 Log.e(TAG, "Unknown request type"); 408 return null; 409 } 410 return newMessage; 411 } 412 413 /** 414 * Blocking read of an entire array of data. 415 * @param is the input stream to read from 416 * @param buffer the buffer to read into - the length of the buffer will 417 * determine how many bytes will be read. 418 */ read(InputStream is, byte[] buffer)419 private static void read(InputStream is, byte[] buffer) throws IOException { 420 int bytesToRead = buffer.length; 421 int bytesRead = 0; 422 int tmpBytesRead; 423 while (bytesRead < bytesToRead) { 424 tmpBytesRead = is.read(buffer, bytesRead, bytesToRead-bytesRead); 425 if(tmpBytesRead == -1) 426 throw new IOException("EOS reached while reading a byte array."); 427 else 428 bytesRead += tmpBytesRead; 429 } 430 } 431 432 /** 433 * Skip a number of bytes in an InputStream. 434 * @param is the input stream 435 * @param count the number of bytes to skip 436 * @throws IOException In case of reaching EOF or a stream error 437 */ skip(InputStream is, int count)438 private static void skip(InputStream is, int count) throws IOException { 439 for(int i = 0; i < count; i++) { 440 is.read(); // Do not use the InputStream.skip as it fails for some stream types 441 } 442 } 443 444 /** 445 * Read the parameters from the stream and update the relevant members. 446 * This function will ensure that all parameters are read from the stream, even 447 * if an error is detected. 448 * @param count the number of parameters to read 449 * @param is the input stream 450 * @return True if all parameters were successfully parsed, False if an error were detected. 451 * @throws IOException 452 */ parseParameters(int count, InputStream is)453 private boolean parseParameters(int count, InputStream is) throws IOException { 454 int paramId; 455 int paramLength; 456 boolean success = true; 457 int skipLen = 0; 458 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 465 // As per SAP spec padding should be 0-3 bytes 466 if ((paramLength % 4) != 0) 467 skipLen = 4 - (paramLength % 4); 468 469 if(VERBOSE) Log.i(TAG, "parsing paramId: " + paramId + " with length: " + paramLength); 470 switch(paramId) { 471 case PARAM_MAX_MSG_SIZE_ID: 472 if(paramLength != PARAM_MAX_MSG_SIZE_LENGTH) { 473 Log.e(TAG, "Received PARAM_MAX_MSG_SIZE with wrong length: " + 474 paramLength + " skipping this parameter."); 475 skip(is, paramLength + skipLen); 476 success = false; 477 } else { 478 mMaxMsgSize = is.read(); 479 mMaxMsgSize = mMaxMsgSize << 8 | is.read(); 480 skip(is, 4 - PARAM_MAX_MSG_SIZE_LENGTH); 481 } 482 break; 483 case PARAM_COMMAND_APDU_ID: 484 mApdu = new byte[paramLength]; 485 read(is, mApdu); 486 skip(is, skipLen); 487 break; 488 case PARAM_COMMAND_APDU7816_ID: 489 mApdu7816 = new byte[paramLength]; 490 read(is, mApdu7816); 491 skip(is, skipLen); 492 break; 493 case PARAM_TRANSPORT_PROTOCOL_ID: 494 if(paramLength != PARAM_TRANSPORT_PROTOCOL_LENGTH) { 495 Log.e(TAG, "Received PARAM_TRANSPORT_PROTOCOL with wrong length: " + 496 paramLength + " skipping this parameter."); 497 skip(is, paramLength + skipLen); 498 success = false; 499 } else { 500 mTransportProtocol = is.read(); 501 skip(is, 4 - PARAM_TRANSPORT_PROTOCOL_LENGTH); 502 } 503 break; 504 case PARAM_CONNECTION_STATUS_ID: 505 // not needed for server role, but used for module test 506 if(paramLength != PARAM_CONNECTION_STATUS_LENGTH) { 507 Log.e(TAG, "Received PARAM_CONNECTION_STATUS with wrong length: " + 508 paramLength + " skipping this parameter."); 509 skip(is, paramLength + skipLen); 510 success = false; 511 } else { 512 mConnectionStatus = is.read(); 513 skip(is, 4 - PARAM_CONNECTION_STATUS_LENGTH); 514 } 515 break; 516 case PARAM_CARD_READER_STATUS_ID: 517 // not needed for server role, but used for module test 518 if(paramLength != PARAM_CARD_READER_STATUS_LENGTH) { 519 Log.e(TAG, "Received PARAM_CARD_READER_STATUS with wrong length: " + 520 paramLength + " skipping this parameter."); 521 skip(is, paramLength + skipLen); 522 success = false; 523 } else { 524 mCardReaderStatus = is.read(); 525 skip(is, 4 - PARAM_CARD_READER_STATUS_LENGTH); 526 } 527 break; 528 case PARAM_STATUS_CHANGE_ID: 529 // not needed for server role, but used for module 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 + skipLen); 534 success = false; 535 } else { 536 mStatusChange = is.read(); 537 skip(is, 4 - PARAM_STATUS_CHANGE_LENGTH); 538 } 539 break; 540 case PARAM_RESULT_CODE_ID: 541 // not needed for server role, but used for module test 542 if(paramLength != PARAM_RESULT_CODE_LENGTH) { 543 Log.e(TAG, "Received PARAM_RESULT_CODE with wrong length: " + 544 paramLength + " skipping this parameter."); 545 skip(is, paramLength + skipLen); 546 success = false; 547 } else { 548 mResultCode = is.read(); 549 skip(is, 4 - PARAM_RESULT_CODE_LENGTH); 550 } 551 break; 552 case PARAM_DISCONNECT_TYPE_ID: 553 // not needed for server role, but used for module test 554 if(paramLength != PARAM_DISCONNECT_TYPE_LENGTH) { 555 Log.e(TAG, "Received PARAM_DISCONNECT_TYPE_ID with wrong length: " + 556 paramLength + " skipping this parameter."); 557 skip(is, paramLength + skipLen); 558 success = false; 559 } else { 560 mDisconnectionType = is.read(); 561 skip(is, 4 - PARAM_DISCONNECT_TYPE_LENGTH); 562 } 563 break; 564 case PARAM_RESPONSE_APDU_ID: 565 // not needed for server role, but used for module test 566 mApduResp = new byte[paramLength]; 567 read(is, mApduResp); 568 skip(is, skipLen); 569 break; 570 case PARAM_ATR_ID: 571 // not needed for server role, but used for module test 572 mAtr = new byte[paramLength]; 573 read(is, mAtr); 574 skip(is, skipLen); 575 break; 576 default: 577 Log.e(TAG, "Received unknown parameter ID: " + paramId + " length: " + 578 paramLength + " skipping this parameter."); 579 skip(is, paramLength + skipLen); 580 } 581 } 582 return success; 583 } 584 585 /** 586 * Writes a single value parameter of 1 or 2 bytes in length. 587 * @param os The BufferedOutputStream to write to. 588 * @param id The Parameter ID 589 * @param value The parameter value 590 * @param length The length of the parameter value 591 * @throws IOException if the write to os fails 592 */ writeParameter(OutputStream os, int id, int value, int length)593 private static void writeParameter(OutputStream os, int id, int value, int length) 594 throws IOException { 595 596 /* Parameter Header*/ 597 os.write(id); 598 os.write(0); 599 os.write(0); 600 os.write(length); 601 602 switch(length) { 603 case 1: 604 os.write(value & 0xff); 605 os.write(0); // Padding 606 os.write(0); // Padding 607 os.write(0); // padding 608 break; 609 case 2: 610 os.write((value >> 8) & 0xff); 611 os.write(value & 0xff); 612 os.write(0); // Padding 613 os.write(0); // padding 614 break; 615 default: 616 throw new IOException("Unable to write value of length: " + length); 617 } 618 } 619 620 /** 621 * Writes a byte[] parameter of any length. 622 * @param os The BufferedOutputStream to write to. 623 * @param id The Parameter ID 624 * @param value The byte array to write, the length will be extracted from the array. 625 * @throws IOException if the write to os fails 626 */ writeParameter(OutputStream os, int id, byte[] value)627 private static void writeParameter(OutputStream os, int id, byte[] value) throws IOException { 628 629 /* Parameter Header*/ 630 os.write(id); 631 os.write(0); // reserved 632 os.write((value.length >> 8) & 0xff); 633 os.write(value.length & 0xff); 634 635 /* Payload */ 636 os.write(value); 637 if (value.length % 4 != 0) { 638 for (int i = 0; i < (4 - (value.length % 4)); ++i) { 639 os.write(0); // Padding 640 } 641 } 642 } 643 write(OutputStream os)644 public void write(OutputStream os) throws IOException { 645 /* Write the header */ 646 os.write(mMsgType); 647 os.write(getParamCount()); 648 os.write(0); // padding 649 os.write(0); // padding 650 651 /* write the parameters */ 652 if(mConnectionStatus != INVALID_VALUE) { 653 writeParameter(os,PARAM_CONNECTION_STATUS_ID, mConnectionStatus, 654 PARAM_CONNECTION_STATUS_LENGTH); 655 } 656 if(mMaxMsgSize != INVALID_VALUE) { 657 writeParameter(os, PARAM_MAX_MSG_SIZE_ID, mMaxMsgSize, 658 PARAM_MAX_MSG_SIZE_LENGTH); 659 } 660 if(mResultCode != INVALID_VALUE) { 661 writeParameter(os, PARAM_RESULT_CODE_ID, mResultCode, 662 PARAM_RESULT_CODE_LENGTH); 663 } 664 if(mDisconnectionType != INVALID_VALUE) { 665 writeParameter(os, PARAM_DISCONNECT_TYPE_ID, mDisconnectionType, 666 PARAM_DISCONNECT_TYPE_LENGTH); 667 } 668 if(mCardReaderStatus != INVALID_VALUE) { 669 writeParameter(os, PARAM_CARD_READER_STATUS_ID, mCardReaderStatus, 670 PARAM_CARD_READER_STATUS_LENGTH); 671 } 672 if(mStatusChange != INVALID_VALUE) { 673 writeParameter(os, PARAM_STATUS_CHANGE_ID, mStatusChange, 674 PARAM_STATUS_CHANGE_LENGTH); 675 } 676 if(mTransportProtocol != INVALID_VALUE) { 677 writeParameter(os, PARAM_TRANSPORT_PROTOCOL_ID, mTransportProtocol, 678 PARAM_TRANSPORT_PROTOCOL_LENGTH); 679 } 680 if(mApdu != null) { 681 writeParameter(os, PARAM_COMMAND_APDU_ID, mApdu); 682 } 683 if(mApdu7816 != null) { 684 writeParameter(os, PARAM_COMMAND_APDU7816_ID, mApdu7816); 685 } 686 if(mApduResp != null) { 687 writeParameter(os, PARAM_RESPONSE_APDU_ID, mApduResp); 688 } 689 if(mAtr != null) { 690 writeParameter(os, PARAM_ATR_ID, mAtr); 691 } 692 } 693 694 /*************************************************************************** 695 * RILD Interface message conversion functions. 696 ***************************************************************************/ 697 698 /** 699 * We use this function to 700 * @param length 701 * @param rawOut 702 * @throws IOException 703 */ writeLength(int length, CodedOutputStreamMicro out)704 private void writeLength(int length, CodedOutputStreamMicro out) throws IOException { 705 byte[] dataLength = new byte[4]; 706 dataLength[0] = dataLength[1] = 0; 707 dataLength[2] = (byte)((length >> 8) & 0xff); 708 dataLength[3] = (byte)((length) & 0xff); 709 out.writeRawBytes(dataLength); 710 } 711 /** 712 * Write this SAP message as a rild compatible protobuf message. 713 * Solicited Requests are formed as follows: 714 * int type - the rild-bt type 715 * int serial - an number incrementing for each message. 716 */ writeReqToStream(CodedOutputStreamMicro out)717 public void writeReqToStream(CodedOutputStreamMicro out) throws IOException { 718 719 int rilSerial = sNextSerial.getAndIncrement(); 720 SapApi.MsgHeader msg = new MsgHeader(); 721 /* Common variables for all requests */ 722 msg.setToken(rilSerial); 723 msg.setType(SapApi.REQUEST); 724 msg.setError(SapApi.RIL_E_UNUSED); 725 726 switch(mMsgType) { 727 case ID_CONNECT_REQ: 728 { 729 SapApi.RIL_SIM_SAP_CONNECT_REQ reqMsg = new RIL_SIM_SAP_CONNECT_REQ(); 730 reqMsg.setMaxMessageSize(mMaxMsgSize); 731 msg.setId(SapApi.RIL_SIM_SAP_CONNECT); 732 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 733 writeLength(msg.getSerializedSize(), out); 734 msg.writeTo(out); 735 break; 736 } 737 case ID_DISCONNECT_REQ: 738 { 739 SapApi.RIL_SIM_SAP_DISCONNECT_REQ reqMsg = new RIL_SIM_SAP_DISCONNECT_REQ(); 740 msg.setId(SapApi.RIL_SIM_SAP_DISCONNECT); 741 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 742 writeLength(msg.getSerializedSize(), out); 743 msg.writeTo(out); 744 break; 745 } 746 case ID_TRANSFER_APDU_REQ: 747 { 748 SapApi.RIL_SIM_SAP_APDU_REQ reqMsg = new RIL_SIM_SAP_APDU_REQ(); 749 msg.setId(SapApi.RIL_SIM_SAP_APDU); 750 if(mApdu != null) { 751 reqMsg.setType(SapApi.RIL_SIM_SAP_APDU_REQ.RIL_TYPE_APDU); 752 reqMsg.setCommand(ByteStringMicro.copyFrom(mApdu)); 753 } else if (mApdu7816 != null) { 754 reqMsg.setType(SapApi.RIL_SIM_SAP_APDU_REQ.RIL_TYPE_APDU7816); 755 reqMsg.setCommand(ByteStringMicro.copyFrom(mApdu7816)); 756 } else { 757 Log.e(TAG, "Missing Apdu parameter in TRANSFER_APDU_REQ"); 758 throw new IllegalArgumentException(); 759 } 760 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 761 writeLength(msg.getSerializedSize(), out); 762 msg.writeTo(out); 763 break; 764 } 765 case ID_SET_TRANSPORT_PROTOCOL_REQ: 766 { 767 SapApi.RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ reqMsg = 768 new RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ(); 769 msg.setId(SapApi.RIL_SIM_SAP_SET_TRANSFER_PROTOCOL); 770 771 if(mTransportProtocol == TRANS_PROTO_T0) { 772 reqMsg.setProtocol(SapApi.RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ.t0); 773 } else if(mTransportProtocol == TRANS_PROTO_T1) { 774 reqMsg.setProtocol(SapApi.RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ.t1); 775 } else { 776 Log.e(TAG, "Missing or invalid TransportProtocol parameter in"+ 777 " SET_TRANSPORT_PROTOCOL_REQ: "+ mTransportProtocol ); 778 throw new IllegalArgumentException(); 779 } 780 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 781 writeLength(msg.getSerializedSize(), out); 782 msg.writeTo(out); 783 break; 784 } 785 case ID_TRANSFER_ATR_REQ: 786 { 787 SapApi.RIL_SIM_SAP_TRANSFER_ATR_REQ reqMsg = new RIL_SIM_SAP_TRANSFER_ATR_REQ(); 788 msg.setId(SapApi.RIL_SIM_SAP_TRANSFER_ATR); 789 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 790 writeLength(msg.getSerializedSize(), out); 791 msg.writeTo(out); 792 break; 793 } 794 case ID_POWER_SIM_OFF_REQ: 795 { 796 SapApi.RIL_SIM_SAP_POWER_REQ reqMsg = new RIL_SIM_SAP_POWER_REQ(); 797 msg.setId(SapApi.RIL_SIM_SAP_POWER); 798 reqMsg.setState(false); 799 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 800 writeLength(msg.getSerializedSize(), out); 801 msg.writeTo(out); 802 break; 803 } 804 case ID_POWER_SIM_ON_REQ: 805 { 806 SapApi.RIL_SIM_SAP_POWER_REQ reqMsg = new RIL_SIM_SAP_POWER_REQ(); 807 msg.setId(SapApi.RIL_SIM_SAP_POWER); 808 reqMsg.setState(true); 809 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 810 writeLength(msg.getSerializedSize(), out); 811 msg.writeTo(out); 812 break; 813 } 814 case ID_RESET_SIM_REQ: 815 { 816 SapApi.RIL_SIM_SAP_RESET_SIM_REQ reqMsg = new RIL_SIM_SAP_RESET_SIM_REQ(); 817 msg.setId(SapApi.RIL_SIM_SAP_RESET_SIM); 818 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 819 writeLength(msg.getSerializedSize(), out); 820 msg.writeTo(out); 821 break; 822 } 823 case ID_TRANSFER_CARD_READER_STATUS_REQ: 824 { 825 SapApi.RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ reqMsg = 826 new RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ(); 827 msg.setId(SapApi.RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS); 828 msg.setPayload(ByteStringMicro.copyFrom(reqMsg.toByteArray())); 829 writeLength(msg.getSerializedSize(), out); 830 msg.writeTo(out); 831 break; 832 } 833 default: 834 Log.e(TAG, "Unknown request type"); 835 throw new IllegalArgumentException(); 836 } 837 /* Update the ongoing requests queue */ 838 if(mClearRilQueue == true) { 839 resetPendingRilMessages(); 840 } 841 // No need to synchronize this, as the HashList is already doing this. 842 sOngoingRequests.put(rilSerial, mMsgType); 843 out.flush(); 844 } 845 newInstance(MsgHeader msg)846 public static SapMessage newInstance(MsgHeader msg) throws IOException { 847 return new SapMessage(msg); 848 } 849 SapMessage(MsgHeader msg)850 private SapMessage(MsgHeader msg) throws IOException { 851 // All header members are "required" hence the hasXxxx() is not needed for those 852 try{ 853 switch(msg.getType()){ 854 case SapApi.UNSOL_RESPONSE: 855 createUnsolicited(msg); 856 break; 857 case SapApi.RESPONSE: 858 createSolicited(msg); 859 break; 860 default: 861 throw new IOException("Wrong msg header received: Type: " + msg.getType()); 862 } 863 } catch (InvalidProtocolBufferMicroException e) { 864 Log.w(TAG, "Error occured parsing a RIL message", e); 865 throw new IOException("Error occured parsing a RIL message"); 866 } 867 } 868 createUnsolicited(MsgHeader msg)869 private void createUnsolicited(MsgHeader msg) 870 throws IOException, InvalidProtocolBufferMicroException { 871 switch(msg.getId()) { 872 // TODO: 873 // Not sure when we use these? case RIL_UNSOL_RIL_CONNECTED: 874 // if(VERBOSE) Log.i(TAG, "RIL_UNSOL_RIL_CONNECTED received, ignoring"); 875 // msgType = ID_RIL_UNSOL_CONNECTED; 876 // break; 877 case SapApi.RIL_SIM_SAP_STATUS: 878 { 879 if(VERBOSE) Log.i(TAG, "RIL_SIM_SAP_STATUS_IND received"); 880 RIL_SIM_SAP_STATUS_IND indMsg = 881 RIL_SIM_SAP_STATUS_IND.parseFrom(msg.getPayload().toByteArray()); 882 mMsgType = ID_STATUS_IND; 883 if(indMsg.hasStatusChange()) { 884 setStatusChange(indMsg.getStatusChange()); 885 if(VERBOSE) Log.i(TAG, "RIL_UNSOL_SIM_SAP_STATUS_IND received value = " 886 + mStatusChange); 887 } else { 888 if(VERBOSE) Log.i(TAG, "Wrong number of parameters in SAP_STATUS_IND, ignoring..."); 889 mMsgType = ID_RIL_UNKNOWN; 890 } 891 break; 892 } 893 case SapApi.RIL_SIM_SAP_DISCONNECT: 894 { 895 if(VERBOSE) Log.i(TAG, "RIL_SIM_SAP_DISCONNECT_IND received"); 896 897 RIL_SIM_SAP_DISCONNECT_IND indMsg = 898 RIL_SIM_SAP_DISCONNECT_IND.parseFrom(msg.getPayload().toByteArray()); 899 mMsgType = ID_RIL_UNSOL_DISCONNECT_IND; // don't use ID_DISCONNECT_IND; 900 if(indMsg.hasDisconnectType()) { 901 setDisconnectionType(indMsg.getDisconnectType()); 902 if(VERBOSE) Log.i(TAG, "RIL_UNSOL_SIM_SAP_STATUS_IND received value = " 903 + mDisconnectionType); 904 } else { 905 if(VERBOSE) Log.i(TAG, "Wrong number of parameters in SAP_STATUS_IND, ignoring..."); 906 mMsgType = ID_RIL_UNKNOWN; 907 } 908 break; 909 } 910 default: 911 if(VERBOSE) Log.i(TAG, "Unused unsolicited message received, ignoring: " + msg.getId()); 912 mMsgType = ID_RIL_UNKNOWN; 913 } 914 } 915 createSolicited(MsgHeader msg)916 private void createSolicited(MsgHeader msg) throws IOException, 917 InvalidProtocolBufferMicroException{ 918 /* re-evaluate if we should just ignore these - we could simply catch the exception? */ 919 if(msg.hasToken() == false) throw new IOException("Token is missing"); 920 if(msg.hasError() == false) throw new IOException("Error code is missing"); 921 int serial = msg.getToken(); 922 int error = msg.getError(); 923 Integer reqType = null; 924 reqType = sOngoingRequests.remove(serial); 925 if(VERBOSE) Log.i(TAG, "RIL SOLICITED serial: " + serial + ", error: " + error 926 + " SapReqType: " + ((reqType== null)?"null":getMsgTypeName(reqType))); 927 928 if(reqType == null) { 929 /* This can happen if we get a resp. for a canceled request caused by a power off, 930 * reset or disconnect 931 */ 932 Log.w(TAG, "Solicited response received on a command not initiated - ignoring."); 933 return; 934 } 935 mResultCode = mapRilErrorCode(error); 936 937 switch(reqType) { 938 case ID_CONNECT_REQ: 939 { 940 RIL_SIM_SAP_CONNECT_RSP resMsg = 941 RIL_SIM_SAP_CONNECT_RSP.parseFrom(msg.getPayload().toByteArray()); 942 mMsgType = ID_CONNECT_RESP; 943 if(resMsg.hasMaxMessageSize()) { 944 mMaxMsgSize = resMsg.getMaxMessageSize(); 945 946 } 947 switch(resMsg.getResponse()) { 948 case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SUCCESS: 949 mConnectionStatus = CON_STATUS_OK; 950 break; 951 case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SAP_CONNECT_OK_CALL_ONGOING: 952 mConnectionStatus = CON_STATUS_OK_ONGOING_CALL; 953 break; 954 case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SAP_CONNECT_FAILURE: 955 mConnectionStatus = CON_STATUS_ERROR_CONNECTION; 956 break; 957 case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SAP_MSG_SIZE_TOO_LARGE: 958 mConnectionStatus = CON_STATUS_ERROR_MAX_MSG_SIZE_UNSUPPORTED; 959 break; 960 case RIL_SIM_SAP_CONNECT_RSP.RIL_E_SAP_MSG_SIZE_TOO_SMALL: 961 mConnectionStatus = CON_STATUS_ERROR_MAX_MSG_SIZE_TOO_SMALL; 962 break; 963 default: 964 mConnectionStatus = CON_STATUS_ERROR_CONNECTION; // Cannot happen! 965 break; 966 } 967 mResultCode = INVALID_VALUE; 968 if(VERBOSE) Log.v(TAG, " ID_CONNECT_REQ: mMaxMsgSize: " + mMaxMsgSize 969 + " mConnectionStatus: " + mConnectionStatus); 970 break; 971 } 972 case ID_DISCONNECT_REQ: 973 mMsgType = ID_DISCONNECT_RESP; 974 mResultCode = INVALID_VALUE; 975 break; 976 case ID_TRANSFER_APDU_REQ: 977 { 978 RIL_SIM_SAP_APDU_RSP resMsg = 979 RIL_SIM_SAP_APDU_RSP.parseFrom(msg.getPayload().toByteArray()); 980 mMsgType = ID_TRANSFER_APDU_RESP; 981 switch(resMsg.getResponse()) { 982 case RIL_SIM_SAP_APDU_RSP.RIL_E_SUCCESS: 983 mResultCode = RESULT_OK; 984 /* resMsg.getType is unused as the client knows the type of request used. */ 985 if(resMsg.hasApduResponse()){ 986 mApduResp = resMsg.getApduResponse().toByteArray(); 987 } 988 break; 989 case RIL_SIM_SAP_APDU_RSP.RIL_E_GENERIC_FAILURE: 990 mResultCode = RESULT_ERROR_NO_REASON; 991 break; 992 case RIL_SIM_SAP_APDU_RSP.RIL_E_SIM_ABSENT: 993 mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; 994 break; 995 case RIL_SIM_SAP_APDU_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: 996 mResultCode = RESULT_ERROR_CARD_POWERED_OFF; 997 break; 998 case RIL_SIM_SAP_APDU_RSP.RIL_E_SIM_NOT_READY: 999 mResultCode = RESULT_ERROR_CARD_REMOVED; 1000 break; 1001 default: 1002 mResultCode = RESULT_ERROR_NO_REASON; 1003 break; 1004 } 1005 break; 1006 } 1007 case ID_SET_TRANSPORT_PROTOCOL_REQ: 1008 { 1009 RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP resMsg = 1010 RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.parseFrom( 1011 msg.getPayload().toByteArray()); 1012 mMsgType = ID_SET_TRANSPORT_PROTOCOL_RESP; 1013 switch(resMsg.getResponse()) { 1014 case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_SUCCESS: 1015 mResultCode = RESULT_OK; 1016 break; 1017 case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_GENERIC_FAILURE: 1018 mResultCode = RESULT_ERROR_NOT_SUPPORTED; 1019 break; 1020 case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_SIM_ABSENT: 1021 mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; 1022 break; 1023 case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: 1024 mResultCode = RESULT_ERROR_CARD_POWERED_OFF; 1025 break; 1026 case RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP.RIL_E_SIM_NOT_READY: 1027 mResultCode = RESULT_ERROR_CARD_REMOVED; 1028 break; 1029 default: 1030 mResultCode = RESULT_ERROR_NOT_SUPPORTED; 1031 break; 1032 } 1033 break; 1034 } 1035 case ID_TRANSFER_ATR_REQ: 1036 { 1037 RIL_SIM_SAP_TRANSFER_ATR_RSP resMsg = 1038 RIL_SIM_SAP_TRANSFER_ATR_RSP.parseFrom(msg.getPayload().toByteArray()); 1039 mMsgType =ID_TRANSFER_ATR_RESP; 1040 if(resMsg.hasAtr()) { 1041 mAtr = resMsg.getAtr().toByteArray(); 1042 } 1043 switch(resMsg.getResponse()) { 1044 case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SUCCESS: 1045 mResultCode = RESULT_OK; 1046 break; 1047 case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_GENERIC_FAILURE: 1048 mResultCode = RESULT_ERROR_NO_REASON; 1049 break; 1050 case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SIM_ABSENT: 1051 mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; 1052 break; 1053 case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: 1054 mResultCode = RESULT_ERROR_CARD_POWERED_OFF; 1055 break; 1056 case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SIM_ALREADY_POWERED_ON: 1057 mResultCode = RESULT_ERROR_CARD_POWERED_ON; 1058 break; 1059 case RIL_SIM_SAP_TRANSFER_ATR_RSP.RIL_E_SIM_DATA_NOT_AVAILABLE: 1060 mResultCode = RESULT_ERROR_DATA_NOT_AVAILABLE; 1061 break; 1062 default: 1063 mResultCode = RESULT_ERROR_NO_REASON; 1064 break; 1065 } 1066 break; 1067 } 1068 case ID_POWER_SIM_OFF_REQ: 1069 { 1070 RIL_SIM_SAP_POWER_RSP resMsg = 1071 RIL_SIM_SAP_POWER_RSP.parseFrom(msg.getPayload().toByteArray()); 1072 mMsgType = ID_POWER_SIM_OFF_RESP; 1073 switch(resMsg.getResponse()) { 1074 case RIL_SIM_SAP_POWER_RSP.RIL_E_SUCCESS: 1075 mResultCode = RESULT_OK; 1076 break; 1077 case RIL_SIM_SAP_POWER_RSP.RIL_E_GENERIC_FAILURE: 1078 mResultCode = RESULT_ERROR_NO_REASON; 1079 break; 1080 case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ABSENT: 1081 mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; 1082 break; 1083 case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: 1084 mResultCode = RESULT_ERROR_CARD_POWERED_OFF; 1085 break; 1086 case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ALREADY_POWERED_ON: 1087 mResultCode = RESULT_ERROR_CARD_POWERED_ON; 1088 break; 1089 default: 1090 mResultCode = RESULT_ERROR_NO_REASON; 1091 break; 1092 } 1093 break; 1094 } 1095 case ID_POWER_SIM_ON_REQ: 1096 { 1097 RIL_SIM_SAP_POWER_RSP resMsg = 1098 RIL_SIM_SAP_POWER_RSP.parseFrom(msg.getPayload().toByteArray()); 1099 mMsgType = ID_POWER_SIM_ON_RESP; 1100 switch(resMsg.getResponse()) { 1101 case RIL_SIM_SAP_POWER_RSP.RIL_E_SUCCESS: 1102 mResultCode = RESULT_OK; 1103 break; 1104 case RIL_SIM_SAP_POWER_RSP.RIL_E_GENERIC_FAILURE: 1105 mResultCode = RESULT_ERROR_NO_REASON; 1106 break; 1107 case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ABSENT: 1108 mResultCode = RESULT_ERROR_CARD_NOT_ACCESSIBLE; 1109 break; 1110 case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ALREADY_POWERED_OFF: 1111 mResultCode = RESULT_ERROR_CARD_POWERED_OFF; 1112 break; 1113 case RIL_SIM_SAP_POWER_RSP.RIL_E_SIM_ALREADY_POWERED_ON: 1114 mResultCode = RESULT_ERROR_CARD_POWERED_ON; 1115 break; 1116 default: 1117 mResultCode = RESULT_ERROR_NO_REASON; 1118 break; 1119 } 1120 break; 1121 } 1122 case ID_RESET_SIM_REQ: 1123 { 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 { 1148 RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP resMsg = 1149 RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP.parseFrom( 1150 msg.getPayload().toByteArray()); 1151 mMsgType = ID_TRANSFER_CARD_READER_STATUS_RESP; 1152 switch(resMsg.getResponse()) { 1153 case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP.RIL_E_SUCCESS: 1154 mResultCode = RESULT_OK; 1155 if(resMsg.hasCardReaderStatus()) { 1156 mCardReaderStatus = resMsg.getCardReaderStatus(); 1157 } else { 1158 mResultCode = RESULT_ERROR_DATA_NOT_AVAILABLE; 1159 } 1160 break; 1161 case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP.RIL_E_GENERIC_FAILURE: 1162 mResultCode = RESULT_ERROR_NO_REASON; 1163 break; 1164 case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP.RIL_E_SIM_DATA_NOT_AVAILABLE: 1165 mResultCode = RESULT_ERROR_DATA_NOT_AVAILABLE; 1166 break; 1167 default: 1168 mResultCode = RESULT_ERROR_NO_REASON; 1169 break; 1170 } 1171 break; 1172 } 1173 1174 case ID_RIL_SIM_ACCESS_TEST_REQ: // TODO: implement in RILD 1175 mMsgType = ID_RIL_SIM_ACCESS_TEST_RESP; 1176 break; 1177 default: 1178 Log.e(TAG, "Unknown request type: " + reqType); 1179 1180 } 1181 } 1182 1183 1184 1185 /* Map from RIL header error codes to SAP error codes */ mapRilErrorCode(int rilErrorCode)1186 private static int mapRilErrorCode(int rilErrorCode) { 1187 switch(rilErrorCode) { 1188 case SapApi.RIL_E_SUCCESS: 1189 return RESULT_OK; 1190 case SapApi.RIL_E_CANCELLED: 1191 return RESULT_ERROR_NO_REASON; 1192 case SapApi.RIL_E_GENERIC_FAILURE: 1193 return RESULT_ERROR_NO_REASON; 1194 case SapApi.RIL_E_RADIO_NOT_AVAILABLE: 1195 return RESULT_ERROR_CARD_NOT_ACCESSIBLE; 1196 case SapApi.RIL_E_INVALID_PARAMETER: 1197 return RESULT_ERROR_NO_REASON; 1198 case SapApi.RIL_E_REQUEST_NOT_SUPPORTED: 1199 return RESULT_ERROR_NOT_SUPPORTED; 1200 default: 1201 return RESULT_ERROR_NO_REASON; 1202 } 1203 } 1204 1205 1206 getMsgTypeName(int msgType)1207 public static String getMsgTypeName(int msgType) { 1208 if(DEBUG || VERBOSE) { 1209 switch (msgType) 1210 { 1211 case ID_CONNECT_REQ: return "ID_CONNECT_REQ"; 1212 case ID_CONNECT_RESP: return "ID_CONNECT_RESP"; 1213 case ID_DISCONNECT_REQ: return "ID_DISCONNECT_REQ"; 1214 case ID_DISCONNECT_RESP: return "ID_DISCONNECT_RESP"; 1215 case ID_DISCONNECT_IND: return "ID_DISCONNECT_IND"; 1216 case ID_TRANSFER_APDU_REQ: return "ID_TRANSFER_APDU_REQ"; 1217 case ID_TRANSFER_APDU_RESP: return "ID_TRANSFER_APDU_RESP"; 1218 case ID_TRANSFER_ATR_REQ: return "ID_TRANSFER_ATR_REQ"; 1219 case ID_TRANSFER_ATR_RESP: return "ID_TRANSFER_ATR_RESP"; 1220 case ID_POWER_SIM_OFF_REQ: return "ID_POWER_SIM_OFF_REQ"; 1221 case ID_POWER_SIM_OFF_RESP: return "ID_POWER_SIM_OFF_RESP"; 1222 case ID_POWER_SIM_ON_REQ: return "ID_POWER_SIM_ON_REQ"; 1223 case ID_POWER_SIM_ON_RESP: return "ID_POWER_SIM_ON_RESP"; 1224 case ID_RESET_SIM_REQ: return "ID_RESET_SIM_REQ"; 1225 case ID_RESET_SIM_RESP: return "ID_RESET_SIM_RESP"; 1226 case ID_TRANSFER_CARD_READER_STATUS_REQ: 1227 return "ID_TRANSFER_CARD_READER_STATUS_REQ"; 1228 case ID_TRANSFER_CARD_READER_STATUS_RESP: 1229 return "ID_TRANSFER_CARD_READER_STATUS_RESP"; 1230 case ID_STATUS_IND: return "ID_STATUS_IND"; 1231 case ID_ERROR_RESP: return "ID_ERROR_RESP"; 1232 case ID_SET_TRANSPORT_PROTOCOL_REQ: return "ID_SET_TRANSPORT_PROTOCOL_REQ"; 1233 case ID_SET_TRANSPORT_PROTOCOL_RESP: return "ID_SET_TRANSPORT_PROTOCOL_RESP"; 1234 case ID_RIL_UNSOL_CONNECTED: return "ID_RIL_UNSOL_CONNECTED"; 1235 case ID_RIL_UNKNOWN: return "ID_RIL_UNKNOWN"; 1236 case ID_RIL_GET_SIM_STATUS_REQ: return "ID_RIL_GET_SIM_STATUS_REQ"; 1237 case ID_RIL_SIM_ACCESS_TEST_REQ: return "ID_RIL_SIM_ACCESS_TEST_REQ"; 1238 case ID_RIL_SIM_ACCESS_TEST_RESP: return "ID_RIL_SIM_ACCESS_TEST_RESP"; 1239 default: return "Unknown Message Type (" + msgType + ")"; 1240 } 1241 } else { 1242 return null; 1243 } 1244 } 1245 } 1246