CommandParamsFactory.java revision 86968438e444728053137c764cc37cf9c0a15d16
1/* 2 * Copyright (C) 2007 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.cat; 18 19import android.graphics.Bitmap; 20import android.os.Handler; 21import android.os.Message; 22 23import com.android.internal.telephony.GsmAlphabet; 24import com.android.internal.telephony.uicc.IccFileHandler; 25 26import java.util.Iterator; 27import java.util.List; 28 29/** 30 * Factory class, used for decoding raw byte arrays, received from baseband, 31 * into a CommandParams object. 32 * 33 */ 34class CommandParamsFactory extends Handler { 35 private static CommandParamsFactory sInstance = null; 36 private IconLoader mIconLoader; 37 private CommandParams mCmdParams = null; 38 private int mIconLoadState = LOAD_NO_ICON; 39 private RilMessageDecoder mCaller = null; 40 41 // constants 42 static final int MSG_ID_LOAD_ICON_DONE = 1; 43 44 // loading icons state parameters. 45 static final int LOAD_NO_ICON = 0; 46 static final int LOAD_SINGLE_ICON = 1; 47 static final int LOAD_MULTI_ICONS = 2; 48 49 // Command Qualifier values for refresh command 50 static final int REFRESH_NAA_INIT_AND_FULL_FILE_CHANGE = 0x00; 51 static final int REFRESH_NAA_INIT_AND_FILE_CHANGE = 0x02; 52 static final int REFRESH_NAA_INIT = 0x03; 53 static final int REFRESH_UICC_RESET = 0x04; 54 55 // Command Qualifier values for PLI command 56 static final int DTTZ_SETTING = 0x03; 57 static final int LANGUAGE_SETTING = 0x04; 58 59 static synchronized CommandParamsFactory getInstance(RilMessageDecoder caller, 60 IccFileHandler fh) { 61 if (sInstance != null) { 62 return sInstance; 63 } 64 if (fh != null) { 65 return new CommandParamsFactory(caller, fh); 66 } 67 return null; 68 } 69 70 private CommandParamsFactory(RilMessageDecoder caller, IccFileHandler fh) { 71 mCaller = caller; 72 mIconLoader = IconLoader.getInstance(this, fh); 73 } 74 75 private CommandDetails processCommandDetails(List<ComprehensionTlv> ctlvs) { 76 CommandDetails cmdDet = null; 77 78 if (ctlvs != null) { 79 // Search for the Command Details object. 80 ComprehensionTlv ctlvCmdDet = searchForTag( 81 ComprehensionTlvTag.COMMAND_DETAILS, ctlvs); 82 if (ctlvCmdDet != null) { 83 try { 84 cmdDet = ValueParser.retrieveCommandDetails(ctlvCmdDet); 85 } catch (ResultException e) { 86 CatLog.d(this, 87 "processCommandDetails: Failed to procees command details e=" + e); 88 } 89 } 90 } 91 return cmdDet; 92 } 93 94 void make(BerTlv berTlv) { 95 if (berTlv == null) { 96 return; 97 } 98 // reset global state parameters. 99 mCmdParams = null; 100 mIconLoadState = LOAD_NO_ICON; 101 // only proactive command messages are processed. 102 if (berTlv.getTag() != BerTlv.BER_PROACTIVE_COMMAND_TAG) { 103 sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD); 104 return; 105 } 106 boolean cmdPending = false; 107 List<ComprehensionTlv> ctlvs = berTlv.getComprehensionTlvs(); 108 // process command dtails from the tlv list. 109 CommandDetails cmdDet = processCommandDetails(ctlvs); 110 if (cmdDet == null) { 111 sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD); 112 return; 113 } 114 115 // extract command type enumeration from the raw value stored inside 116 // the Command Details object. 117 AppInterface.CommandType cmdType = AppInterface.CommandType 118 .fromInt(cmdDet.typeOfCommand); 119 if (cmdType == null) { 120 // This PROACTIVE COMMAND is presently not handled. Hence set 121 // result code as BEYOND_TERMINAL_CAPABILITY in TR. 122 mCmdParams = new CommandParams(cmdDet); 123 sendCmdParams(ResultCode.BEYOND_TERMINAL_CAPABILITY); 124 return; 125 } 126 127 try { 128 switch (cmdType) { 129 case SET_UP_MENU: 130 cmdPending = processSelectItem(cmdDet, ctlvs); 131 break; 132 case SELECT_ITEM: 133 cmdPending = processSelectItem(cmdDet, ctlvs); 134 break; 135 case DISPLAY_TEXT: 136 cmdPending = processDisplayText(cmdDet, ctlvs); 137 break; 138 case SET_UP_IDLE_MODE_TEXT: 139 cmdPending = processSetUpIdleModeText(cmdDet, ctlvs); 140 break; 141 case GET_INKEY: 142 cmdPending = processGetInkey(cmdDet, ctlvs); 143 break; 144 case GET_INPUT: 145 cmdPending = processGetInput(cmdDet, ctlvs); 146 break; 147 case SEND_DTMF: 148 case SEND_SMS: 149 case SEND_SS: 150 case SEND_USSD: 151 cmdPending = processEventNotify(cmdDet, ctlvs); 152 break; 153 case GET_CHANNEL_STATUS: 154 case SET_UP_CALL: 155 cmdPending = processSetupCall(cmdDet, ctlvs); 156 break; 157 case REFRESH: 158 processRefresh(cmdDet, ctlvs); 159 cmdPending = false; 160 break; 161 case LAUNCH_BROWSER: 162 cmdPending = processLaunchBrowser(cmdDet, ctlvs); 163 break; 164 case PLAY_TONE: 165 cmdPending = processPlayTone(cmdDet, ctlvs); 166 break; 167 case PROVIDE_LOCAL_INFORMATION: 168 cmdPending = processProvideLocalInfo(cmdDet, ctlvs); 169 break; 170 case OPEN_CHANNEL: 171 case CLOSE_CHANNEL: 172 case RECEIVE_DATA: 173 case SEND_DATA: 174 cmdPending = processBIPClient(cmdDet, ctlvs); 175 break; 176 default: 177 // unsupported proactive commands 178 mCmdParams = new CommandParams(cmdDet); 179 sendCmdParams(ResultCode.BEYOND_TERMINAL_CAPABILITY); 180 return; 181 } 182 } catch (ResultException e) { 183 CatLog.d(this, "make: caught ResultException e=" + e); 184 mCmdParams = new CommandParams(cmdDet); 185 sendCmdParams(e.result()); 186 return; 187 } 188 if (!cmdPending) { 189 sendCmdParams(ResultCode.OK); 190 } 191 } 192 193 @Override 194 public void handleMessage(Message msg) { 195 switch (msg.what) { 196 case MSG_ID_LOAD_ICON_DONE: 197 sendCmdParams(setIcons(msg.obj)); 198 break; 199 } 200 } 201 202 private ResultCode setIcons(Object data) { 203 Bitmap[] icons = null; 204 int iconIndex = 0; 205 206 if (data == null) { 207 return ResultCode.OK; 208 } 209 switch(mIconLoadState) { 210 case LOAD_SINGLE_ICON: 211 mCmdParams.setIcon((Bitmap) data); 212 break; 213 case LOAD_MULTI_ICONS: 214 icons = (Bitmap[]) data; 215 // set each item icon. 216 for (Bitmap icon : icons) { 217 mCmdParams.setIcon(icon); 218 } 219 break; 220 } 221 return ResultCode.OK; 222 } 223 224 private void sendCmdParams(ResultCode resCode) { 225 mCaller.sendMsgParamsDecoded(resCode, mCmdParams); 226 } 227 228 /** 229 * Search for a COMPREHENSION-TLV object with the given tag from a list 230 * 231 * @param tag A tag to search for 232 * @param ctlvs List of ComprehensionTlv objects used to search in 233 * 234 * @return A ComprehensionTlv object that has the tag value of {@code tag}. 235 * If no object is found with the tag, null is returned. 236 */ 237 private ComprehensionTlv searchForTag(ComprehensionTlvTag tag, 238 List<ComprehensionTlv> ctlvs) { 239 Iterator<ComprehensionTlv> iter = ctlvs.iterator(); 240 return searchForNextTag(tag, iter); 241 } 242 243 /** 244 * Search for the next COMPREHENSION-TLV object with the given tag from a 245 * list iterated by {@code iter}. {@code iter} points to the object next to 246 * the found object when this method returns. Used for searching the same 247 * list for similar tags, usually item id. 248 * 249 * @param tag A tag to search for 250 * @param iter Iterator for ComprehensionTlv objects used for search 251 * 252 * @return A ComprehensionTlv object that has the tag value of {@code tag}. 253 * If no object is found with the tag, null is returned. 254 */ 255 private ComprehensionTlv searchForNextTag(ComprehensionTlvTag tag, 256 Iterator<ComprehensionTlv> iter) { 257 int tagValue = tag.value(); 258 while (iter.hasNext()) { 259 ComprehensionTlv ctlv = iter.next(); 260 if (ctlv.getTag() == tagValue) { 261 return ctlv; 262 } 263 } 264 return null; 265 } 266 267 /** 268 * Processes DISPLAY_TEXT proactive command from the SIM card. 269 * 270 * @param cmdDet Command Details container object. 271 * @param ctlvs List of ComprehensionTlv objects following Command Details 272 * object and Device Identities object within the proactive command 273 * @return true if the command is processing is pending and additional 274 * asynchronous processing is required. 275 * @throws ResultException 276 */ 277 private boolean processDisplayText(CommandDetails cmdDet, 278 List<ComprehensionTlv> ctlvs) 279 throws ResultException { 280 281 CatLog.d(this, "process DisplayText"); 282 283 TextMessage textMsg = new TextMessage(); 284 IconId iconId = null; 285 286 ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING, 287 ctlvs); 288 if (ctlv != null) { 289 textMsg.text = ValueParser.retrieveTextString(ctlv); 290 } 291 // If the tlv object doesn't exist or the it is a null object reply 292 // with command not understood. 293 if (textMsg.text == null) { 294 throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); 295 } 296 297 ctlv = searchForTag(ComprehensionTlvTag.IMMEDIATE_RESPONSE, ctlvs); 298 if (ctlv != null) { 299 textMsg.responseNeeded = false; 300 } 301 // parse icon identifier 302 ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); 303 if (ctlv != null) { 304 iconId = ValueParser.retrieveIconId(ctlv); 305 textMsg.iconSelfExplanatory = iconId.selfExplanatory; 306 } 307 // parse tone duration 308 ctlv = searchForTag(ComprehensionTlvTag.DURATION, ctlvs); 309 if (ctlv != null) { 310 textMsg.duration = ValueParser.retrieveDuration(ctlv); 311 } 312 313 // Parse command qualifier parameters. 314 textMsg.isHighPriority = (cmdDet.commandQualifier & 0x01) != 0; 315 textMsg.userClear = (cmdDet.commandQualifier & 0x80) != 0; 316 317 mCmdParams = new DisplayTextParams(cmdDet, textMsg); 318 319 if (iconId != null) { 320 mIconLoadState = LOAD_SINGLE_ICON; 321 mIconLoader.loadIcon(iconId.recordNumber, this 322 .obtainMessage(MSG_ID_LOAD_ICON_DONE)); 323 return true; 324 } 325 return false; 326 } 327 328 /** 329 * Processes SET_UP_IDLE_MODE_TEXT proactive command from the SIM card. 330 * 331 * @param cmdDet Command Details container object. 332 * @param ctlvs List of ComprehensionTlv objects following Command Details 333 * object and Device Identities object within the proactive command 334 * @return true if the command is processing is pending and additional 335 * asynchronous processing is required. 336 * @throws ResultException 337 */ 338 private boolean processSetUpIdleModeText(CommandDetails cmdDet, 339 List<ComprehensionTlv> ctlvs) throws ResultException { 340 341 CatLog.d(this, "process SetUpIdleModeText"); 342 343 TextMessage textMsg = new TextMessage(); 344 IconId iconId = null; 345 346 ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING, 347 ctlvs); 348 if (ctlv != null) { 349 textMsg.text = ValueParser.retrieveTextString(ctlv); 350 } 351 // load icons only when text exist. 352 if (textMsg.text != null) { 353 ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); 354 if (ctlv != null) { 355 iconId = ValueParser.retrieveIconId(ctlv); 356 textMsg.iconSelfExplanatory = iconId.selfExplanatory; 357 } 358 } 359 360 mCmdParams = new DisplayTextParams(cmdDet, textMsg); 361 362 if (iconId != null) { 363 mIconLoadState = LOAD_SINGLE_ICON; 364 mIconLoader.loadIcon(iconId.recordNumber, this 365 .obtainMessage(MSG_ID_LOAD_ICON_DONE)); 366 return true; 367 } 368 return false; 369 } 370 371 /** 372 * Processes GET_INKEY proactive command from the SIM card. 373 * 374 * @param cmdDet Command Details container object. 375 * @param ctlvs List of ComprehensionTlv objects following Command Details 376 * object and Device Identities object within the proactive command 377 * @return true if the command is processing is pending and additional 378 * asynchronous processing is required. 379 * @throws ResultException 380 */ 381 private boolean processGetInkey(CommandDetails cmdDet, 382 List<ComprehensionTlv> ctlvs) throws ResultException { 383 384 CatLog.d(this, "process GetInkey"); 385 386 Input input = new Input(); 387 IconId iconId = null; 388 389 ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING, 390 ctlvs); 391 if (ctlv != null) { 392 input.text = ValueParser.retrieveTextString(ctlv); 393 } else { 394 throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); 395 } 396 // parse icon identifier 397 ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); 398 if (ctlv != null) { 399 iconId = ValueParser.retrieveIconId(ctlv); 400 } 401 402 // parse duration 403 ctlv = searchForTag(ComprehensionTlvTag.DURATION, ctlvs); 404 if (ctlv != null) { 405 input.duration = ValueParser.retrieveDuration(ctlv); 406 } 407 408 input.minLen = 1; 409 input.maxLen = 1; 410 411 input.digitOnly = (cmdDet.commandQualifier & 0x01) == 0; 412 input.ucs2 = (cmdDet.commandQualifier & 0x02) != 0; 413 input.yesNo = (cmdDet.commandQualifier & 0x04) != 0; 414 input.helpAvailable = (cmdDet.commandQualifier & 0x80) != 0; 415 input.echo = true; 416 417 mCmdParams = new GetInputParams(cmdDet, input); 418 419 if (iconId != null) { 420 mIconLoadState = LOAD_SINGLE_ICON; 421 mIconLoader.loadIcon(iconId.recordNumber, this 422 .obtainMessage(MSG_ID_LOAD_ICON_DONE)); 423 return true; 424 } 425 return false; 426 } 427 428 /** 429 * Processes GET_INPUT proactive command from the SIM card. 430 * 431 * @param cmdDet Command Details container object. 432 * @param ctlvs List of ComprehensionTlv objects following Command Details 433 * object and Device Identities object within the proactive command 434 * @return true if the command is processing is pending and additional 435 * asynchronous processing is required. 436 * @throws ResultException 437 */ 438 private boolean processGetInput(CommandDetails cmdDet, 439 List<ComprehensionTlv> ctlvs) throws ResultException { 440 441 CatLog.d(this, "process GetInput"); 442 443 Input input = new Input(); 444 IconId iconId = null; 445 446 ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING, 447 ctlvs); 448 if (ctlv != null) { 449 input.text = ValueParser.retrieveTextString(ctlv); 450 } else { 451 throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); 452 } 453 454 ctlv = searchForTag(ComprehensionTlvTag.RESPONSE_LENGTH, ctlvs); 455 if (ctlv != null) { 456 try { 457 byte[] rawValue = ctlv.getRawValue(); 458 int valueIndex = ctlv.getValueIndex(); 459 input.minLen = rawValue[valueIndex] & 0xff; 460 input.maxLen = rawValue[valueIndex + 1] & 0xff; 461 } catch (IndexOutOfBoundsException e) { 462 throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); 463 } 464 } else { 465 throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); 466 } 467 468 ctlv = searchForTag(ComprehensionTlvTag.DEFAULT_TEXT, ctlvs); 469 if (ctlv != null) { 470 input.defaultText = ValueParser.retrieveTextString(ctlv); 471 } 472 // parse icon identifier 473 ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); 474 if (ctlv != null) { 475 iconId = ValueParser.retrieveIconId(ctlv); 476 } 477 478 input.digitOnly = (cmdDet.commandQualifier & 0x01) == 0; 479 input.ucs2 = (cmdDet.commandQualifier & 0x02) != 0; 480 input.echo = (cmdDet.commandQualifier & 0x04) == 0; 481 input.packed = (cmdDet.commandQualifier & 0x08) != 0; 482 input.helpAvailable = (cmdDet.commandQualifier & 0x80) != 0; 483 484 mCmdParams = new GetInputParams(cmdDet, input); 485 486 if (iconId != null) { 487 mIconLoadState = LOAD_SINGLE_ICON; 488 mIconLoader.loadIcon(iconId.recordNumber, this 489 .obtainMessage(MSG_ID_LOAD_ICON_DONE)); 490 return true; 491 } 492 return false; 493 } 494 495 /** 496 * Processes REFRESH proactive command from the SIM card. 497 * 498 * @param cmdDet Command Details container object. 499 * @param ctlvs List of ComprehensionTlv objects following Command Details 500 * object and Device Identities object within the proactive command 501 */ 502 private boolean processRefresh(CommandDetails cmdDet, 503 List<ComprehensionTlv> ctlvs) { 504 505 CatLog.d(this, "process Refresh"); 506 507 // REFRESH proactive command is rerouted by the baseband and handled by 508 // the telephony layer. IDLE TEXT should be removed for a REFRESH command 509 // with "initialization" or "reset" 510 switch (cmdDet.commandQualifier) { 511 case REFRESH_NAA_INIT_AND_FULL_FILE_CHANGE: 512 case REFRESH_NAA_INIT_AND_FILE_CHANGE: 513 case REFRESH_NAA_INIT: 514 case REFRESH_UICC_RESET: 515 mCmdParams = new DisplayTextParams(cmdDet, null); 516 break; 517 } 518 return false; 519 } 520 521 /** 522 * Processes SELECT_ITEM proactive command from the SIM card. 523 * 524 * @param cmdDet Command Details container object. 525 * @param ctlvs List of ComprehensionTlv objects following Command Details 526 * object and Device Identities object within the proactive command 527 * @return true if the command is processing is pending and additional 528 * asynchronous processing is required. 529 * @throws ResultException 530 */ 531 private boolean processSelectItem(CommandDetails cmdDet, 532 List<ComprehensionTlv> ctlvs) throws ResultException { 533 534 CatLog.d(this, "process SelectItem"); 535 536 Menu menu = new Menu(); 537 IconId titleIconId = null; 538 ItemsIconId itemsIconId = null; 539 Iterator<ComprehensionTlv> iter = ctlvs.iterator(); 540 541 ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, 542 ctlvs); 543 if (ctlv != null) { 544 menu.title = ValueParser.retrieveAlphaId(ctlv); 545 } 546 547 while (true) { 548 ctlv = searchForNextTag(ComprehensionTlvTag.ITEM, iter); 549 if (ctlv != null) { 550 menu.items.add(ValueParser.retrieveItem(ctlv)); 551 } else { 552 break; 553 } 554 } 555 556 // We must have at least one menu item. 557 if (menu.items.size() == 0) { 558 throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); 559 } 560 561 ctlv = searchForTag(ComprehensionTlvTag.ITEM_ID, ctlvs); 562 if (ctlv != null) { 563 // CAT items are listed 1...n while list start at 0, need to 564 // subtract one. 565 menu.defaultItem = ValueParser.retrieveItemId(ctlv) - 1; 566 } 567 568 ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); 569 if (ctlv != null) { 570 mIconLoadState = LOAD_SINGLE_ICON; 571 titleIconId = ValueParser.retrieveIconId(ctlv); 572 menu.titleIconSelfExplanatory = titleIconId.selfExplanatory; 573 } 574 575 ctlv = searchForTag(ComprehensionTlvTag.ITEM_ICON_ID_LIST, ctlvs); 576 if (ctlv != null) { 577 mIconLoadState = LOAD_MULTI_ICONS; 578 itemsIconId = ValueParser.retrieveItemsIconId(ctlv); 579 menu.itemsIconSelfExplanatory = itemsIconId.selfExplanatory; 580 } 581 582 boolean presentTypeSpecified = (cmdDet.commandQualifier & 0x01) != 0; 583 if (presentTypeSpecified) { 584 if ((cmdDet.commandQualifier & 0x02) == 0) { 585 menu.presentationType = PresentationType.DATA_VALUES; 586 } else { 587 menu.presentationType = PresentationType.NAVIGATION_OPTIONS; 588 } 589 } 590 menu.softKeyPreferred = (cmdDet.commandQualifier & 0x04) != 0; 591 menu.helpAvailable = (cmdDet.commandQualifier & 0x80) != 0; 592 593 mCmdParams = new SelectItemParams(cmdDet, menu, titleIconId != null); 594 595 // Load icons data if needed. 596 switch(mIconLoadState) { 597 case LOAD_NO_ICON: 598 return false; 599 case LOAD_SINGLE_ICON: 600 mIconLoader.loadIcon(titleIconId.recordNumber, this 601 .obtainMessage(MSG_ID_LOAD_ICON_DONE)); 602 break; 603 case LOAD_MULTI_ICONS: 604 int[] recordNumbers = itemsIconId.recordNumbers; 605 if (titleIconId != null) { 606 // Create a new array for all the icons (title and items). 607 recordNumbers = new int[itemsIconId.recordNumbers.length + 1]; 608 recordNumbers[0] = titleIconId.recordNumber; 609 System.arraycopy(itemsIconId.recordNumbers, 0, recordNumbers, 610 1, itemsIconId.recordNumbers.length); 611 } 612 mIconLoader.loadIcons(recordNumbers, this 613 .obtainMessage(MSG_ID_LOAD_ICON_DONE)); 614 break; 615 } 616 return true; 617 } 618 619 /** 620 * Processes EVENT_NOTIFY message from baseband. 621 * 622 * @param cmdDet Command Details container object. 623 * @param ctlvs List of ComprehensionTlv objects following Command Details 624 * object and Device Identities object within the proactive command 625 * @return true if the command is processing is pending and additional 626 * asynchronous processing is required. 627 */ 628 private boolean processEventNotify(CommandDetails cmdDet, 629 List<ComprehensionTlv> ctlvs) throws ResultException { 630 631 CatLog.d(this, "process EventNotify"); 632 633 TextMessage textMsg = new TextMessage(); 634 IconId iconId = null; 635 636 ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, 637 ctlvs); 638 textMsg.text = ValueParser.retrieveAlphaId(ctlv); 639 640 ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); 641 if (ctlv != null) { 642 iconId = ValueParser.retrieveIconId(ctlv); 643 textMsg.iconSelfExplanatory = iconId.selfExplanatory; 644 } 645 646 textMsg.responseNeeded = false; 647 mCmdParams = new DisplayTextParams(cmdDet, textMsg); 648 649 if (iconId != null) { 650 mIconLoadState = LOAD_SINGLE_ICON; 651 mIconLoader.loadIcon(iconId.recordNumber, this 652 .obtainMessage(MSG_ID_LOAD_ICON_DONE)); 653 return true; 654 } 655 return false; 656 } 657 658 /** 659 * Processes SET_UP_EVENT_LIST proactive command from the SIM card. 660 * 661 * @param cmdDet Command Details object retrieved. 662 * @param ctlvs List of ComprehensionTlv objects following Command Details 663 * object and Device Identities object within the proactive command 664 * @return true if the command is processing is pending and additional 665 * asynchronous processing is required. 666 */ 667 private boolean processSetUpEventList(CommandDetails cmdDet, 668 List<ComprehensionTlv> ctlvs) { 669 670 CatLog.d(this, "process SetUpEventList"); 671 // 672 // ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.EVENT_LIST, 673 // ctlvs); 674 // if (ctlv != null) { 675 // try { 676 // byte[] rawValue = ctlv.getRawValue(); 677 // int valueIndex = ctlv.getValueIndex(); 678 // int valueLen = ctlv.getLength(); 679 // 680 // } catch (IndexOutOfBoundsException e) {} 681 // } 682 return true; 683 } 684 685 /** 686 * Processes LAUNCH_BROWSER proactive command from the SIM card. 687 * 688 * @param cmdDet Command Details container object. 689 * @param ctlvs List of ComprehensionTlv objects following Command Details 690 * object and Device Identities object within the proactive command 691 * @return true if the command is processing is pending and additional 692 * asynchronous processing is required. 693 * @throws ResultException 694 */ 695 private boolean processLaunchBrowser(CommandDetails cmdDet, 696 List<ComprehensionTlv> ctlvs) throws ResultException { 697 698 CatLog.d(this, "process LaunchBrowser"); 699 700 TextMessage confirmMsg = new TextMessage(); 701 IconId iconId = null; 702 String url = null; 703 704 ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.URL, ctlvs); 705 if (ctlv != null) { 706 try { 707 byte[] rawValue = ctlv.getRawValue(); 708 int valueIndex = ctlv.getValueIndex(); 709 int valueLen = ctlv.getLength(); 710 if (valueLen > 0) { 711 url = GsmAlphabet.gsm8BitUnpackedToString(rawValue, 712 valueIndex, valueLen); 713 } else { 714 url = null; 715 } 716 } catch (IndexOutOfBoundsException e) { 717 throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); 718 } 719 } 720 721 // parse alpha identifier. 722 ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, ctlvs); 723 confirmMsg.text = ValueParser.retrieveAlphaId(ctlv); 724 725 // parse icon identifier 726 ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); 727 if (ctlv != null) { 728 iconId = ValueParser.retrieveIconId(ctlv); 729 confirmMsg.iconSelfExplanatory = iconId.selfExplanatory; 730 } 731 732 // parse command qualifier value. 733 LaunchBrowserMode mode; 734 switch (cmdDet.commandQualifier) { 735 case 0x00: 736 default: 737 mode = LaunchBrowserMode.LAUNCH_IF_NOT_ALREADY_LAUNCHED; 738 break; 739 case 0x02: 740 mode = LaunchBrowserMode.USE_EXISTING_BROWSER; 741 break; 742 case 0x03: 743 mode = LaunchBrowserMode.LAUNCH_NEW_BROWSER; 744 break; 745 } 746 747 mCmdParams = new LaunchBrowserParams(cmdDet, confirmMsg, url, mode); 748 749 if (iconId != null) { 750 mIconLoadState = LOAD_SINGLE_ICON; 751 mIconLoader.loadIcon(iconId.recordNumber, this 752 .obtainMessage(MSG_ID_LOAD_ICON_DONE)); 753 return true; 754 } 755 return false; 756 } 757 758 /** 759 * Processes PLAY_TONE proactive command from the SIM card. 760 * 761 * @param cmdDet Command Details container object. 762 * @param ctlvs List of ComprehensionTlv objects following Command Details 763 * object and Device Identities object within the proactive command 764 * @return true if the command is processing is pending and additional 765 * asynchronous processing is required.t 766 * @throws ResultException 767 */ 768 private boolean processPlayTone(CommandDetails cmdDet, 769 List<ComprehensionTlv> ctlvs) throws ResultException { 770 771 CatLog.d(this, "process PlayTone"); 772 773 Tone tone = null; 774 TextMessage textMsg = new TextMessage(); 775 Duration duration = null; 776 IconId iconId = null; 777 778 ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TONE, ctlvs); 779 if (ctlv != null) { 780 // Nothing to do for null objects. 781 if (ctlv.getLength() > 0) { 782 try { 783 byte[] rawValue = ctlv.getRawValue(); 784 int valueIndex = ctlv.getValueIndex(); 785 int toneVal = rawValue[valueIndex]; 786 tone = Tone.fromInt(toneVal); 787 } catch (IndexOutOfBoundsException e) { 788 throw new ResultException( 789 ResultCode.CMD_DATA_NOT_UNDERSTOOD); 790 } 791 } 792 } 793 // parse alpha identifier 794 ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, ctlvs); 795 if (ctlv != null) { 796 textMsg.text = ValueParser.retrieveAlphaId(ctlv); 797 } 798 // parse tone duration 799 ctlv = searchForTag(ComprehensionTlvTag.DURATION, ctlvs); 800 if (ctlv != null) { 801 duration = ValueParser.retrieveDuration(ctlv); 802 } 803 // parse icon identifier 804 ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); 805 if (ctlv != null) { 806 iconId = ValueParser.retrieveIconId(ctlv); 807 textMsg.iconSelfExplanatory = iconId.selfExplanatory; 808 } 809 810 boolean vibrate = (cmdDet.commandQualifier & 0x01) != 0x00; 811 812 textMsg.responseNeeded = false; 813 mCmdParams = new PlayToneParams(cmdDet, textMsg, tone, duration, vibrate); 814 815 if (iconId != null) { 816 mIconLoadState = LOAD_SINGLE_ICON; 817 mIconLoader.loadIcon(iconId.recordNumber, this 818 .obtainMessage(MSG_ID_LOAD_ICON_DONE)); 819 return true; 820 } 821 return false; 822 } 823 824 /** 825 * Processes SETUP_CALL proactive command from the SIM card. 826 * 827 * @param cmdDet Command Details object retrieved from the proactive command 828 * object 829 * @param ctlvs List of ComprehensionTlv objects following Command Details 830 * object and Device Identities object within the proactive command 831 * @return true if the command is processing is pending and additional 832 * asynchronous processing is required. 833 */ 834 private boolean processSetupCall(CommandDetails cmdDet, 835 List<ComprehensionTlv> ctlvs) throws ResultException { 836 CatLog.d(this, "process SetupCall"); 837 838 Iterator<ComprehensionTlv> iter = ctlvs.iterator(); 839 ComprehensionTlv ctlv = null; 840 // User confirmation phase message. 841 TextMessage confirmMsg = new TextMessage(); 842 // Call set up phase message. 843 TextMessage callMsg = new TextMessage(); 844 IconId confirmIconId = null; 845 IconId callIconId = null; 846 847 // get confirmation message string. 848 ctlv = searchForNextTag(ComprehensionTlvTag.ALPHA_ID, iter); 849 confirmMsg.text = ValueParser.retrieveAlphaId(ctlv); 850 851 ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); 852 if (ctlv != null) { 853 confirmIconId = ValueParser.retrieveIconId(ctlv); 854 confirmMsg.iconSelfExplanatory = confirmIconId.selfExplanatory; 855 } 856 857 // get call set up message string. 858 ctlv = searchForNextTag(ComprehensionTlvTag.ALPHA_ID, iter); 859 if (ctlv != null) { 860 callMsg.text = ValueParser.retrieveAlphaId(ctlv); 861 } 862 863 ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); 864 if (ctlv != null) { 865 callIconId = ValueParser.retrieveIconId(ctlv); 866 callMsg.iconSelfExplanatory = callIconId.selfExplanatory; 867 } 868 869 mCmdParams = new CallSetupParams(cmdDet, confirmMsg, callMsg); 870 871 if (confirmIconId != null || callIconId != null) { 872 mIconLoadState = LOAD_MULTI_ICONS; 873 int[] recordNumbers = new int[2]; 874 recordNumbers[0] = confirmIconId != null 875 ? confirmIconId.recordNumber : -1; 876 recordNumbers[1] = callIconId != null ? callIconId.recordNumber 877 : -1; 878 879 mIconLoader.loadIcons(recordNumbers, this 880 .obtainMessage(MSG_ID_LOAD_ICON_DONE)); 881 return true; 882 } 883 return false; 884 } 885 886 private boolean processProvideLocalInfo(CommandDetails cmdDet, List<ComprehensionTlv> ctlvs) 887 throws ResultException { 888 CatLog.d(this, "process ProvideLocalInfo"); 889 switch (cmdDet.commandQualifier) { 890 case DTTZ_SETTING: 891 CatLog.d(this, "PLI [DTTZ_SETTING]"); 892 mCmdParams = new CommandParams(cmdDet); 893 break; 894 case LANGUAGE_SETTING: 895 CatLog.d(this, "PLI [LANGUAGE_SETTING]"); 896 mCmdParams = new CommandParams(cmdDet); 897 break; 898 default: 899 CatLog.d(this, "PLI[" + cmdDet.commandQualifier + "] Command Not Supported"); 900 mCmdParams = new CommandParams(cmdDet); 901 throw new ResultException(ResultCode.BEYOND_TERMINAL_CAPABILITY); 902 } 903 return false; 904 } 905 906 private boolean processBIPClient(CommandDetails cmdDet, 907 List<ComprehensionTlv> ctlvs) throws ResultException { 908 AppInterface.CommandType commandType = 909 AppInterface.CommandType.fromInt(cmdDet.typeOfCommand); 910 if (commandType != null) { 911 CatLog.d(this, "process "+ commandType.name()); 912 } 913 914 TextMessage textMsg = new TextMessage(); 915 IconId iconId = null; 916 ComprehensionTlv ctlv = null; 917 boolean has_alpha_id = false; 918 919 // parse alpha identifier 920 ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, ctlvs); 921 if (ctlv != null) { 922 textMsg.text = ValueParser.retrieveAlphaId(ctlv); 923 CatLog.d(this, "alpha TLV text=" + textMsg.text); 924 has_alpha_id = true; 925 } 926 927 // parse icon identifier 928 ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); 929 if (ctlv != null) { 930 iconId = ValueParser.retrieveIconId(ctlv); 931 textMsg.iconSelfExplanatory = iconId.selfExplanatory; 932 } 933 934 textMsg.responseNeeded = false; 935 mCmdParams = new BIPClientParams(cmdDet, textMsg, has_alpha_id); 936 937 if (iconId != null) { 938 mIconLoadState = LOAD_SINGLE_ICON; 939 mIconLoader.loadIcon(iconId.recordNumber, this.obtainMessage(MSG_ID_LOAD_ICON_DONE)); 940 return true; 941 } 942 return false; 943 } 944} 945