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