/**
   * Processes LAUNCH_BROWSER proactive command from the SIM card.
   *
   * @param cmdDet Command Details container object.
   * @param ctlvs List of ComprehensionTlv objects following Command Details object and Device
   *     Identities object within the proactive command
   * @return true if the command is processing is pending and additional asynchronous processing is
   *     required.
   * @throws ResultException
   */
  private boolean processLaunchBrowser(CommandDetails cmdDet, List<ComprehensionTlv> ctlvs)
      throws ResultException {

    CatLog.d(this, "process LaunchBrowser");

    TextMessage confirmMsg = new TextMessage();
    IconId iconId = null;
    String url = null;

    ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.URL, ctlvs);
    if (ctlv != null) {
      try {
        byte[] rawValue = ctlv.getRawValue();
        int valueIndex = ctlv.getValueIndex();
        int valueLen = ctlv.getLength();
        if (valueLen > 0) {
          url = GsmAlphabet.gsm8BitUnpackedToString(rawValue, valueIndex, valueLen);
        } else {
          url = null;
        }
      } catch (IndexOutOfBoundsException e) {
        throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
      }
    }

    // parse alpha identifier.
    ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, ctlvs);
    confirmMsg.text = ValueParser.retrieveAlphaId(ctlv);

    // parse icon identifier
    ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
    if (ctlv != null) {
      iconId = ValueParser.retrieveIconId(ctlv);
      confirmMsg.iconSelfExplanatory = iconId.selfExplanatory;
    }

    // parse command qualifier value.
    LaunchBrowserMode mode;
    switch (cmdDet.commandQualifier) {
      case 0x00:
      default:
        mode = LaunchBrowserMode.LAUNCH_IF_NOT_ALREADY_LAUNCHED;
        break;
      case 0x02:
        mode = LaunchBrowserMode.USE_EXISTING_BROWSER;
        break;
      case 0x03:
        mode = LaunchBrowserMode.LAUNCH_NEW_BROWSER;
        break;
    }

    mCmdParams = new LaunchBrowserParams(cmdDet, confirmMsg, url, mode);

    if (iconId != null) {
      mIconLoadState = LOAD_SINGLE_ICON;
      mIconLoader.loadIcon(iconId.recordNumber, this.obtainMessage(MSG_ID_LOAD_ICON_DONE));
      return true;
    }
    return false;
  }
  /**
   * Processes EVENT_NOTIFY message from baseband.
   *
   * @param cmdDet Command Details container object.
   * @param ctlvs List of ComprehensionTlv objects following Command Details object and Device
   *     Identities object within the proactive command
   * @return true if the command is processing is pending and additional asynchronous processing is
   *     required.
   */
  private boolean processEventNotify(CommandDetails cmdDet, List<ComprehensionTlv> ctlvs)
      throws ResultException {

    CatLog.d(this, "process EventNotify");

    TextMessage textMsg = new TextMessage();
    IconId iconId = null;

    ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, ctlvs);
    textMsg.text = ValueParser.retrieveAlphaId(ctlv);

    ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
    if (ctlv != null) {
      iconId = ValueParser.retrieveIconId(ctlv);
      textMsg.iconSelfExplanatory = iconId.selfExplanatory;
    }

    textMsg.responseNeeded = false;
    mCmdParams = new DisplayTextParams(cmdDet, textMsg);

    if (iconId != null) {
      mloadIcon = true;
      mIconLoadState = LOAD_SINGLE_ICON;
      mIconLoader.loadIcon(iconId.recordNumber, this.obtainMessage(MSG_ID_LOAD_ICON_DONE));
      return true;
    }
    return false;
  }
  /**
   * Processes PLAY_TONE proactive command from the SIM card.
   *
   * @param cmdDet Command Details container object.
   * @param ctlvs List of ComprehensionTlv objects following Command Details object and Device
   *     Identities object within the proactive command
   * @return true if the command is processing is pending and additional asynchronous processing is
   *     required.t
   * @throws ResultException
   */
  private boolean processPlayTone(CommandDetails cmdDet, List<ComprehensionTlv> ctlvs)
      throws ResultException {

    CatLog.d(this, "process PlayTone");

    Tone tone = null;
    TextMessage textMsg = new TextMessage();
    Duration duration = null;
    IconId iconId = null;

    ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TONE, ctlvs);
    if (ctlv != null) {
      // Nothing to do for null objects.
      if (ctlv.getLength() > 0) {
        try {
          byte[] rawValue = ctlv.getRawValue();
          int valueIndex = ctlv.getValueIndex();
          int toneVal = rawValue[valueIndex];
          tone = Tone.fromInt(toneVal);
        } catch (IndexOutOfBoundsException e) {
          throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
        }
      }
    }
    // parse alpha identifier
    ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, ctlvs);
    if (ctlv != null) {
      textMsg.text = ValueParser.retrieveAlphaId(ctlv);
    }
    // parse tone duration
    ctlv = searchForTag(ComprehensionTlvTag.DURATION, ctlvs);
    if (ctlv != null) {
      duration = ValueParser.retrieveDuration(ctlv);
    }
    // parse icon identifier
    ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
    if (ctlv != null) {
      iconId = ValueParser.retrieveIconId(ctlv);
      textMsg.iconSelfExplanatory = iconId.selfExplanatory;
    }

    boolean vibrate = (cmdDet.commandQualifier & 0x01) != 0x00;

    textMsg.responseNeeded = false;
    mCmdParams = new PlayToneParams(cmdDet, textMsg, tone, duration, vibrate);

    if (iconId != null) {
      mIconLoadState = LOAD_SINGLE_ICON;
      mIconLoader.loadIcon(iconId.recordNumber, this.obtainMessage(MSG_ID_LOAD_ICON_DONE));
      return true;
    }
    return false;
  }
  /**
   * Processes SET_UP_IDLE_MODE_TEXT proactive command from the SIM card.
   *
   * @param cmdDet Command Details container object.
   * @param ctlvs List of ComprehensionTlv objects following Command Details object and Device
   *     Identities object within the proactive command
   * @return true if the command is processing is pending and additional asynchronous processing is
   *     required.
   * @throws ResultException
   */
  private boolean processSetUpIdleModeText(CommandDetails cmdDet, List<ComprehensionTlv> ctlvs)
      throws ResultException {

    CatLog.d(this, "process SetUpIdleModeText");

    TextMessage textMsg = new TextMessage();
    IconId iconId = null;

    ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING, ctlvs);
    if (ctlv != null) {
      textMsg.text = ValueParser.retrieveTextString(ctlv);
    }

    ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
    if (ctlv != null) {
      iconId = ValueParser.retrieveIconId(ctlv);
      textMsg.iconSelfExplanatory = iconId.selfExplanatory;
    }

    /*
     * If the tlv object doesn't contain text and the icon is not self
     * explanatory then reply with command not understood.
     */

    if (textMsg.text == null && iconId != null && !textMsg.iconSelfExplanatory) {
      throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
    }

    mCmdParams = new DisplayTextParams(cmdDet, textMsg);

    if (iconId != null) {
      mloadIcon = true;
      mIconLoadState = LOAD_SINGLE_ICON;
      mIconLoader.loadIcon(iconId.recordNumber, this.obtainMessage(MSG_ID_LOAD_ICON_DONE));
      return true;
    }
    return false;
  }
  private boolean processBIPClient(CommandDetails cmdDet, List<ComprehensionTlv> ctlvs)
      throws ResultException {
    AppInterface.CommandType commandType = AppInterface.CommandType.fromInt(cmdDet.typeOfCommand);
    if (commandType != null) {
      CatLog.d(this, "process " + commandType.name());
    }

    TextMessage textMsg = new TextMessage();
    IconId iconId = null;
    ComprehensionTlv ctlv = null;
    boolean has_alpha_id = false;

    // parse alpha identifier
    ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, ctlvs);
    if (ctlv != null) {
      textMsg.text = ValueParser.retrieveAlphaId(ctlv);
      CatLog.d(this, "alpha TLV text=" + textMsg.text);
      has_alpha_id = true;
    }

    // parse icon identifier
    ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
    if (ctlv != null) {
      iconId = ValueParser.retrieveIconId(ctlv);
      textMsg.iconSelfExplanatory = iconId.selfExplanatory;
    }

    textMsg.responseNeeded = false;
    mCmdParams = new BIPClientParams(cmdDet, textMsg, has_alpha_id);

    if (iconId != null) {
      mIconLoadState = LOAD_SINGLE_ICON;
      mIconLoader.loadIcon(iconId.recordNumber, this.obtainMessage(MSG_ID_LOAD_ICON_DONE));
      return true;
    }
    return false;
  }
  /**
   * Processes DISPLAY_TEXT proactive command from the SIM card.
   *
   * @param cmdDet Command Details container object.
   * @param ctlvs List of ComprehensionTlv objects following Command Details object and Device
   *     Identities object within the proactive command
   * @return true if the command is processing is pending and additional asynchronous processing is
   *     required.
   * @throws ResultException
   */
  private boolean processDisplayText(CommandDetails cmdDet, List<ComprehensionTlv> ctlvs)
      throws ResultException {

    CatLog.d(this, "process DisplayText");

    TextMessage textMsg = new TextMessage();
    IconId iconId = null;

    ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING, ctlvs);
    if (ctlv != null) {
      textMsg.text = ValueParser.retrieveTextString(ctlv);
    }
    // If the tlv object doesn't exist or the it is a null object reply
    // with command not understood.
    if (textMsg.text == null) {
      throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
    }

    ctlv = searchForTag(ComprehensionTlvTag.IMMEDIATE_RESPONSE, ctlvs);
    if (ctlv != null) {
      textMsg.responseNeeded = false;
    }
    // parse icon identifier
    ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
    if (ctlv != null) {
      iconId = ValueParser.retrieveIconId(ctlv);
      textMsg.iconSelfExplanatory = iconId.selfExplanatory;
    }
    // parse tone duration
    ctlv = searchForTag(ComprehensionTlvTag.DURATION, ctlvs);
    if (ctlv != null) {
      textMsg.duration = ValueParser.retrieveDuration(ctlv);
    }

    // Parse command qualifier parameters.
    textMsg.isHighPriority = (cmdDet.commandQualifier & 0x01) != 0;
    textMsg.userClear = (cmdDet.commandQualifier & 0x80) != 0;

    mCmdParams = new DisplayTextParams(cmdDet, textMsg);

    if (iconId != null) {
      mloadIcon = true;
      mIconLoadState = LOAD_SINGLE_ICON;
      mIconLoader.loadIcon(iconId.recordNumber, this.obtainMessage(MSG_ID_LOAD_ICON_DONE));
      return true;
    }
    return false;
  }
  /**
   * Processes SETUP_CALL proactive command from the SIM card.
   *
   * @param cmdDet Command Details object retrieved from the proactive command object
   * @param ctlvs List of ComprehensionTlv objects following Command Details object and Device
   *     Identities object within the proactive command
   * @return true if the command is processing is pending and additional asynchronous processing is
   *     required.
   */
  private boolean processSetupCall(CommandDetails cmdDet, List<ComprehensionTlv> ctlvs)
      throws ResultException {
    CatLog.d(this, "process SetupCall");

    Iterator<ComprehensionTlv> iter = ctlvs.iterator();
    ComprehensionTlv ctlv = null;
    // User confirmation phase message.
    TextMessage confirmMsg = new TextMessage();
    // Call set up phase message.
    TextMessage callMsg = new TextMessage();
    IconId confirmIconId = null;
    IconId callIconId = null;

    // get confirmation message string.
    ctlv = searchForNextTag(ComprehensionTlvTag.ALPHA_ID, iter);
    confirmMsg.text = ValueParser.retrieveAlphaId(ctlv);

    ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
    if (ctlv != null) {
      confirmIconId = ValueParser.retrieveIconId(ctlv);
      confirmMsg.iconSelfExplanatory = confirmIconId.selfExplanatory;
    }

    // get call set up message string.
    ctlv = searchForNextTag(ComprehensionTlvTag.ALPHA_ID, iter);
    if (ctlv != null) {
      callMsg.text = ValueParser.retrieveAlphaId(ctlv);
    }

    ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
    if (ctlv != null) {
      callIconId = ValueParser.retrieveIconId(ctlv);
      callMsg.iconSelfExplanatory = callIconId.selfExplanatory;
    }

    mCmdParams = new CallSetupParams(cmdDet, confirmMsg, callMsg);

    if (confirmIconId != null || callIconId != null) {
      mIconLoadState = LOAD_MULTI_ICONS;
      int[] recordNumbers = new int[2];
      recordNumbers[0] = confirmIconId != null ? confirmIconId.recordNumber : -1;
      recordNumbers[1] = callIconId != null ? callIconId.recordNumber : -1;

      mIconLoader.loadIcons(recordNumbers, this.obtainMessage(MSG_ID_LOAD_ICON_DONE));
      return true;
    }
    return false;
  }