1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.telephony.mockmodem;
18 
19 import static android.telephony.mockmodem.MockSimService.COMMAND_GET_RESPONSE;
20 import static android.telephony.mockmodem.MockSimService.COMMAND_READ_BINARY;
21 import static android.telephony.mockmodem.MockSimService.EF_GID1;
22 import static android.telephony.mockmodem.MockSimService.EF_ICCID;
23 
24 import android.hardware.radio.RadioError;
25 import android.hardware.radio.RadioIndicationType;
26 import android.hardware.radio.RadioResponseInfo;
27 import android.hardware.radio.sim.CardStatus;
28 import android.hardware.radio.sim.Carrier;
29 import android.hardware.radio.sim.CarrierRestrictions;
30 import android.hardware.radio.sim.IRadioSim;
31 import android.hardware.radio.sim.IRadioSimIndication;
32 import android.hardware.radio.sim.IRadioSimResponse;
33 import android.hardware.radio.sim.SimRefreshResult;
34 import android.os.AsyncResult;
35 import android.os.Build;
36 import android.os.Handler;
37 import android.os.Message;
38 import android.os.RemoteException;
39 import android.telephony.mockmodem.MockModemConfigBase.SimInfoChangedResult;
40 import android.telephony.mockmodem.MockSimService.SimAppData;
41 import android.util.Log;
42 
43 import java.util.ArrayList;
44 import com.android.internal.telephony.flags.Flags;
45 
46 public class IRadioSimImpl extends IRadioSim.Stub {
47     private static final String TAG = "MRSIM";
48     private final MockModemService mService;
49     private IRadioSimResponse mRadioSimResponse;
50     private IRadioSimIndication mRadioSimIndication;
51     private MockModemConfigInterface mMockModemConfigInterface;
52     private Object mCacheUpdateMutex;
53     private final Handler mHandler;
54     private int mSubId;
55     private String mTag;
56 
57     // ***** Events
58     static final int EVENT_SIM_CARD_STATUS_CHANGED = 1;
59     static final int EVENT_SIM_APP_DATA_CHANGED = 2;
60     static final int EVENT_SIM_INFO_CHANGED = 3;
61 
62     // ***** Cache of modem attributes/status
63     private CardStatus mCardStatus;
64     private ArrayList<SimAppData> mSimAppList;
65 
66     private Carrier[] mCarrierList;
67     private int mCarrierRestrictionStatus = CarrierRestrictions.CarrierRestrictionStatus.UNKNOWN;
68 
69     private int mMultiSimPolicy =
70             android.hardware.radio.sim.SimLockMultiSimPolicy.NO_MULTISIM_POLICY;
71     private CarrierRestrictions mCarrierRestrictionRules;
72 
IRadioSimImpl( MockModemService service, MockModemConfigInterface configInterface, int instanceId)73     public IRadioSimImpl(
74             MockModemService service, MockModemConfigInterface configInterface, int instanceId) {
75         mTag = TAG + "-" + instanceId;
76         Log.d(mTag, "Instantiated");
77 
78         this.mService = service;
79         mMockModemConfigInterface = configInterface;
80         mSubId = instanceId;
81         mCardStatus = new CardStatus();
82         mCacheUpdateMutex = new Object();
83         mHandler = new IRadioSimHandler();
84 
85         // Register events
86         mMockModemConfigInterface.registerForCardStatusChanged(
87                 mSubId, mHandler, EVENT_SIM_CARD_STATUS_CHANGED, null);
88 
89         // Register events
90         mMockModemConfigInterface.registerForSimAppDataChanged(
91                 mSubId, mHandler, EVENT_SIM_APP_DATA_CHANGED, null);
92 
93         // Register events
94         mMockModemConfigInterface.registerForSimInfoChanged(
95                 mSubId, mHandler, EVENT_SIM_INFO_CHANGED, null);
96     }
97 
98     /** Handler class to handle callbacks */
99     private final class IRadioSimHandler extends Handler {
100         @Override
handleMessage(Message msg)101         public void handleMessage(Message msg) {
102             AsyncResult ar;
103             synchronized (mCacheUpdateMutex) {
104                 switch (msg.what) {
105                     case EVENT_SIM_CARD_STATUS_CHANGED:
106                         Log.d(mTag, "Received EVENT_SIM_CARD_STATUS_CHANGED");
107                         ar = (AsyncResult) msg.obj;
108                         if (ar != null && ar.exception == null) {
109                             mCardStatus = (CardStatus) ar.result;
110                             Log.i(mTag, "Sim card status: " + mCardStatus);
111                             simStatusChanged();
112                         } else {
113                             Log.e(mTag, msg.what + " failure. Exception: " + ar.exception);
114                         }
115                         break;
116 
117                     case EVENT_SIM_APP_DATA_CHANGED:
118                         Log.d(mTag, "Received EVENT_SIM_APP_DATA_CHANGED");
119                         ar = (AsyncResult) msg.obj;
120                         if (ar != null && ar.exception == null) {
121                             mSimAppList = (ArrayList<SimAppData>) ar.result;
122                             if (mSimAppList != null) {
123                                 Log.i(mTag, "number of SIM app data: " + mSimAppList.size());
124                             } else {
125                                 Log.e(mTag, "mSimAppList = null");
126                             }
127                         } else {
128                             Log.e(mTag, msg.what + " failure. Exception: " + ar.exception);
129                         }
130                         break;
131 
132                     case EVENT_SIM_INFO_CHANGED:
133                         ar = (AsyncResult) msg.obj;
134                         if (ar != null && ar.exception == null) {
135                             SimInfoChangedResult simInfoChangeResult =
136                                     (SimInfoChangedResult) ar.result;
137                             Log.d(mTag, "Received EVENT_SIM_INFO_CHANGED: " + simInfoChangeResult);
138                             SimRefreshResult simRefreshResult = new SimRefreshResult();
139                             switch (simInfoChangeResult.mSimInfoType) {
140                                 case SimInfoChangedResult.SIM_INFO_TYPE_MCC_MNC:
141                                 case SimInfoChangedResult.SIM_INFO_TYPE_IMSI:
142                                     if (simRefreshResult != null) {
143                                         simRefreshResult.type =
144                                                 SimRefreshResult.TYPE_SIM_FILE_UPDATE;
145                                         simRefreshResult.efId = simInfoChangeResult.mEfId;
146                                         simRefreshResult.aid = simInfoChangeResult.mAid;
147                                         simRefresh(simRefreshResult);
148                                     }
149                                     break;
150                             }
151                         } else {
152                             Log.e(mTag, msg.what + " failure. Exception: " + ar.exception);
153                         }
154                         break;
155                 }
156             }
157         }
158     }
159 
160     // Implementation of IRadioSim functions
161     @Override
setResponseFunctions( IRadioSimResponse radioSimResponse, IRadioSimIndication radioSimIndication)162     public void setResponseFunctions(
163             IRadioSimResponse radioSimResponse, IRadioSimIndication radioSimIndication) {
164         Log.d(mTag, "setResponseFunctions");
165         mRadioSimResponse = radioSimResponse;
166         mRadioSimIndication = radioSimIndication;
167         mService.countDownLatch(MockModemService.LATCH_RADIO_INTERFACES_READY);
168     }
169 
170     @Override
responseAcknowledgement()171     public void responseAcknowledgement() {
172         Log.d(mTag, "responseAcknowledgement");
173         // TODO
174         // acknowledgeRequest(in int serial);
175     }
176 
177     @Override
areUiccApplicationsEnabled(int serial)178     public void areUiccApplicationsEnabled(int serial) {
179         Log.d(mTag, "areUiccApplicationsEnabled");
180 
181         boolean enabled = true;
182 
183         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
184         try {
185             mRadioSimResponse.areUiccApplicationsEnabledResponse(rsp, enabled);
186         } catch (RemoteException ex) {
187             Log.e(mTag, "Failed to areUiccApplicationsEnabled from AIDL. Exception" + ex);
188         }
189     }
190 
191     @Override
changeIccPin2ForApp(int serial, String oldPin2, String newPin2, String aid)192     public void changeIccPin2ForApp(int serial, String oldPin2, String newPin2, String aid) {
193         Log.d(mTag, "changeIccPin2ForApp");
194         // TODO: cache value
195 
196         int remainingRetries = 3;
197 
198         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
199         try {
200             mRadioSimResponse.changeIccPin2ForAppResponse(rsp, remainingRetries);
201         } catch (RemoteException ex) {
202             Log.e(mTag, "Failed to changeIccPin2ForApp from AIDL. Exception" + ex);
203         }
204     }
205 
206     @Override
changeIccPinForApp(int serial, String oldPin, String newPin, String aid)207     public void changeIccPinForApp(int serial, String oldPin, String newPin, String aid) {
208         Log.d(mTag, "changeIccPinForApp");
209         // TODO: cache value
210 
211         int remainingRetries = 3;
212 
213         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
214         try {
215             mRadioSimResponse.changeIccPinForAppResponse(rsp, remainingRetries);
216         } catch (RemoteException ex) {
217             Log.e(mTag, "Failed to changeIccPinForApp from AIDL. Exception" + ex);
218         }
219     }
220 
221     @Override
enableUiccApplications(int serial, boolean enable)222     public void enableUiccApplications(int serial, boolean enable) {
223         Log.d(mTag, "enableUiccApplications");
224         // TODO: cache value
225 
226         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
227         try {
228             mRadioSimResponse.enableUiccApplicationsResponse(rsp);
229         } catch (RemoteException ex) {
230             Log.e(mTag, "Failed to enableUiccApplications from AIDL. Exception" + ex);
231         }
232     }
233 
234     @Override
getAllowedCarriers(int serial)235     public void getAllowedCarriers(int serial) {
236         Log.d(mTag, "getAllowedCarriers");
237         RadioResponseInfo rsp = mService.makeSolRsp(serial);
238         android.hardware.radio.sim.CarrierRestrictions carriers =
239                 new android.hardware.radio.sim.CarrierRestrictions();
240         if (mCarrierList == null || mCarrierList.length < 1) {
241             carriers.allowedCarriers = new Carrier[0];
242         } else {
243             carriers.allowedCarriers = mCarrierList;
244         }
245         carriers.excludedCarriers = new Carrier[0];
246         if (Build.VERSION.SDK_INT > Build.VERSION_CODES.TIRAMISU) {
247             carriers.status = mCarrierRestrictionStatus;
248         }
249         if (Flags.carrierRestrictionRulesEnhancement() && mCarrierRestrictionRules != null) {
250             Log.e(mTag, "Updating carrierInfo information in CarrierRestrictions");
251             carriers.allowedCarrierInfoList = mCarrierRestrictionRules.allowedCarrierInfoList;
252             carriers.excludedCarrierInfoList = mCarrierRestrictionRules.excludedCarrierInfoList;
253         }
254         try {
255             mRadioSimResponse.getAllowedCarriersResponse(rsp, carriers, mMultiSimPolicy);
256         } catch (RemoteException ex) {
257             Log.e(mTag, "Failed to getAllowedCarriers from AIDL. Exception" + ex);
258         } finally {
259             // resetting the mCarrierRestrictionRules
260             mCarrierRestrictionRules = null;
261             mMultiSimPolicy = android.hardware.radio.sim.SimLockMultiSimPolicy.NO_MULTISIM_POLICY;
262         }
263     }
264 
265     @Override
getCdmaSubscription(int serial)266     public void getCdmaSubscription(int serial) {
267         Log.d(mTag, "getCdmaSubscription");
268 
269         String mdn = "";
270         String hSid = "";
271         String hNid = "";
272         String min = "";
273         String prl = "";
274 
275         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
276         try {
277             mRadioSimResponse.getCdmaSubscriptionResponse(rsp, mdn, hSid, hNid, min, prl);
278         } catch (RemoteException ex) {
279             Log.e(mTag, "Failed to getCdmaSubscription from AIDL. Exception" + ex);
280         }
281     }
282 
283     @Override
getCdmaSubscriptionSource(int serial)284     public void getCdmaSubscriptionSource(int serial) {
285         Log.d(mTag, "getCdmaSubscriptionSource");
286 
287         int source = 0; // CdmaSubscriptionSource.RUIM_SIM
288 
289         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
290         try {
291             mRadioSimResponse.getCdmaSubscriptionSourceResponse(rsp, source);
292         } catch (RemoteException ex) {
293             Log.e(mTag, "Failed to getCdmaSubscriptionSource from AIDL. Exception" + ex);
294         }
295     }
296 
297     @Override
getFacilityLockForApp( int serial, String facility, String password, int serviceClass, String appId)298     public void getFacilityLockForApp(
299             int serial, String facility, String password, int serviceClass, String appId) {
300         Log.d(mTag, "getFacilityLockForApp");
301         int numOfSimApp = mSimAppList.size();
302         int responseError = RadioError.NONE;
303         int simAppIdx;
304         boolean isHandled = false;
305         boolean isFacilitySupport = true;
306         int responseData = -1;
307 
308         synchronized (mCacheUpdateMutex) {
309             // TODO: check service class
310             for (simAppIdx = 0;
311                     simAppIdx < numOfSimApp && isFacilitySupport && !isHandled;
312                     simAppIdx++) {
313                 switch (facility) {
314                     case "FD": // FDN status query
315                         if (appId.equals(mSimAppList.get(simAppIdx).getAid())) {
316                             responseData = mSimAppList.get(simAppIdx).getFdnStatus();
317                             isHandled = true;
318                         }
319                         break;
320                     case "SC": // PIN1 status query
321                         if (appId.equals(mSimAppList.get(simAppIdx).getAid())) {
322                             responseData = mSimAppList.get(simAppIdx).getPin1State();
323                             isHandled = true;
324                         }
325                         break;
326                     default:
327                         isFacilitySupport = false;
328                         break;
329                 }
330             }
331         }
332 
333         if (!isHandled) {
334             Log.e(mTag, "Not support sim application aid = " + appId);
335             responseError = RadioError.NO_SUCH_ELEMENT;
336         } else if (!isFacilitySupport) {
337             Log.e(mTag, "Not support facility = " + facility);
338             responseError = RadioError.REQUEST_NOT_SUPPORTED;
339         } else if (responseData == -1) {
340             responseError = RadioError.INTERNAL_ERR;
341         }
342 
343         RadioResponseInfo rsp = mService.makeSolRsp(serial, responseError);
344         try {
345             mRadioSimResponse.getFacilityLockForAppResponse(rsp, responseData);
346         } catch (RemoteException ex) {
347             Log.e(mTag, "Failed to getFacilityLockForApp from AIDL. Exception" + ex);
348         }
349     }
350 
351     @Override
getIccCardStatus(int serial)352     public void getIccCardStatus(int serial) {
353         Log.d(mTag, "getIccCardStatus");
354         CardStatus cardStatus;
355 
356         synchronized (mCacheUpdateMutex) {
357             cardStatus = mCardStatus;
358         }
359 
360         RadioResponseInfo rsp = mService.makeSolRsp(serial);
361         try {
362             mRadioSimResponse.getIccCardStatusResponse(rsp, cardStatus);
363         } catch (RemoteException ex) {
364             Log.e(mTag, "Failed to getIccCardStatus from AIDL. Exception" + ex);
365         }
366     }
367 
368     @Override
getImsiForApp(int serial, String aid)369     public void getImsiForApp(int serial, String aid) {
370         Log.d(mTag, "getImsiForApp");
371         String imsi = "";
372         int numOfSimApp = mSimAppList.size();
373         int responseError = RadioError.NONE;
374         int simAppIdx;
375         boolean isHandled;
376 
377         synchronized (mCacheUpdateMutex) {
378             for (simAppIdx = 0, isHandled = false;
379                     simAppIdx < numOfSimApp && !isHandled;
380                     simAppIdx++) {
381                 if (aid.equals(mSimAppList.get(simAppIdx).getAid())) {
382                     imsi = mSimAppList.get(simAppIdx).getImsi();
383                     isHandled = true;
384                 }
385             }
386         }
387 
388         if (!isHandled) {
389             Log.e(mTag, "Not support sim application aid = " + aid);
390             responseError = RadioError.NO_SUCH_ELEMENT;
391         }
392 
393         RadioResponseInfo rsp = mService.makeSolRsp(serial, responseError);
394         try {
395             mRadioSimResponse.getImsiForAppResponse(rsp, imsi);
396         } catch (RemoteException ex) {
397             Log.e(mTag, "Failed to getImsiForApp from AIDL. Exception" + ex);
398         }
399     }
400 
401     @Override
getSimPhonebookCapacity(int serial)402     public void getSimPhonebookCapacity(int serial) {
403         Log.d(mTag, "getSimPhonebookCapacity");
404 
405         android.hardware.radio.sim.PhonebookCapacity capacity =
406                 new android.hardware.radio.sim.PhonebookCapacity();
407 
408         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
409         try {
410             mRadioSimResponse.getSimPhonebookCapacityResponse(rsp, capacity);
411         } catch (RemoteException ex) {
412             Log.e(mTag, "Failed to getSimPhonebookCapacity from AIDL. Exception" + ex);
413         }
414     }
415 
416     @Override
getSimPhonebookRecords(int serial)417     public void getSimPhonebookRecords(int serial) {
418         Log.d(mTag, "getSimPhonebookRecords");
419 
420         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
421         try {
422             mRadioSimResponse.getSimPhonebookRecordsResponse(rsp);
423         } catch (RemoteException ex) {
424             Log.e(mTag, "Failed to getSimPhonebookRecords from AIDL. Exception" + ex);
425         }
426     }
427 
428     @Override
iccCloseLogicalChannel(int serial, int channelId)429     public void iccCloseLogicalChannel(int serial, int channelId) {
430         Log.d(mTag, "iccCloseLogicalChannel");
431         // TODO: cache value
432 
433         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
434         try {
435             mRadioSimResponse.iccCloseLogicalChannelResponse(rsp);
436         } catch (RemoteException ex) {
437             Log.e(mTag, "Failed to iccCloseLogicalChannel from AIDL. Exception" + ex);
438         }
439     }
440 
441     @Override
iccCloseLogicalChannelWithSessionInfo(int serial, android.hardware.radio.sim.SessionInfo sessionInfo)442     public void iccCloseLogicalChannelWithSessionInfo(int serial,
443             android.hardware.radio.sim.SessionInfo sessionInfo) {
444         Log.d(mTag, "iccCloseLogicalChannelWithSessionInfo");
445         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
446         try {
447             mRadioSimResponse.iccCloseLogicalChannelWithSessionInfoResponse(rsp);
448         } catch (RemoteException ex) {
449             Log.e(mTag,
450                     "Failed to iccCloseLogicalChannelWithSessionInfo from AIDL. Exception" + ex);
451         }
452     }
453 
encodeBcdString(String str)454     private String encodeBcdString(String str) {
455         StringBuffer bcdString = new StringBuffer();
456 
457         if (str.length() % 2 != 0) {
458             Log.d(mTag, "Invalid string(" + str + ") for Bcd format");
459             return "";
460         }
461 
462         for (int i = 0; i < str.length(); i += 2) {
463             bcdString.append(str.substring(i + 1, i + 2));
464             bcdString.append(str.substring(i, i + 1));
465         }
466 
467         return bcdString.toString();
468     }
469 
getIccIoResult( android.hardware.radio.sim.IccIoResult iccIoResult, int command, int fileId, String path, int p1, int p2, int p3, String aid)470     private int getIccIoResult(
471             android.hardware.radio.sim.IccIoResult iccIoResult,
472             int command,
473             int fileId,
474             String path,
475             int p1,
476             int p2,
477             int p3,
478             String aid) {
479         int numOfSimApp = mSimAppList.size();
480         int simAppIdx;
481         boolean foundAid;
482         int responseError = RadioError.GENERIC_FAILURE;
483 
484         if (iccIoResult == null) {
485             return responseError;
486         }
487 
488         synchronized (mCacheUpdateMutex) {
489             for (simAppIdx = 0, foundAid = false; simAppIdx < numOfSimApp; simAppIdx++) {
490                 if (aid.equals(mSimAppList.get(simAppIdx).getAid())) {
491                     foundAid = true;
492                     break;
493                 }
494             }
495 
496             if (!foundAid) {
497                 Log.e(mTag, "Not support sim application aid = " + aid);
498                 iccIoResult.sw1 = 0x6A;
499                 iccIoResult.sw2 = 0x82;
500             } else {
501                 switch (fileId) {
502                     case EF_ICCID:
503                         if (command == COMMAND_READ_BINARY) {
504                             String bcdIccid =
505                                     encodeBcdString(mSimAppList.get(simAppIdx).getIccid());
506                             iccIoResult.simResponse = bcdIccid;
507                             Log.d(mTag, "Get IccIo result: ICCID = " + iccIoResult.simResponse);
508                             iccIoResult.sw1 = 0x90;
509                             responseError = RadioError.NONE;
510                         } else if (command == COMMAND_GET_RESPONSE) {
511                             iccIoResult.simResponse = mSimAppList.get(simAppIdx).getIccidInfo();
512                             Log.d(mTag, "Get IccIo result: ICCID = " + iccIoResult.simResponse);
513                             iccIoResult.sw1 = 0x90;
514                             responseError = RadioError.NONE;
515                         } else {
516                             Log.d(
517                                     mTag,
518                                     "Command("
519                                             + command
520                                             + ") not support for file id = 0x"
521                                             + Integer.toHexString(fileId));
522                             iccIoResult.sw1 = 0x6A;
523                             iccIoResult.sw2 = 0x82;
524                         }
525                         break;
526                     case EF_GID1:
527                         if (command == COMMAND_READ_BINARY) {
528                             String gid1 = mSimAppList.get(simAppIdx).getGid1();
529                             if (gid1 != null) {
530                                 iccIoResult.simResponse = gid1;
531                                 Log.d(
532                                         mTag,
533                                         "COMMAND_READ_BINARY result: GID1 = "
534                                                 + iccIoResult.simResponse);
535                                 iccIoResult.sw1 = 0x90;
536                                 iccIoResult.sw2 = 0x00;
537                                 responseError = RadioError.NONE;
538                             } else {
539                                 Log.d(mTag, "No COMMAND_READ_BINARY result for GID1");
540                                 iccIoResult.sw1 = 0x6A;
541                                 iccIoResult.sw2 = 0x82;
542                             }
543                         } else if (command == COMMAND_GET_RESPONSE) {
544                             String gid1Info = mSimAppList.get(simAppIdx).getGid1Info();
545                             if (gid1Info != null) {
546                                 iccIoResult.simResponse = gid1Info;
547                                 Log.d(
548                                         mTag,
549                                         "COMMAND_GET_RESPONSE result: GID1 = "
550                                                 + iccIoResult.simResponse);
551                                 iccIoResult.sw1 = 0x90;
552                                 iccIoResult.sw2 = 0x00;
553                                 responseError = RadioError.NONE;
554                             } else {
555                                 Log.d(mTag, "No COMMAND_GET_RESPONSE result for GID1");
556                                 iccIoResult.sw1 = 0x6A;
557                                 iccIoResult.sw2 = 0x82;
558                             }
559                         }
560                         break;
561                     default:
562                         Log.d(mTag, "Not find EF file id = 0x" + Integer.toHexString(fileId));
563                         iccIoResult.sw1 = 0x6A;
564                         iccIoResult.sw2 = 0x82;
565                         break;
566                 }
567             }
568         }
569 
570         return responseError;
571     }
572 
573     @Override
iccIoForApp(int serial, android.hardware.radio.sim.IccIo iccIo)574     public void iccIoForApp(int serial, android.hardware.radio.sim.IccIo iccIo) {
575         Log.d(mTag, "iccIoForApp");
576         int responseError = RadioError.NONE;
577         android.hardware.radio.sim.IccIoResult iccIoResult =
578                 new android.hardware.radio.sim.IccIoResult();
579 
580         switch (iccIo.command) {
581             case COMMAND_READ_BINARY:
582             case COMMAND_GET_RESPONSE:
583                 responseError =
584                         getIccIoResult(
585                                 iccIoResult,
586                                 iccIo.command,
587                                 iccIo.fileId,
588                                 iccIo.path,
589                                 iccIo.p1,
590                                 iccIo.p2,
591                                 iccIo.p3,
592                                 iccIo.aid);
593                 break;
594             default:
595                 responseError = RadioError.REQUEST_NOT_SUPPORTED;
596                 break;
597         }
598 
599         RadioResponseInfo rsp = mService.makeSolRsp(serial, responseError);
600         try {
601             mRadioSimResponse.iccIoForAppResponse(rsp, iccIoResult);
602         } catch (RemoteException ex) {
603             Log.e(mTag, "Failed to iccIoForApp from AIDL. Exception" + ex);
604         }
605     }
606 
607     @Override
iccOpenLogicalChannel(int serial, String aid, int p2)608     public void iccOpenLogicalChannel(int serial, String aid, int p2) {
609         Log.d(mTag, "iccOpenLogicalChannel");
610         // TODO: cache value
611         int channelId = 0;
612         byte[] selectResponse = new byte[0];
613 
614         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
615         try {
616             mRadioSimResponse.iccOpenLogicalChannelResponse(rsp, channelId, selectResponse);
617         } catch (RemoteException ex) {
618             Log.e(mTag, "Failed to iccOpenLogicalChannel from AIDL. Exception" + ex);
619         }
620     }
621 
622     @Override
iccTransmitApduBasicChannel( int serial, android.hardware.radio.sim.SimApdu message)623     public void iccTransmitApduBasicChannel(
624             int serial, android.hardware.radio.sim.SimApdu message) {
625         Log.d(mTag, "iccTransmitApduBasicChannel");
626         // TODO: cache value
627         android.hardware.radio.sim.IccIoResult iccIoResult =
628                 new android.hardware.radio.sim.IccIoResult();
629 
630         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
631         try {
632             mRadioSimResponse.iccTransmitApduBasicChannelResponse(rsp, iccIoResult);
633         } catch (RemoteException ex) {
634             Log.e(mTag, "Failed to iccTransmitApduBasicChannel from AIDL. Exception" + ex);
635         }
636     }
637 
638     @Override
iccTransmitApduLogicalChannel( int serial, android.hardware.radio.sim.SimApdu message)639     public void iccTransmitApduLogicalChannel(
640             int serial, android.hardware.radio.sim.SimApdu message) {
641         Log.d(mTag, "iccTransmitApduLogicalChannel");
642         // TODO: cache value
643         android.hardware.radio.sim.IccIoResult iccIoResult =
644                 new android.hardware.radio.sim.IccIoResult();
645 
646         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
647         try {
648             mRadioSimResponse.iccTransmitApduBasicChannelResponse(rsp, iccIoResult);
649         } catch (RemoteException ex) {
650             Log.e(mTag, "Failed to iccTransmitApduLogicalChannel from AIDL. Exception" + ex);
651         }
652     }
653 
654     @Override
reportStkServiceIsRunning(int serial)655     public void reportStkServiceIsRunning(int serial) {
656         Log.d(mTag, "reportStkServiceIsRunning");
657 
658         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
659         try {
660             mRadioSimResponse.reportStkServiceIsRunningResponse(rsp);
661         } catch (RemoteException ex) {
662             Log.e(mTag, "Failed to reportStkServiceIsRunning from AIDL. Exception" + ex);
663         }
664     }
665 
666     @Override
requestIccSimAuthentication( int serial, int authContext, String authData, String aid)667     public void requestIccSimAuthentication(
668             int serial, int authContext, String authData, String aid) {
669         Log.d(mTag, "requestIccSimAuthentication");
670         // TODO: cache value
671         android.hardware.radio.sim.IccIoResult iccIoResult =
672                 new android.hardware.radio.sim.IccIoResult();
673 
674         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
675         try {
676             mRadioSimResponse.requestIccSimAuthenticationResponse(rsp, iccIoResult);
677         } catch (RemoteException ex) {
678             Log.e(mTag, "Failed to requestIccSimAuthentication from AIDL. Exception" + ex);
679         }
680     }
681 
682     @Override
sendEnvelope(int serial, String contents)683     public void sendEnvelope(int serial, String contents) {
684         Log.d(mTag, "sendEnvelope");
685         // TODO: cache value
686         String commandResponse = "";
687 
688         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
689         try {
690             mRadioSimResponse.sendEnvelopeResponse(rsp, commandResponse);
691         } catch (RemoteException ex) {
692             Log.e(mTag, "Failed to sendEnvelope from AIDL. Exception" + ex);
693         }
694     }
695 
696     @Override
sendEnvelopeWithStatus(int serial, String contents)697     public void sendEnvelopeWithStatus(int serial, String contents) {
698         Log.d(mTag, "sendEnvelopeWithStatus");
699         // TODO: cache value
700         android.hardware.radio.sim.IccIoResult iccIoResult =
701                 new android.hardware.radio.sim.IccIoResult();
702 
703         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
704         try {
705             mRadioSimResponse.sendEnvelopeWithStatusResponse(rsp, iccIoResult);
706         } catch (RemoteException ex) {
707             Log.e(mTag, "Failed to sendEnvelopeWithStatus from AIDL. Exception" + ex);
708         }
709     }
710 
711     @Override
sendTerminalResponseToSim(int serial, String contents)712     public void sendTerminalResponseToSim(int serial, String contents) {
713         Log.d(mTag, "sendTerminalResponseToSim");
714         // TODO: cache value
715 
716         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
717         try {
718             mRadioSimResponse.sendTerminalResponseToSimResponse(rsp);
719         } catch (RemoteException ex) {
720             Log.e(mTag, "Failed to sendTerminalResponseToSim from AIDL. Exception" + ex);
721         }
722     }
723 
724     @Override
setAllowedCarriers( int serial, android.hardware.radio.sim.CarrierRestrictions carriers, int multiSimPolicy)725     public void setAllowedCarriers(
726             int serial,
727             android.hardware.radio.sim.CarrierRestrictions carriers,
728             int multiSimPolicy) {
729         Log.d(mTag, "sendTerminalResponseToSim");
730         // TODO: cache value
731 
732         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
733         try {
734             mRadioSimResponse.setAllowedCarriersResponse(rsp);
735         } catch (RemoteException ex) {
736             Log.e(mTag, "Failed to setAllowedCarriers from AIDL. Exception" + ex);
737         }
738     }
739 
740     @Override
setCarrierInfoForImsiEncryption( int serial, android.hardware.radio.sim.ImsiEncryptionInfo imsiEncryptionInfo)741     public void setCarrierInfoForImsiEncryption(
742             int serial, android.hardware.radio.sim.ImsiEncryptionInfo imsiEncryptionInfo) {
743         Log.d(mTag, "setCarrierInfoForImsiEncryption");
744         // TODO: cache value
745 
746         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
747         try {
748             mRadioSimResponse.setCarrierInfoForImsiEncryptionResponse(rsp);
749         } catch (RemoteException ex) {
750             Log.e(mTag, "Failed to setCarrierInfoForImsiEncryption from AIDL. Exception" + ex);
751         }
752     }
753 
754     @Override
setCdmaSubscriptionSource(int serial, int cdmaSub)755     public void setCdmaSubscriptionSource(int serial, int cdmaSub) {
756         Log.d(mTag, "setCdmaSubscriptionSource");
757         // TODO: cache value
758 
759         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
760         try {
761             mRadioSimResponse.setCdmaSubscriptionSourceResponse(rsp);
762         } catch (RemoteException ex) {
763             Log.e(mTag, "Failed to setCdmaSubscriptionSource from AIDL. Exception" + ex);
764         }
765     }
766 
767     @Override
setFacilityLockForApp( int serial, String facility, boolean lockState, String password, int serviceClass, String appId)768     public void setFacilityLockForApp(
769             int serial,
770             String facility,
771             boolean lockState,
772             String password,
773             int serviceClass,
774             String appId) {
775         Log.d(mTag, "setFacilityLockForApp");
776         // TODO: cache value
777         int retry = 10;
778 
779         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
780         try {
781             mRadioSimResponse.setFacilityLockForAppResponse(rsp, retry);
782         } catch (RemoteException ex) {
783             Log.e(mTag, "Failed to setFacilityLockForApp from AIDL. Exception" + ex);
784         }
785     }
786 
787     @Override
setSimCardPower(int serial, int powerUp)788     public void setSimCardPower(int serial, int powerUp) {
789         Log.d(mTag, "setSimCardPower");
790         // TODO: cache value
791 
792         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
793         try {
794             mRadioSimResponse.setSimCardPowerResponse(rsp);
795         } catch (RemoteException ex) {
796             Log.e(mTag, "Failed to setSimCardPower from AIDL. Exception" + ex);
797         }
798     }
799 
800     @Override
setUiccSubscription(int serial, android.hardware.radio.sim.SelectUiccSub uiccSub)801     public void setUiccSubscription(int serial, android.hardware.radio.sim.SelectUiccSub uiccSub) {
802         Log.d(mTag, "setUiccSubscription");
803         // TODO: cache value
804 
805         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
806         try {
807             mRadioSimResponse.setUiccSubscriptionResponse(rsp);
808         } catch (RemoteException ex) {
809             Log.e(mTag, "Failed to setUiccSubscription from AIDL. Exception" + ex);
810         }
811     }
812 
813     @Override
supplyIccPin2ForApp(int serial, String pin2, String aid)814     public void supplyIccPin2ForApp(int serial, String pin2, String aid) {
815         Log.d(mTag, "supplyIccPin2ForApp");
816         // TODO: cache value
817         int setFacilityLockForApp = 10;
818 
819         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
820         try {
821             mRadioSimResponse.supplyIccPin2ForAppResponse(rsp, setFacilityLockForApp);
822         } catch (RemoteException ex) {
823             Log.e(mTag, "Failed to supplyIccPin2ForApp from AIDL. Exception" + ex);
824         }
825     }
826 
827     @Override
supplyIccPinForApp(int serial, String pin, String aid)828     public void supplyIccPinForApp(int serial, String pin, String aid) {
829         Log.d(mTag, "supplyIccPinForApp");
830         // TODO: cache value
831         int setFacilityLockForApp = 10;
832 
833         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
834         try {
835             mRadioSimResponse.supplyIccPinForAppResponse(rsp, setFacilityLockForApp);
836         } catch (RemoteException ex) {
837             Log.e(mTag, "Failed to supplyIccPinForApp from AIDL. Exception" + ex);
838         }
839     }
840 
841     @Override
supplyIccPuk2ForApp(int serial, String puk2, String pin2, String aid)842     public void supplyIccPuk2ForApp(int serial, String puk2, String pin2, String aid) {
843         Log.d(mTag, "supplyIccPuk2ForApp");
844         // TODO: cache value
845         int setFacilityLockForApp = 10;
846 
847         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
848         try {
849             mRadioSimResponse.supplyIccPuk2ForAppResponse(rsp, setFacilityLockForApp);
850         } catch (RemoteException ex) {
851             Log.e(mTag, "Failed to supplyIccPuk2ForApp from AIDL. Exception" + ex);
852         }
853     }
854 
855     @Override
supplyIccPukForApp(int serial, String puk, String pin, String aid)856     public void supplyIccPukForApp(int serial, String puk, String pin, String aid) {
857         Log.d(mTag, "supplyIccPukForApp");
858         // TODO: cache value
859         int setFacilityLockForApp = 10;
860 
861         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
862         try {
863             mRadioSimResponse.supplyIccPukForAppResponse(rsp, setFacilityLockForApp);
864         } catch (RemoteException ex) {
865             Log.e(mTag, "Failed to supplyIccPukForApp from AIDL. Exception" + ex);
866         }
867     }
868 
869     @Override
supplySimDepersonalization(int serial, int persoType, String controlKey)870     public void supplySimDepersonalization(int serial, int persoType, String controlKey) {
871         Log.d(mTag, "supplySimDepersonalization");
872         // TODO: cache value
873         int retPersoType = persoType;
874         int setFacilityLockForApp = 10;
875 
876         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
877         try {
878             mRadioSimResponse.supplySimDepersonalizationResponse(
879                     rsp, retPersoType, setFacilityLockForApp);
880         } catch (RemoteException ex) {
881             Log.e(mTag, "Failed to supplySimDepersonalization from AIDL. Exception" + ex);
882         }
883     }
884 
885     @Override
updateSimPhonebookRecords( int serial, android.hardware.radio.sim.PhonebookRecordInfo recordInfo)886     public void updateSimPhonebookRecords(
887             int serial, android.hardware.radio.sim.PhonebookRecordInfo recordInfo) {
888         Log.d(mTag, "updateSimPhonebookRecords");
889         // TODO: cache value
890         int updatedRecordIndex = 0;
891 
892         RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
893         try {
894             mRadioSimResponse.updateSimPhonebookRecordsResponse(rsp, updatedRecordIndex);
895         } catch (RemoteException ex) {
896             Log.e(mTag, "Failed to updateSimPhonebookRecords from AIDL. Exception" + ex);
897         }
898     }
899 
carrierInfoForImsiEncryption()900     public void carrierInfoForImsiEncryption() {
901         Log.d(mTag, "carrierInfoForImsiEncryption");
902 
903         if (mRadioSimIndication != null) {
904             try {
905                 mRadioSimIndication.carrierInfoForImsiEncryption(RadioIndicationType.UNSOLICITED);
906             } catch (RemoteException ex) {
907                 Log.e(mTag, "Failed to carrierInfoForImsiEncryption from AIDL. Exception" + ex);
908             }
909         } else {
910             Log.e(mTag, "null mRadioSimIndication");
911         }
912     }
913 
cdmaSubscriptionSourceChanged(int cdmaSource)914     public void cdmaSubscriptionSourceChanged(int cdmaSource) {
915         Log.d(mTag, "carrierInfoForImsiEncryption");
916 
917         if (mRadioSimIndication != null) {
918             try {
919                 mRadioSimIndication.cdmaSubscriptionSourceChanged(
920                         RadioIndicationType.UNSOLICITED, cdmaSource);
921             } catch (RemoteException ex) {
922                 Log.e(mTag, "Failed to cdmaSubscriptionSourceChanged from AIDL. Exception" + ex);
923             }
924         } else {
925             Log.e(mTag, "null mRadioSimIndication");
926         }
927     }
928 
simPhonebookChanged()929     public void simPhonebookChanged() {
930         Log.d(mTag, "simPhonebookChanged");
931 
932         if (mRadioSimIndication != null) {
933             try {
934                 mRadioSimIndication.simPhonebookChanged(RadioIndicationType.UNSOLICITED);
935             } catch (RemoteException ex) {
936                 Log.e(mTag, "Failed to simPhonebookChanged from AIDL. Exception" + ex);
937             }
938         } else {
939             Log.e(mTag, "null mRadioSimIndication");
940         }
941     }
942 
simPhonebookRecordsReceived( byte status, android.hardware.radio.sim.PhonebookRecordInfo[] records)943     public void simPhonebookRecordsReceived(
944             byte status, android.hardware.radio.sim.PhonebookRecordInfo[] records) {
945         Log.d(mTag, "simPhonebookRecordsReceived");
946 
947         if (mRadioSimIndication != null) {
948             try {
949                 mRadioSimIndication.simPhonebookRecordsReceived(
950                         RadioIndicationType.UNSOLICITED, status, records);
951             } catch (RemoteException ex) {
952                 Log.e(mTag, "Failed to simPhonebookRecordsReceived from AIDL. Exception" + ex);
953             }
954         } else {
955             Log.e(mTag, "null mRadioSimIndication");
956         }
957     }
958 
simRefresh(SimRefreshResult refreshResult)959     public void simRefresh(SimRefreshResult refreshResult) {
960         Log.d(mTag, "simRefresh");
961 
962         if (mRadioSimIndication != null) {
963             try {
964                 mRadioSimIndication.simRefresh(RadioIndicationType.UNSOLICITED, refreshResult);
965             } catch (RemoteException ex) {
966                 Log.e(mTag, "Failed to simRefresh from AIDL. Exception" + ex);
967             }
968         } else {
969             Log.e(mTag, "null mRadioSimIndication");
970         }
971     }
972 
simStatusChanged()973     public void simStatusChanged() {
974         Log.d(mTag, "simStatusChanged");
975 
976         if (mRadioSimIndication != null) {
977             try {
978                 mRadioSimIndication.simStatusChanged(RadioIndicationType.UNSOLICITED);
979             } catch (RemoteException ex) {
980                 Log.e(mTag, "Failed to simStatusChanged from AIDL. Exception" + ex);
981             }
982         } else {
983             Log.e(mTag, "null mRadioSimIndication");
984         }
985     }
986 
stkEventNotify(String cmd)987     public void stkEventNotify(String cmd) {
988         Log.d(mTag, "stkEventNotify");
989 
990         if (mRadioSimIndication != null) {
991             try {
992                 mRadioSimIndication.stkEventNotify(RadioIndicationType.UNSOLICITED, cmd);
993             } catch (RemoteException ex) {
994                 Log.e(mTag, "Failed to stkEventNotify from AIDL. Exception" + ex);
995             }
996         } else {
997             Log.e(mTag, "null mRadioSimIndication");
998         }
999     }
1000 
stkProactiveCommand(String cmd)1001     public void stkProactiveCommand(String cmd) {
1002         Log.d(mTag, "stkProactiveCommand");
1003 
1004         if (mRadioSimIndication != null) {
1005             try {
1006                 mRadioSimIndication.stkProactiveCommand(RadioIndicationType.UNSOLICITED, cmd);
1007             } catch (RemoteException ex) {
1008                 Log.e(mTag, "Failed to stkProactiveCommand from AIDL. Exception" + ex);
1009             }
1010         } else {
1011             Log.e(mTag, "null mRadioSimIndication");
1012         }
1013     }
1014 
stkSessionEnd()1015     public void stkSessionEnd() {
1016         Log.d(mTag, "stkSessionEnd");
1017 
1018         if (mRadioSimIndication != null) {
1019             try {
1020                 mRadioSimIndication.stkSessionEnd(RadioIndicationType.UNSOLICITED);
1021             } catch (RemoteException ex) {
1022                 Log.e(mTag, "Failed to stkSessionEnd from AIDL. Exception" + ex);
1023             }
1024         } else {
1025             Log.e(mTag, "null mRadioSimIndication");
1026         }
1027     }
1028 
subscriptionStatusChanged(boolean activate)1029     public void subscriptionStatusChanged(boolean activate) {
1030         Log.d(mTag, "subscriptionStatusChanged");
1031 
1032         if (mRadioSimIndication != null) {
1033             try {
1034                 mRadioSimIndication.subscriptionStatusChanged(
1035                         RadioIndicationType.UNSOLICITED, activate);
1036             } catch (RemoteException ex) {
1037                 Log.e(mTag, "Failed to subscriptionStatusChanged from AIDL. Exception" + ex);
1038             }
1039         } else {
1040             Log.e(mTag, "null mRadioSimIndication");
1041         }
1042     }
1043 
uiccApplicationsEnablementChanged(boolean enabled)1044     public void uiccApplicationsEnablementChanged(boolean enabled) {
1045         Log.d(mTag, "uiccApplicationsEnablementChanged");
1046 
1047         if (mRadioSimIndication != null) {
1048             try {
1049                 mRadioSimIndication.uiccApplicationsEnablementChanged(
1050                         RadioIndicationType.UNSOLICITED, enabled);
1051             } catch (RemoteException ex) {
1052                 Log.e(
1053                         mTag,
1054                         "Failed to uiccApplicationsEnablementChanged from AIDL. Exception" + ex);
1055             }
1056         } else {
1057             Log.e(mTag, "null mRadioSimIndication");
1058         }
1059     }
1060 
1061     @Override
getInterfaceHash()1062     public String getInterfaceHash() {
1063         return IRadioSim.HASH;
1064     }
1065 
1066     @Override
getInterfaceVersion()1067     public int getInterfaceVersion() {
1068         return IRadioSim.VERSION;
1069     }
1070 
updateCarrierRestrictionStatusInfo( Carrier[] carrierList, int carrierRestrictionStatus)1071     public void updateCarrierRestrictionStatusInfo(
1072             Carrier[] carrierList, int carrierRestrictionStatus) {
1073         mCarrierList = carrierList;
1074         mCarrierRestrictionStatus = carrierRestrictionStatus;
1075     }
1076 
updateCarrierRestrictionRules(CarrierRestrictions carrierRestrictionRules, int multiSimPolicy)1077     public void updateCarrierRestrictionRules(CarrierRestrictions carrierRestrictionRules,
1078             int multiSimPolicy) {
1079         Log.d(mTag, "updateCarrierRestrictionRules");
1080         mCarrierRestrictionRules = carrierRestrictionRules;
1081         mMultiSimPolicy = multiSimPolicy;
1082     }
1083 }
1084