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