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