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