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