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