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