Telephony: Define enable/disable APIs for Cdma CMAS
[android/platform/frameworks/opt/telephony.git] / src / java / com / android / internal / telephony / test / SimulatedCommands.java
1 /*
2  * Copyright (C) 2006 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 com.android.internal.telephony.test;
18
19 import android.os.AsyncResult;
20 import android.os.HandlerThread;
21 import android.os.Looper;
22 import android.os.Message;
23 import android.telephony.Rlog;
24
25 import com.android.internal.telephony.BaseCommands;
26 import com.android.internal.telephony.CommandException;
27 import com.android.internal.telephony.CommandsInterface;
28 import com.android.internal.telephony.DataCallState;
29 import com.android.internal.telephony.Phone;
30 import com.android.internal.telephony.UUSInfo;
31 import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
32 import com.android.internal.telephony.gsm.CallFailCause;
33 import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
34 import com.android.internal.telephony.gsm.SuppServiceNotification;
35
36 import java.util.ArrayList;
37
38 public final class SimulatedCommands extends BaseCommands
39         implements CommandsInterface, SimulatedRadioControl {
40     private final static String LOG_TAG = "SIM";
41
42     private enum SimLockState {
43         NONE,
44         REQUIRE_PIN,
45         REQUIRE_PUK,
46         SIM_PERM_LOCKED
47     }
48
49     private enum SimFdnState {
50         NONE,
51         REQUIRE_PIN2,
52         REQUIRE_PUK2,
53         SIM_PERM_LOCKED
54     }
55
56     private final static SimLockState INITIAL_LOCK_STATE = SimLockState.NONE;
57     private final static String DEFAULT_SIM_PIN_CODE = "1234";
58     private final static String SIM_PUK_CODE = "12345678";
59     private final static SimFdnState INITIAL_FDN_STATE = SimFdnState.NONE;
60     private final static String DEFAULT_SIM_PIN2_CODE = "5678";
61     private final static String SIM_PUK2_CODE = "87654321";
62
63     //***** Instance Variables
64
65     SimulatedGsmCallState simulatedCallState;
66     HandlerThread mHandlerThread;
67     SimLockState mSimLockedState;
68     boolean mSimLockEnabled;
69     int mPinUnlockAttempts;
70     int mPukUnlockAttempts;
71     String mPinCode;
72     SimFdnState mSimFdnEnabledState;
73     boolean mSimFdnEnabled;
74     int mPin2UnlockAttempts;
75     int mPuk2UnlockAttempts;
76     int mNetworkType;
77     String mPin2Code;
78     boolean mSsnNotifyOn = false;
79
80     int pausedResponseCount;
81     ArrayList<Message> pausedResponses = new ArrayList<Message>();
82
83     int nextCallFailCause = CallFailCause.NORMAL_CLEARING;
84
85     //***** Constructor
86
87     public
88     SimulatedCommands() {
89         super(null);  // Don't log statistics
90         mHandlerThread = new HandlerThread("SimulatedCommands");
91         mHandlerThread.start();
92         Looper looper = mHandlerThread.getLooper();
93
94         simulatedCallState = new SimulatedGsmCallState(looper);
95
96         setRadioState(RadioState.RADIO_OFF);
97         mSimLockedState = INITIAL_LOCK_STATE;
98         mSimLockEnabled = (mSimLockedState != SimLockState.NONE);
99         mPinCode = DEFAULT_SIM_PIN_CODE;
100         mSimFdnEnabledState = INITIAL_FDN_STATE;
101         mSimFdnEnabled = (mSimFdnEnabledState != SimFdnState.NONE);
102         mPin2Code = DEFAULT_SIM_PIN2_CODE;
103     }
104
105     //***** CommandsInterface implementation
106
107     public void getIccCardStatus(Message result) {
108         unimplemented(result);
109     }
110
111     public void supplyIccPin(String pin, Message result)  {
112         if (mSimLockedState != SimLockState.REQUIRE_PIN) {
113             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPin: wrong state, state=" +
114                     mSimLockedState);
115             CommandException ex = new CommandException(
116                     CommandException.Error.PASSWORD_INCORRECT);
117             AsyncResult.forMessage(result, null, ex);
118             result.sendToTarget();
119             return;
120         }
121
122         if (pin != null && pin.equals(mPinCode)) {
123             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPin: success!");
124             mPinUnlockAttempts = 0;
125             mSimLockedState = SimLockState.NONE;
126             mIccStatusChangedRegistrants.notifyRegistrants();
127
128             if (result != null) {
129                 AsyncResult.forMessage(result, null, null);
130                 result.sendToTarget();
131             }
132
133             return;
134         }
135
136         if (result != null) {
137             mPinUnlockAttempts ++;
138
139             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPin: failed! attempt=" +
140                     mPinUnlockAttempts);
141             if (mPinUnlockAttempts >= 3) {
142                 Rlog.i(LOG_TAG, "[SimCmd] supplyIccPin: set state to REQUIRE_PUK");
143                 mSimLockedState = SimLockState.REQUIRE_PUK;
144             }
145
146             CommandException ex = new CommandException(
147                     CommandException.Error.PASSWORD_INCORRECT);
148             AsyncResult.forMessage(result, null, ex);
149             result.sendToTarget();
150         }
151     }
152
153     public void supplyIccPuk(String puk, String newPin, Message result)  {
154         if (mSimLockedState != SimLockState.REQUIRE_PUK) {
155             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPuk: wrong state, state=" +
156                     mSimLockedState);
157             CommandException ex = new CommandException(
158                     CommandException.Error.PASSWORD_INCORRECT);
159             AsyncResult.forMessage(result, null, ex);
160             result.sendToTarget();
161             return;
162         }
163
164         if (puk != null && puk.equals(SIM_PUK_CODE)) {
165             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPuk: success!");
166             mSimLockedState = SimLockState.NONE;
167             mPukUnlockAttempts = 0;
168             mIccStatusChangedRegistrants.notifyRegistrants();
169
170             if (result != null) {
171                 AsyncResult.forMessage(result, null, null);
172                 result.sendToTarget();
173             }
174
175             return;
176         }
177
178         if (result != null) {
179             mPukUnlockAttempts ++;
180
181             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPuk: failed! attempt=" +
182                     mPukUnlockAttempts);
183             if (mPukUnlockAttempts >= 10) {
184                 Rlog.i(LOG_TAG, "[SimCmd] supplyIccPuk: set state to SIM_PERM_LOCKED");
185                 mSimLockedState = SimLockState.SIM_PERM_LOCKED;
186             }
187
188             CommandException ex = new CommandException(
189                     CommandException.Error.PASSWORD_INCORRECT);
190             AsyncResult.forMessage(result, null, ex);
191             result.sendToTarget();
192         }
193     }
194
195     public void supplyIccPin2(String pin2, Message result)  {
196         if (mSimFdnEnabledState != SimFdnState.REQUIRE_PIN2) {
197             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPin2: wrong state, state=" +
198                     mSimFdnEnabledState);
199             CommandException ex = new CommandException(
200                     CommandException.Error.PASSWORD_INCORRECT);
201             AsyncResult.forMessage(result, null, ex);
202             result.sendToTarget();
203             return;
204         }
205
206         if (pin2 != null && pin2.equals(mPin2Code)) {
207             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPin2: success!");
208             mPin2UnlockAttempts = 0;
209             mSimFdnEnabledState = SimFdnState.NONE;
210
211             if (result != null) {
212                 AsyncResult.forMessage(result, null, null);
213                 result.sendToTarget();
214             }
215
216             return;
217         }
218
219         if (result != null) {
220             mPin2UnlockAttempts ++;
221
222             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPin2: failed! attempt=" +
223                     mPin2UnlockAttempts);
224             if (mPin2UnlockAttempts >= 3) {
225                 Rlog.i(LOG_TAG, "[SimCmd] supplyIccPin2: set state to REQUIRE_PUK2");
226                 mSimFdnEnabledState = SimFdnState.REQUIRE_PUK2;
227             }
228
229             CommandException ex = new CommandException(
230                     CommandException.Error.PASSWORD_INCORRECT);
231             AsyncResult.forMessage(result, null, ex);
232             result.sendToTarget();
233         }
234     }
235
236     public void supplyIccPuk2(String puk2, String newPin2, Message result)  {
237         if (mSimFdnEnabledState != SimFdnState.REQUIRE_PUK2) {
238             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPuk2: wrong state, state=" +
239                     mSimLockedState);
240             CommandException ex = new CommandException(
241                     CommandException.Error.PASSWORD_INCORRECT);
242             AsyncResult.forMessage(result, null, ex);
243             result.sendToTarget();
244             return;
245         }
246
247         if (puk2 != null && puk2.equals(SIM_PUK2_CODE)) {
248             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPuk2: success!");
249             mSimFdnEnabledState = SimFdnState.NONE;
250             mPuk2UnlockAttempts = 0;
251
252             if (result != null) {
253                 AsyncResult.forMessage(result, null, null);
254                 result.sendToTarget();
255             }
256
257             return;
258         }
259
260         if (result != null) {
261             mPuk2UnlockAttempts ++;
262
263             Rlog.i(LOG_TAG, "[SimCmd] supplyIccPuk2: failed! attempt=" +
264                     mPuk2UnlockAttempts);
265             if (mPuk2UnlockAttempts >= 10) {
266                 Rlog.i(LOG_TAG, "[SimCmd] supplyIccPuk2: set state to SIM_PERM_LOCKED");
267                 mSimFdnEnabledState = SimFdnState.SIM_PERM_LOCKED;
268             }
269
270             CommandException ex = new CommandException(
271                     CommandException.Error.PASSWORD_INCORRECT);
272             AsyncResult.forMessage(result, null, ex);
273             result.sendToTarget();
274         }
275     }
276
277     public void changeIccPin(String oldPin, String newPin, Message result)  {
278         if (oldPin != null && oldPin.equals(mPinCode)) {
279             mPinCode = newPin;
280             if (result != null) {
281                 AsyncResult.forMessage(result, null, null);
282                 result.sendToTarget();
283             }
284
285             return;
286         }
287
288         if (result != null) {
289             Rlog.i(LOG_TAG, "[SimCmd] changeIccPin: pin failed!");
290
291             CommandException ex = new CommandException(
292                     CommandException.Error.PASSWORD_INCORRECT);
293             AsyncResult.forMessage(result, null, ex);
294             result.sendToTarget();
295         }
296     }
297
298     public void changeIccPin2(String oldPin2, String newPin2, Message result)  {
299         if (oldPin2 != null && oldPin2.equals(mPin2Code)) {
300             mPin2Code = newPin2;
301             if (result != null) {
302                 AsyncResult.forMessage(result, null, null);
303                 result.sendToTarget();
304             }
305
306             return;
307         }
308
309         if (result != null) {
310             Rlog.i(LOG_TAG, "[SimCmd] changeIccPin2: pin2 failed!");
311
312             CommandException ex = new CommandException(
313                     CommandException.Error.PASSWORD_INCORRECT);
314             AsyncResult.forMessage(result, null, ex);
315             result.sendToTarget();
316         }
317     }
318
319     public void
320     changeBarringPassword(String facility, String oldPwd, String newPwd, Message result) {
321         unimplemented(result);
322     }
323
324     public void
325     setSuppServiceNotifications(boolean enable, Message result) {
326         resultSuccess(result, null);
327
328         if (enable && mSsnNotifyOn) {
329             Rlog.w(LOG_TAG, "Supp Service Notifications already enabled!");
330         }
331
332         mSsnNotifyOn = enable;
333     }
334
335     @Override
336     public void queryFacilityLock(String facility, String pin,
337                                    int serviceClass, Message result) {
338         queryFacilityLockForApp(facility, pin, serviceClass, null, result);
339     }
340
341     @Override
342     public void queryFacilityLockForApp(String facility, String pin, int serviceClass,
343             String appId, Message result) {
344         if (facility != null && facility.equals(CommandsInterface.CB_FACILITY_BA_SIM)) {
345             if (result != null) {
346                 int[] r = new int[1];
347                 r[0] = (mSimLockEnabled ? 1 : 0);
348                 Rlog.i(LOG_TAG, "[SimCmd] queryFacilityLock: SIM is "
349                         + (r[0] == 0 ? "unlocked" : "locked"));
350                 AsyncResult.forMessage(result, r, null);
351                 result.sendToTarget();
352             }
353             return;
354         } else if (facility != null && facility.equals(CommandsInterface.CB_FACILITY_BA_FD)) {
355             if (result != null) {
356                 int[] r = new int[1];
357                 r[0] = (mSimFdnEnabled ? 1 : 0);
358                 Rlog.i(LOG_TAG, "[SimCmd] queryFacilityLock: FDN is "
359                         + (r[0] == 0 ? "disabled" : "enabled"));
360                 AsyncResult.forMessage(result, r, null);
361                 result.sendToTarget();
362             }
363             return;
364         }
365
366         unimplemented(result);
367     }
368
369     @Override
370     public void setFacilityLock(String facility, boolean lockEnabled, String pin, int serviceClass,
371             Message result) {
372         setFacilityLockForApp(facility, lockEnabled, pin, serviceClass, null, result);
373     }
374
375     @Override
376     public void setFacilityLockForApp(String facility, boolean lockEnabled,
377                                  String pin, int serviceClass, String appId,
378                                  Message result) {
379         if (facility != null &&
380                 facility.equals(CommandsInterface.CB_FACILITY_BA_SIM)) {
381             if (pin != null && pin.equals(mPinCode)) {
382                 Rlog.i(LOG_TAG, "[SimCmd] setFacilityLock: pin is valid");
383                 mSimLockEnabled = lockEnabled;
384
385                 if (result != null) {
386                     AsyncResult.forMessage(result, null, null);
387                     result.sendToTarget();
388                 }
389
390                 return;
391             }
392
393             if (result != null) {
394                 Rlog.i(LOG_TAG, "[SimCmd] setFacilityLock: pin failed!");
395
396                 CommandException ex = new CommandException(
397                         CommandException.Error.GENERIC_FAILURE);
398                 AsyncResult.forMessage(result, null, ex);
399                 result.sendToTarget();
400             }
401
402             return;
403         }  else if (facility != null &&
404                 facility.equals(CommandsInterface.CB_FACILITY_BA_FD)) {
405             if (pin != null && pin.equals(mPin2Code)) {
406                 Rlog.i(LOG_TAG, "[SimCmd] setFacilityLock: pin2 is valid");
407                 mSimFdnEnabled = lockEnabled;
408
409                 if (result != null) {
410                     AsyncResult.forMessage(result, null, null);
411                     result.sendToTarget();
412                 }
413
414                 return;
415             }
416
417             if (result != null) {
418                 Rlog.i(LOG_TAG, "[SimCmd] setFacilityLock: pin2 failed!");
419
420                 CommandException ex = new CommandException(
421                         CommandException.Error.GENERIC_FAILURE);
422                 AsyncResult.forMessage(result, null, ex);
423                 result.sendToTarget();
424             }
425
426             return;
427         }
428
429         unimplemented(result);
430     }
431
432     public void supplyNetworkDepersonalization(String netpin, Message result)  {
433         unimplemented(result);
434     }
435
436     /**
437      *  returned message
438      *  retMsg.obj = AsyncResult ar
439      *  ar.exception carries exception on failure
440      *  ar.userObject contains the original value of result.obj
441      *  ar.result contains a List of DriverCall
442      *      The ar.result List is sorted by DriverCall.index
443      */
444     public void getCurrentCalls (Message result) {
445         if ((mState == RadioState.RADIO_ON) && !isSimLocked()) {
446             //Rlog.i("GSM", "[SimCmds] getCurrentCalls");
447             resultSuccess(result, simulatedCallState.getDriverCalls());
448         } else {
449             //Rlog.i("GSM", "[SimCmds] getCurrentCalls: RADIO_OFF or SIM not ready!");
450             resultFail(result,
451                 new CommandException(
452                     CommandException.Error.RADIO_NOT_AVAILABLE));
453         }
454     }
455
456     /**
457      *  @deprecated
458      */
459     public void getPDPContextList(Message result) {
460         getDataCallList(result);
461     }
462
463     /**
464      *  returned message
465      *  retMsg.obj = AsyncResult ar
466      *  ar.exception carries exception on failure
467      *  ar.userObject contains the original value of result.obj
468      *  ar.result contains a List of DataCallState
469      */
470     public void getDataCallList(Message result) {
471         resultSuccess(result, new ArrayList<DataCallState>(0));
472     }
473
474     /**
475      *  returned message
476      *  retMsg.obj = AsyncResult ar
477      *  ar.exception carries exception on failure
478      *  ar.userObject contains the original value of result.obj
479      *  ar.result is null on success and failure
480      *
481      * CLIR_DEFAULT     == on "use subscription default value"
482      * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation)
483      * CLIR_INVOCATION  == on "CLIR invocation" (restrict CLI presentation)
484      */
485     public void dial (String address, int clirMode, Message result) {
486         simulatedCallState.onDial(address);
487
488         resultSuccess(result, null);
489     }
490
491     /**
492      *  returned message
493      *  retMsg.obj = AsyncResult ar
494      *  ar.exception carries exception on failure
495      *  ar.userObject contains the original value of result.obj
496      *  ar.result is null on success and failure
497      *
498      * CLIR_DEFAULT     == on "use subscription default value"
499      * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation)
500      * CLIR_INVOCATION  == on "CLIR invocation" (restrict CLI presentation)
501      */
502     public void dial(String address, int clirMode, UUSInfo uusInfo, Message result) {
503         simulatedCallState.onDial(address);
504
505         resultSuccess(result, null);
506     }
507
508     public void getIMSI(Message result) {
509         getIMSIForApp(null, result);
510     }
511     /**
512      *  returned message
513      *  retMsg.obj = AsyncResult ar
514      *  ar.exception carries exception on failure
515      *  ar.userObject contains the original value of result.obj
516      *  ar.result is String containing IMSI on success
517      */
518     public void getIMSIForApp(String aid, Message result) {
519         resultSuccess(result, "012345678901234");
520     }
521
522     /**
523      *  returned message
524      *  retMsg.obj = AsyncResult ar
525      *  ar.exception carries exception on failure
526      *  ar.userObject contains the original value of result.obj
527      *  ar.result is String containing IMEI on success
528      */
529     public void getIMEI(Message result) {
530         resultSuccess(result, "012345678901234");
531     }
532
533     /**
534      *  returned message
535      *  retMsg.obj = AsyncResult ar
536      *  ar.exception carries exception on failure
537      *  ar.userObject contains the original value of result.obj
538      *  ar.result is String containing IMEISV on success
539      */
540     public void getIMEISV(Message result) {
541         resultSuccess(result, "99");
542     }
543
544     /**
545      * Hang up one individual connection.
546      *  returned message
547      *  retMsg.obj = AsyncResult ar
548      *  ar.exception carries exception on failure
549      *  ar.userObject contains the original value of result.obj
550      *  ar.result is null on success and failure
551      *
552      *  3GPP 22.030 6.5.5
553      *  "Releases a specific active call X"
554      */
555     public void hangupConnection (int gsmIndex, Message result) {
556         boolean success;
557
558         success = simulatedCallState.onChld('1', (char)('0'+gsmIndex));
559
560         if (!success){
561             Rlog.i("GSM", "[SimCmd] hangupConnection: resultFail");
562             resultFail(result, new RuntimeException("Hangup Error"));
563         } else {
564             Rlog.i("GSM", "[SimCmd] hangupConnection: resultSuccess");
565             resultSuccess(result, null);
566         }
567     }
568
569     /**
570      * 3GPP 22.030 6.5.5
571      *  "Releases all held calls or sets User Determined User Busy (UDUB)
572      *   for a waiting call."
573      *  ar.exception carries exception on failure
574      *  ar.userObject contains the original value of result.obj
575      *  ar.result is null on success and failure
576      */
577     public void hangupWaitingOrBackground (Message result) {
578         boolean success;
579
580         success = simulatedCallState.onChld('0', '\0');
581
582         if (!success){
583             resultFail(result, new RuntimeException("Hangup Error"));
584         } else {
585             resultSuccess(result, null);
586         }
587     }
588
589     /**
590      * 3GPP 22.030 6.5.5
591      * "Releases all active calls (if any exist) and accepts
592      *  the other (held or waiting) call."
593      *
594      *  ar.exception carries exception on failure
595      *  ar.userObject contains the original value of result.obj
596      *  ar.result is null on success and failure
597      */
598     public void hangupForegroundResumeBackground (Message result) {
599         boolean success;
600
601         success = simulatedCallState.onChld('1', '\0');
602
603         if (!success){
604             resultFail(result, new RuntimeException("Hangup Error"));
605         } else {
606             resultSuccess(result, null);
607         }
608     }
609
610     /**
611      * 3GPP 22.030 6.5.5
612      * "Places all active calls (if any exist) on hold and accepts
613      *  the other (held or waiting) call."
614      *
615      *  ar.exception carries exception on failure
616      *  ar.userObject contains the original value of result.obj
617      *  ar.result is null on success and failure
618      */
619     public void switchWaitingOrHoldingAndActive (Message result) {
620         boolean success;
621
622         success = simulatedCallState.onChld('2', '\0');
623
624         if (!success){
625             resultFail(result, new RuntimeException("Hangup Error"));
626         } else {
627             resultSuccess(result, null);
628         }
629     }
630
631     /**
632      * 3GPP 22.030 6.5.5
633      * "Adds a held call to the conversation"
634      *
635      *  ar.exception carries exception on failure
636      *  ar.userObject contains the original value of result.obj
637      *  ar.result is null on success and failure
638      */
639     public void conference (Message result) {
640         boolean success;
641
642         success = simulatedCallState.onChld('3', '\0');
643
644         if (!success){
645             resultFail(result, new RuntimeException("Hangup Error"));
646         } else {
647             resultSuccess(result, null);
648         }
649     }
650
651     /**
652      * 3GPP 22.030 6.5.5
653      * "Connects the two calls and disconnects the subscriber from both calls"
654      *
655      *  ar.exception carries exception on failure
656      *  ar.userObject contains the original value of result.obj
657      *  ar.result is null on success and failure
658      */
659     public void explicitCallTransfer (Message result) {
660         boolean success;
661
662         success = simulatedCallState.onChld('4', '\0');
663
664         if (!success){
665             resultFail(result, new RuntimeException("Hangup Error"));
666         } else {
667             resultSuccess(result, null);
668         }
669     }
670
671     /**
672      * 3GPP 22.030 6.5.5
673      * "Places all active calls on hold except call X with which
674      *  communication shall be supported."
675      */
676     public void separateConnection (int gsmIndex, Message result) {
677         boolean success;
678
679         char ch = (char)(gsmIndex + '0');
680         success = simulatedCallState.onChld('2', ch);
681
682         if (!success){
683             resultFail(result, new RuntimeException("Hangup Error"));
684         } else {
685             resultSuccess(result, null);
686         }
687     }
688
689     /**
690      *
691      *  ar.exception carries exception on failure
692      *  ar.userObject contains the original value of result.obj
693      *  ar.result is null on success and failure
694      */
695     public void acceptCall (Message result) {
696         boolean success;
697
698         success = simulatedCallState.onAnswer();
699
700         if (!success){
701             resultFail(result, new RuntimeException("Hangup Error"));
702         } else {
703             resultSuccess(result, null);
704         }
705     }
706
707     /**
708      *  also known as UDUB
709      *  ar.exception carries exception on failure
710      *  ar.userObject contains the original value of result.obj
711      *  ar.result is null on success and failure
712      */
713     public void rejectCall (Message result) {
714         boolean success;
715
716         success = simulatedCallState.onChld('0', '\0');
717
718         if (!success){
719             resultFail(result, new RuntimeException("Hangup Error"));
720         } else {
721             resultSuccess(result, null);
722         }
723     }
724
725     /**
726      * cause code returned as Integer in Message.obj.response
727      * Returns integer cause code defined in TS 24.008
728      * Annex H or closest approximation.
729      * Most significant codes:
730      * - Any defined in 22.001 F.4 (for generating busy/congestion)
731      * - Cause 68: ACM >= ACMMax
732      */
733     public void getLastCallFailCause (Message result) {
734         int[] ret = new int[1];
735
736         ret[0] = nextCallFailCause;
737         resultSuccess(result, ret);
738     }
739
740     /**
741      * @deprecated
742      */
743     public void getLastPdpFailCause (Message result) {
744         unimplemented(result);
745     }
746
747     public void getLastDataCallFailCause(Message result) {
748         //
749         unimplemented(result);
750     }
751
752     public void setMute (boolean enableMute, Message result) {unimplemented(result);}
753
754     public void getMute (Message result) {unimplemented(result);}
755
756     /**
757      * response.obj is an AsyncResult
758      * response.obj.result is an int[2]
759      * response.obj.result[0] is received signal strength (0-31, 99)
760      * response.obj.result[1] is  bit error rate (0-7, 99)
761      * as defined in TS 27.007 8.5
762      */
763     public void getSignalStrength (Message result) {
764         int ret[] = new int[2];
765
766         ret[0] = 23;
767         ret[1] = 0;
768
769         resultSuccess(result, ret);
770     }
771
772      /**
773      * Assign a specified band for RF configuration.
774      *
775      * @param bandMode one of BM_*_BAND
776      * @param result is callback message
777      */
778     public void setBandMode (int bandMode, Message result) {
779         resultSuccess(result, null);
780     }
781
782     /**
783      * Query the list of band mode supported by RF.
784      *
785      * @param result is callback message
786      *        ((AsyncResult)response.obj).result  is an int[] with every
787      *        element representing one available BM_*_BAND
788      */
789     public void queryAvailableBandMode (Message result) {
790         int ret[] = new int [4];
791
792         ret[0] = 4;
793         ret[1] = Phone.BM_US_BAND;
794         ret[2] = Phone.BM_JPN_BAND;
795         ret[3] = Phone.BM_AUS_BAND;
796
797         resultSuccess(result, ret);
798     }
799
800     /**
801      * {@inheritDoc}
802      */
803     public void sendTerminalResponse(String contents, Message response) {
804         resultSuccess(response, null);
805     }
806
807     /**
808      * {@inheritDoc}
809      */
810     public void sendEnvelope(String contents, Message response) {
811         resultSuccess(response, null);
812     }
813
814     /**
815      * {@inheritDoc}
816      */
817     public void sendEnvelopeWithStatus(String contents, Message response) {
818         resultSuccess(response, null);
819     }
820
821     /**
822      * {@inheritDoc}
823      */
824     public void handleCallSetupRequestFromSim(
825             boolean accept, Message response) {
826         resultSuccess(response, null);
827     }
828
829     /**
830      * response.obj.result is an String[14]
831      * See ril.h for details
832      *
833      * Please note that registration state 4 ("unknown") is treated
834      * as "out of service" above
835      */
836     public void getVoiceRegistrationState (Message result) {
837         String ret[] = new String[14];
838
839         ret[0] = "5"; // registered roam
840         ret[1] = null;
841         ret[2] = null;
842         ret[3] = null;
843         ret[4] = null;
844         ret[5] = null;
845         ret[6] = null;
846         ret[7] = null;
847         ret[8] = null;
848         ret[9] = null;
849         ret[10] = null;
850         ret[11] = null;
851         ret[12] = null;
852         ret[13] = null;
853
854         resultSuccess(result, ret);
855     }
856
857     /**
858      * response.obj.result is an String[4]
859      * response.obj.result[0] is registration state 0-5 from TS 27.007 7.2
860      * response.obj.result[1] is LAC if registered or NULL if not
861      * response.obj.result[2] is CID if registered or NULL if not
862      * response.obj.result[3] indicates the available radio technology, where:
863      *      0 == unknown
864      *      1 == GPRS only
865      *      2 == EDGE
866      *      3 == UMTS
867      *
868      * valid LAC are 0x0000 - 0xffff
869      * valid CID are 0x00000000 - 0xffffffff
870      *
871      * Please note that registration state 4 ("unknown") is treated
872      * as "out of service" in the Android telephony system
873      */
874     public void getDataRegistrationState (Message result) {
875         String ret[] = new String[4];
876
877         ret[0] = "5"; // registered roam
878         ret[1] = null;
879         ret[2] = null;
880         ret[3] = "2";
881
882         resultSuccess(result, ret);
883     }
884
885     /**
886      * response.obj.result is a String[3]
887      * response.obj.result[0] is long alpha or null if unregistered
888      * response.obj.result[1] is short alpha or null if unregistered
889      * response.obj.result[2] is numeric or null if unregistered
890      */
891     public void getOperator(Message result) {
892         String[] ret = new String[3];
893
894         ret[0] = "El Telco Loco";
895         ret[1] = "Telco Loco";
896         ret[2] = "001001";
897
898         resultSuccess(result, ret);
899     }
900
901     /**
902      *  ar.exception carries exception on failure
903      *  ar.userObject contains the original value of result.obj
904      *  ar.result is null on success and failure
905      */
906     public void sendDtmf(char c, Message result) {
907         resultSuccess(result, null);
908     }
909
910     /**
911      *  ar.exception carries exception on failure
912      *  ar.userObject contains the original value of result.obj
913      *  ar.result is null on success and failure
914      */
915     public void startDtmf(char c, Message result) {
916         resultSuccess(result, null);
917     }
918
919     /**
920      *  ar.exception carries exception on failure
921      *  ar.userObject contains the original value of result.obj
922      *  ar.result is null on success and failure
923      */
924     public void stopDtmf(Message result) {
925         resultSuccess(result, null);
926     }
927
928     /**
929      *  ar.exception carries exception on failure
930      *  ar.userObject contains the original value of result.obj
931      *  ar.result is null on success and failure
932      */
933     public void sendBurstDtmf(String dtmfString, int on, int off, Message result) {
934         resultSuccess(result, null);
935     }
936
937     /**
938      * smscPDU is smsc address in PDU form GSM BCD format prefixed
939      *      by a length byte (as expected by TS 27.005) or NULL for default SMSC
940      * pdu is SMS in PDU format as an ASCII hex string
941      *      less the SMSC address
942      */
943     public void sendSMS (String smscPDU, String pdu, Message result) {unimplemented(result);}
944
945     public void deleteSmsOnSim(int index, Message response) {
946         Rlog.d(LOG_TAG, "Delete message at index " + index);
947         unimplemented(response);
948     }
949
950     public void deleteSmsOnRuim(int index, Message response) {
951         Rlog.d(LOG_TAG, "Delete RUIM message at index " + index);
952         unimplemented(response);
953     }
954
955     public void writeSmsToSim(int status, String smsc, String pdu, Message response) {
956         Rlog.d(LOG_TAG, "Write SMS to SIM with status " + status);
957         unimplemented(response);
958     }
959
960     public void writeSmsToRuim(int status, String pdu, Message response) {
961         Rlog.d(LOG_TAG, "Write SMS to RUIM with status " + status);
962         unimplemented(response);
963     }
964
965     public void setupDataCall(String radioTechnology, String profile,
966             String apn, String user, String password, String authType,
967             String protocol, Message result) {
968         unimplemented(result);
969     }
970
971     public void deactivateDataCall(int cid, int reason, Message result) {unimplemented(result);}
972
973     public void setPreferredNetworkType(int networkType , Message result) {
974         mNetworkType = networkType;
975         resultSuccess(result, null);
976     }
977
978     public void getPreferredNetworkType(Message result) {
979         int ret[] = new int[1];
980
981         ret[0] = mNetworkType;
982         resultSuccess(result, ret);
983     }
984
985     public void getNeighboringCids(Message result) {
986         int ret[] = new int[7];
987
988         ret[0] = 6;
989         for (int i = 1; i<7; i++) {
990             ret[i] = i;
991         }
992         resultSuccess(result, ret);
993     }
994
995     public void setLocationUpdates(boolean enable, Message response) {
996         unimplemented(response);
997     }
998
999     public void getSmscAddress(Message result) {
1000         unimplemented(result);
1001     }
1002
1003     public void setSmscAddress(String address, Message result) {
1004         unimplemented(result);
1005     }
1006
1007     public void reportSmsMemoryStatus(boolean available, Message result) {
1008         unimplemented(result);
1009     }
1010
1011     public void reportStkServiceIsRunning(Message result) {
1012         resultSuccess(result, null);
1013     }
1014
1015     @Override
1016     public void getCdmaSubscriptionSource(Message result) {
1017         unimplemented(result);
1018     }
1019
1020     private boolean isSimLocked() {
1021         if (mSimLockedState != SimLockState.NONE) {
1022             return true;
1023         }
1024         return false;
1025     }
1026
1027     public void setRadioPower(boolean on, Message result) {
1028         if(on) {
1029             setRadioState(RadioState.RADIO_ON);
1030         } else {
1031             setRadioState(RadioState.RADIO_OFF);
1032         }
1033     }
1034
1035
1036     public void acknowledgeLastIncomingGsmSms(boolean success, int cause, Message result) {
1037         unimplemented(result);
1038     }
1039
1040     public void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result) {
1041         unimplemented(result);
1042     }
1043
1044     public void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu,
1045             Message result) {
1046         unimplemented(result);
1047     }
1048
1049     public void iccIO(int command, int fileid, String path, int p1, int p2, int p3, String data,
1050             String pin2, Message response) {
1051         iccIOForApp(command, fileid, path, p1, p2, p3, data,pin2, null, response);
1052     }
1053
1054     /**
1055      * parameters equivalent to 27.007 AT+CRSM command
1056      * response.obj will be an AsyncResult
1057      * response.obj.userObj will be a SimIoResult on success
1058      */
1059     public void iccIOForApp (int command, int fileid, String path, int p1, int p2,
1060                        int p3, String data, String pin2, String aid, Message result) {
1061         unimplemented(result);
1062     }
1063
1064     /**
1065      * (AsyncResult)response.obj).result is an int[] with element [0] set to
1066      * 1 for "CLIP is provisioned", and 0 for "CLIP is not provisioned".
1067      *
1068      * @param response is callback message
1069      */
1070     public void queryCLIP(Message response) { unimplemented(response); }
1071
1072
1073     /**
1074      * response.obj will be a an int[2]
1075      *
1076      * response.obj[0] will be TS 27.007 +CLIR parameter 'n'
1077      *  0 presentation indicator is used according to the subscription of the CLIR service
1078      *  1 CLIR invocation
1079      *  2 CLIR suppression
1080      *
1081      * response.obj[1] will be TS 27.007 +CLIR parameter 'm'
1082      *  0 CLIR not provisioned
1083      *  1 CLIR provisioned in permanent mode
1084      *  2 unknown (e.g. no network, etc.)
1085      *  3 CLIR temporary mode presentation restricted
1086      *  4 CLIR temporary mode presentation allowed
1087      */
1088
1089     public void getCLIR(Message result) {unimplemented(result);}
1090
1091     /**
1092      * clirMode is one of the CLIR_* constants above
1093      *
1094      * response.obj is null
1095      */
1096
1097     public void setCLIR(int clirMode, Message result) {unimplemented(result);}
1098
1099     /**
1100      * (AsyncResult)response.obj).result is an int[] with element [0] set to
1101      * 0 for disabled, 1 for enabled.
1102      *
1103      * @param serviceClass is a sum of SERVICE_CLASS_*
1104      * @param response is callback message
1105      */
1106
1107     public void queryCallWaiting(int serviceClass, Message response) {
1108         unimplemented(response);
1109     }
1110
1111     /**
1112      * @param enable is true to enable, false to disable
1113      * @param serviceClass is a sum of SERVICE_CLASS_*
1114      * @param response is callback message
1115      */
1116
1117     public void setCallWaiting(boolean enable, int serviceClass,
1118             Message response) {
1119         unimplemented(response);
1120     }
1121
1122     /**
1123      * @param action is one of CF_ACTION_*
1124      * @param cfReason is one of CF_REASON_*
1125      * @param serviceClass is a sum of SERVICE_CLASSS_*
1126      */
1127     public void setCallForward(int action, int cfReason, int serviceClass,
1128             String number, int timeSeconds, Message result) {unimplemented(result);}
1129
1130     /**
1131      * cfReason is one of CF_REASON_*
1132      *
1133      * ((AsyncResult)response.obj).result will be an array of
1134      * CallForwardInfo's
1135      *
1136      * An array of length 0 means "disabled for all codes"
1137      */
1138     public void queryCallForwardStatus(int cfReason, int serviceClass,
1139             String number, Message result) {unimplemented(result);}
1140
1141     public void setNetworkSelectionModeAutomatic(Message result) {unimplemented(result);}
1142     public void exitEmergencyCallbackMode(Message result) {unimplemented(result);}
1143     public void setNetworkSelectionModeManual(
1144             String operatorNumeric, Message result) {unimplemented(result);}
1145
1146     /**
1147      * Queries whether the current network selection mode is automatic
1148      * or manual
1149      *
1150      * ((AsyncResult)response.obj).result  is an int[] with element [0] being
1151      * a 0 for automatic selection and a 1 for manual selection
1152      */
1153
1154     public void getNetworkSelectionMode(Message result) {
1155         int ret[] = new int[1];
1156
1157         ret[0] = 0;
1158         resultSuccess(result, ret);
1159     }
1160
1161     /**
1162      * Queries the currently available networks
1163      *
1164      * ((AsyncResult)response.obj).result  is a List of NetworkInfo objects
1165      */
1166     public void getAvailableNetworks(Message result) {unimplemented(result);}
1167
1168     public void getBasebandVersion (Message result) {
1169         resultSuccess(result, "SimulatedCommands");
1170     }
1171
1172     /**
1173      * Simulates an incoming USSD message
1174      * @param statusCode  Status code string. See <code>setOnUSSD</code>
1175      * in CommandsInterface.java
1176      * @param message Message text to send or null if none
1177      */
1178     public void triggerIncomingUssd(String statusCode, String message) {
1179         if (mUSSDRegistrant != null) {
1180             String[] result = {statusCode, message};
1181             mUSSDRegistrant.notifyResult(result);
1182         }
1183     }
1184
1185
1186     public void sendUSSD (String ussdString, Message result) {
1187
1188         // We simulate this particular sequence
1189         if (ussdString.equals("#646#")) {
1190             resultSuccess(result, null);
1191
1192             // 0 == USSD-Notify
1193             triggerIncomingUssd("0", "You have NNN minutes remaining.");
1194         } else {
1195             resultSuccess(result, null);
1196
1197             triggerIncomingUssd("0", "All Done");
1198         }
1199     }
1200
1201     // inherited javadoc suffices
1202     public void cancelPendingUssd (Message response) {
1203         resultSuccess(response, null);
1204     }
1205
1206
1207     public void resetRadio(Message result) {
1208         unimplemented(result);
1209     }
1210
1211     public void invokeOemRilRequestRaw(byte[] data, Message response) {
1212         // Just echo back data
1213         if (response != null) {
1214             AsyncResult.forMessage(response).result = data;
1215             response.sendToTarget();
1216         }
1217     }
1218
1219     public void invokeOemRilRequestStrings(String[] strings, Message response) {
1220         // Just echo back data
1221         if (response != null) {
1222             AsyncResult.forMessage(response).result = strings;
1223             response.sendToTarget();
1224         }
1225     }
1226
1227     //***** SimulatedRadioControl
1228
1229
1230     /** Start the simulated phone ringing */
1231     public void
1232     triggerRing(String number) {
1233         simulatedCallState.triggerRing(number);
1234         mCallStateRegistrants.notifyRegistrants();
1235     }
1236
1237     public void
1238     progressConnectingCallState() {
1239         simulatedCallState.progressConnectingCallState();
1240         mCallStateRegistrants.notifyRegistrants();
1241     }
1242
1243     /** If a call is DIALING or ALERTING, progress it all the way to ACTIVE */
1244     public void
1245     progressConnectingToActive() {
1246         simulatedCallState.progressConnectingToActive();
1247         mCallStateRegistrants.notifyRegistrants();
1248     }
1249
1250     /** automatically progress mobile originated calls to ACTIVE.
1251      *  default to true
1252      */
1253     public void
1254     setAutoProgressConnectingCall(boolean b) {
1255         simulatedCallState.setAutoProgressConnectingCall(b);
1256     }
1257
1258     public void
1259     setNextDialFailImmediately(boolean b) {
1260         simulatedCallState.setNextDialFailImmediately(b);
1261     }
1262
1263     public void
1264     setNextCallFailCause(int gsmCause) {
1265         nextCallFailCause = gsmCause;
1266     }
1267
1268     public void
1269     triggerHangupForeground() {
1270         simulatedCallState.triggerHangupForeground();
1271         mCallStateRegistrants.notifyRegistrants();
1272     }
1273
1274     /** hangup holding calls */
1275     public void
1276     triggerHangupBackground() {
1277         simulatedCallState.triggerHangupBackground();
1278         mCallStateRegistrants.notifyRegistrants();
1279     }
1280
1281     public void triggerSsn(int type, int code) {
1282         SuppServiceNotification not = new SuppServiceNotification();
1283         not.notificationType = type;
1284         not.code = code;
1285         mSsnRegistrant.notifyRegistrant(new AsyncResult(null, not, null));
1286     }
1287
1288     public void
1289     shutdown() {
1290         setRadioState(RadioState.RADIO_UNAVAILABLE);
1291         Looper looper = mHandlerThread.getLooper();
1292         if (looper != null) {
1293             looper.quit();
1294         }
1295     }
1296
1297     /** hangup all */
1298
1299     public void
1300     triggerHangupAll() {
1301         simulatedCallState.triggerHangupAll();
1302         mCallStateRegistrants.notifyRegistrants();
1303     }
1304
1305     public void
1306     triggerIncomingSMS(String message) {
1307         //TODO
1308     }
1309
1310     public void
1311     pauseResponses() {
1312         pausedResponseCount++;
1313     }
1314
1315     public void
1316     resumeResponses() {
1317         pausedResponseCount--;
1318
1319         if (pausedResponseCount == 0) {
1320             for (int i = 0, s = pausedResponses.size(); i < s ; i++) {
1321                 pausedResponses.get(i).sendToTarget();
1322             }
1323             pausedResponses.clear();
1324         } else {
1325             Rlog.e("GSM", "SimulatedCommands.resumeResponses < 0");
1326         }
1327     }
1328
1329     //***** Private Methods
1330
1331     private void unimplemented(Message result) {
1332         if (result != null) {
1333             AsyncResult.forMessage(result).exception
1334                 = new RuntimeException("Unimplemented");
1335
1336             if (pausedResponseCount > 0) {
1337                 pausedResponses.add(result);
1338             } else {
1339                 result.sendToTarget();
1340             }
1341         }
1342     }
1343
1344     private void resultSuccess(Message result, Object ret) {
1345         if (result != null) {
1346             AsyncResult.forMessage(result).result = ret;
1347             if (pausedResponseCount > 0) {
1348                 pausedResponses.add(result);
1349             } else {
1350                 result.sendToTarget();
1351             }
1352         }
1353     }
1354
1355     private void resultFail(Message result, Throwable tr) {
1356         if (result != null) {
1357             AsyncResult.forMessage(result).exception = tr;
1358             if (pausedResponseCount > 0) {
1359                 pausedResponses.add(result);
1360             } else {
1361                 result.sendToTarget();
1362             }
1363         }
1364     }
1365
1366     // ***** Methods for CDMA support
1367     public void
1368     getDeviceIdentity(Message response) {
1369         Rlog.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
1370         unimplemented(response);
1371     }
1372
1373     public void
1374     getCDMASubscription(Message response) {
1375         Rlog.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
1376         unimplemented(response);
1377     }
1378
1379     public void
1380     setCdmaSubscriptionSource(int cdmaSubscriptionType, Message response) {
1381         Rlog.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
1382         unimplemented(response);
1383     }
1384
1385     public void queryCdmaRoamingPreference(Message response) {
1386         Rlog.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
1387         unimplemented(response);
1388     }
1389
1390     public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
1391         Rlog.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
1392         unimplemented(response);
1393     }
1394
1395     public void
1396     setPhoneType(int phoneType) {
1397         Rlog.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
1398     }
1399
1400     public void getPreferredVoicePrivacy(Message result) {
1401         Rlog.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
1402         unimplemented(result);
1403     }
1404
1405     public void setPreferredVoicePrivacy(boolean enable, Message result) {
1406         Rlog.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
1407         unimplemented(result);
1408     }
1409
1410     /**
1411      *  Set the TTY mode
1412      *
1413      * @param ttyMode is one of the following:
1414      * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
1415      * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
1416      * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
1417      * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
1418      * @param response is callback message
1419      */
1420     public void setTTYMode(int ttyMode, Message response) {
1421         Rlog.w(LOG_TAG, "Not implemented in SimulatedCommands");
1422         unimplemented(response);
1423     }
1424
1425     /**
1426      *  Query the TTY mode
1427      * (AsyncResult)response.obj).result is an int[] with element [0] set to
1428      * tty mode:
1429      * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
1430      * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
1431      * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
1432      * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
1433      * @param response is callback message
1434      */
1435     public void queryTTYMode(Message response) {
1436         Rlog.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
1437         unimplemented(response);
1438     }
1439
1440     /**
1441      * {@inheritDoc}
1442      */
1443     public void sendCDMAFeatureCode(String FeatureCode, Message response) {
1444         Rlog.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
1445         unimplemented(response);
1446     }
1447
1448     /**
1449      * {@inheritDoc}
1450      */
1451     public void sendCdmaSms(byte[] pdu, Message response){
1452        Rlog.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
1453     }
1454
1455     public void setCdmaBroadcastActivation(boolean activate, Message response) {
1456         unimplemented(response);
1457
1458     }
1459
1460     public void getCdmaBroadcastConfig(Message response) {
1461         unimplemented(response);
1462
1463     }
1464
1465     public void setCdmaBroadcastConfig(CdmaSmsBroadcastConfigInfo[] configs, Message response) {
1466         unimplemented(response);
1467     }
1468
1469     public void forceDataDormancy(Message response) {
1470         unimplemented(response);
1471     }
1472
1473
1474     public void setGsmBroadcastActivation(boolean activate, Message response) {
1475         unimplemented(response);
1476     }
1477
1478
1479     public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response) {
1480         unimplemented(response);
1481     }
1482
1483     public void getGsmBroadcastConfig(Message response) {
1484         unimplemented(response);
1485     }
1486
1487     @Override
1488     public void supplyIccPinForApp(String pin, String aid, Message response) {
1489         unimplemented(response);
1490     }
1491
1492     @Override
1493     public void supplyIccPukForApp(String puk, String newPin, String aid, Message response) {
1494         unimplemented(response);
1495     }
1496
1497     @Override
1498     public void supplyIccPin2ForApp(String pin2, String aid, Message response) {
1499         unimplemented(response);
1500     }
1501
1502     @Override
1503     public void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message response) {
1504         unimplemented(response);
1505     }
1506
1507     @Override
1508     public void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message response) {
1509         unimplemented(response);
1510     }
1511
1512     @Override
1513     public void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr,
1514             Message response) {
1515         unimplemented(response);
1516     }
1517
1518     public void requestIsimAuthentication(String nonce, Message response) {
1519         unimplemented(response);
1520     }
1521
1522     public void getVoiceRadioTechnology(Message response) {
1523         unimplemented(response);
1524     }
1525 }