/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.telephony.cat; import android.graphics.Bitmap; import android.os.Handler; import android.os.Message; import com.android.internal.telephony.GsmAlphabet; import com.android.internal.telephony.IccFileHandler; import java.util.Iterator; import java.util.List; /** * Factory class, used for decoding raw byte arrays, received from baseband, * into a CommandParams object. * */ class CommandParamsFactory extends Handler { private static CommandParamsFactory sInstance = null; private IconLoader mIconLoader; private CommandParams mCmdParams = null; private int mIconLoadState = LOAD_NO_ICON; private RilMessageDecoder mCaller = null; // constants static final int MSG_ID_LOAD_ICON_DONE = 1; // loading icons state parameters. static final int LOAD_NO_ICON = 0; static final int LOAD_SINGLE_ICON = 1; static final int LOAD_MULTI_ICONS = 2; // Command Qualifier values for refresh command static final int REFRESH_NAA_INIT_AND_FULL_FILE_CHANGE = 0x00; static final int REFRESH_NAA_INIT_AND_FILE_CHANGE = 0x02; static final int REFRESH_NAA_INIT = 0x03; static final int REFRESH_UICC_RESET = 0x04; // Command Qualifier values for PLI command static final int DTTZ_SETTING = 0x03; static final int LANGUAGE_SETTING = 0x04; static synchronized CommandParamsFactory getInstance(RilMessageDecoder caller, IccFileHandler fh) { if (sInstance != null) { return sInstance; } if (fh != null) { return new CommandParamsFactory(caller, fh); } return null; } private CommandParamsFactory(RilMessageDecoder caller, IccFileHandler fh) { mCaller = caller; mIconLoader = IconLoader.getInstance(this, fh); } private CommandDetails processCommandDetails(List ctlvs) { CommandDetails cmdDet = null; if (ctlvs != null) { // Search for the Command Details object. ComprehensionTlv ctlvCmdDet = searchForTag( ComprehensionTlvTag.COMMAND_DETAILS, ctlvs); if (ctlvCmdDet != null) { try { cmdDet = ValueParser.retrieveCommandDetails(ctlvCmdDet); } catch (ResultException e) { CatLog.d(this, "processCommandDetails: Failed to procees command details e=" + e); } } } return cmdDet; } void make(BerTlv berTlv) { if (berTlv == null) { return; } // reset global state parameters. mCmdParams = null; mIconLoadState = LOAD_NO_ICON; // only proactive command messages are processed. if (berTlv.getTag() != BerTlv.BER_PROACTIVE_COMMAND_TAG) { sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD); return; } boolean cmdPending = false; List ctlvs = berTlv.getComprehensionTlvs(); // process command dtails from the tlv list. CommandDetails cmdDet = processCommandDetails(ctlvs); if (cmdDet == null) { sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD); return; } // extract command type enumeration from the raw value stored inside // the Command Details object. AppInterface.CommandType cmdType = AppInterface.CommandType .fromInt(cmdDet.typeOfCommand); if (cmdType == null) { // This PROACTIVE COMMAND is presently not handled. Hence set // result code as BEYOND_TERMINAL_CAPABILITY in TR. mCmdParams = new CommandParams(cmdDet); sendCmdParams(ResultCode.BEYOND_TERMINAL_CAPABILITY); return; } try { switch (cmdType) { case SET_UP_MENU: cmdPending = processSelectItem(cmdDet, ctlvs); break; case SELECT_ITEM: cmdPending = processSelectItem(cmdDet, ctlvs); break; case DISPLAY_TEXT: cmdPending = processDisplayText(cmdDet, ctlvs); break; case SET_UP_IDLE_MODE_TEXT: cmdPending = processSetUpIdleModeText(cmdDet, ctlvs); break; case GET_INKEY: cmdPending = processGetInkey(cmdDet, ctlvs); break; case GET_INPUT: cmdPending = processGetInput(cmdDet, ctlvs); break; case SEND_DTMF: case SEND_SMS: case SEND_SS: case SEND_USSD: cmdPending = processEventNotify(cmdDet, ctlvs); break; case SET_UP_CALL: cmdPending = processSetupCall(cmdDet, ctlvs); break; case REFRESH: processRefresh(cmdDet, ctlvs); cmdPending = false; break; case LAUNCH_BROWSER: cmdPending = processLaunchBrowser(cmdDet, ctlvs); break; case PLAY_TONE: cmdPending = processPlayTone(cmdDet, ctlvs); break; case PROVIDE_LOCAL_INFORMATION: cmdPending = processProvideLocalInfo(cmdDet, ctlvs); break; case OPEN_CHANNEL: case CLOSE_CHANNEL: case RECEIVE_DATA: case SEND_DATA: cmdPending = processBIPClient(cmdDet, ctlvs); break; default: // unsupported proactive commands mCmdParams = new CommandParams(cmdDet); sendCmdParams(ResultCode.BEYOND_TERMINAL_CAPABILITY); return; } } catch (ResultException e) { CatLog.d(this, "make: caught ResultException e=" + e); mCmdParams = new CommandParams(cmdDet); sendCmdParams(e.result()); return; } if (!cmdPending) { sendCmdParams(ResultCode.OK); } } @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_ID_LOAD_ICON_DONE: sendCmdParams(setIcons(msg.obj)); break; } } private ResultCode setIcons(Object data) { Bitmap[] icons = null; int iconIndex = 0; if (data == null) { return ResultCode.PRFRMD_ICON_NOT_DISPLAYED; } switch(mIconLoadState) { case LOAD_SINGLE_ICON: mCmdParams.setIcon((Bitmap) data); break; case LOAD_MULTI_ICONS: icons = (Bitmap[]) data; // set each item icon. for (Bitmap icon : icons) { mCmdParams.setIcon(icon); } break; } return ResultCode.OK; } private void sendCmdParams(ResultCode resCode) { mCaller.sendMsgParamsDecoded(resCode, mCmdParams); } /** * Search for a COMPREHENSION-TLV object with the given tag from a list * * @param tag A tag to search for * @param ctlvs List of ComprehensionTlv objects used to search in * * @return A ComprehensionTlv object that has the tag value of {@code tag}. * If no object is found with the tag, null is returned. */ private ComprehensionTlv searchForTag(ComprehensionTlvTag tag, List ctlvs) { Iterator iter = ctlvs.iterator(); return searchForNextTag(tag, iter); } /** * Search for the next COMPREHENSION-TLV object with the given tag from a * list iterated by {@code iter}. {@code iter} points to the object next to * the found object when this method returns. Used for searching the same * list for similar tags, usually item id. * * @param tag A tag to search for * @param iter Iterator for ComprehensionTlv objects used for search * * @return A ComprehensionTlv object that has the tag value of {@code tag}. * If no object is found with the tag, null is returned. */ private ComprehensionTlv searchForNextTag(ComprehensionTlvTag tag, Iterator iter) { int tagValue = tag.value(); while (iter.hasNext()) { ComprehensionTlv ctlv = iter.next(); if (ctlv.getTag() == tagValue) { return ctlv; } } return null; } /** * 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 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) { 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 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); } // load icons only when text exist. if (textMsg.text != null) { ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); if (ctlv != null) { iconId = ValueParser.retrieveIconId(ctlv); textMsg.iconSelfExplanatory = iconId.selfExplanatory; } } mCmdParams = new DisplayTextParams(cmdDet, textMsg); if (iconId != null) { mIconLoadState = LOAD_SINGLE_ICON; mIconLoader.loadIcon(iconId.recordNumber, this .obtainMessage(MSG_ID_LOAD_ICON_DONE)); return true; } return false; } /** * Processes GET_INKEY 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 processGetInkey(CommandDetails cmdDet, List ctlvs) throws ResultException { CatLog.d(this, "process GetInkey"); Input input = new Input(); IconId iconId = null; ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING, ctlvs); if (ctlv != null) { input.text = ValueParser.retrieveTextString(ctlv); } else { throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); } // parse icon identifier ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); if (ctlv != null) { iconId = ValueParser.retrieveIconId(ctlv); } // parse duration ctlv = searchForTag(ComprehensionTlvTag.DURATION, ctlvs); if (ctlv != null) { input.duration = ValueParser.retrieveDuration(ctlv); } input.minLen = 1; input.maxLen = 1; input.digitOnly = (cmdDet.commandQualifier & 0x01) == 0; input.ucs2 = (cmdDet.commandQualifier & 0x02) != 0; input.yesNo = (cmdDet.commandQualifier & 0x04) != 0; input.helpAvailable = (cmdDet.commandQualifier & 0x80) != 0; input.echo = true; mCmdParams = new GetInputParams(cmdDet, input); if (iconId != null) { mIconLoadState = LOAD_SINGLE_ICON; mIconLoader.loadIcon(iconId.recordNumber, this .obtainMessage(MSG_ID_LOAD_ICON_DONE)); return true; } return false; } /** * Processes GET_INPUT 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 processGetInput(CommandDetails cmdDet, List ctlvs) throws ResultException { CatLog.d(this, "process GetInput"); Input input = new Input(); IconId iconId = null; ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING, ctlvs); if (ctlv != null) { input.text = ValueParser.retrieveTextString(ctlv); } else { throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); } ctlv = searchForTag(ComprehensionTlvTag.RESPONSE_LENGTH, ctlvs); if (ctlv != null) { try { byte[] rawValue = ctlv.getRawValue(); int valueIndex = ctlv.getValueIndex(); input.minLen = rawValue[valueIndex] & 0xff; input.maxLen = rawValue[valueIndex + 1] & 0xff; } catch (IndexOutOfBoundsException e) { throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); } } else { throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); } ctlv = searchForTag(ComprehensionTlvTag.DEFAULT_TEXT, ctlvs); if (ctlv != null) { input.defaultText = ValueParser.retrieveTextString(ctlv); } // parse icon identifier ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); if (ctlv != null) { iconId = ValueParser.retrieveIconId(ctlv); } input.digitOnly = (cmdDet.commandQualifier & 0x01) == 0; input.ucs2 = (cmdDet.commandQualifier & 0x02) != 0; input.echo = (cmdDet.commandQualifier & 0x04) == 0; input.packed = (cmdDet.commandQualifier & 0x08) != 0; input.helpAvailable = (cmdDet.commandQualifier & 0x80) != 0; mCmdParams = new GetInputParams(cmdDet, input); if (iconId != null) { mIconLoadState = LOAD_SINGLE_ICON; mIconLoader.loadIcon(iconId.recordNumber, this .obtainMessage(MSG_ID_LOAD_ICON_DONE)); return true; } return false; } /** * Processes REFRESH 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 */ private boolean processRefresh(CommandDetails cmdDet, List ctlvs) { CatLog.d(this, "process Refresh"); // REFRESH proactive command is rerouted by the baseband and handled by // the telephony layer. IDLE TEXT should be removed for a REFRESH command // with "initialization" or "reset" switch (cmdDet.commandQualifier) { case REFRESH_NAA_INIT_AND_FULL_FILE_CHANGE: case REFRESH_NAA_INIT_AND_FILE_CHANGE: case REFRESH_NAA_INIT: case REFRESH_UICC_RESET: mCmdParams = new DisplayTextParams(cmdDet, null); break; } return false; } /** * Processes SELECT_ITEM 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 processSelectItem(CommandDetails cmdDet, List ctlvs) throws ResultException { CatLog.d(this, "process SelectItem"); Menu menu = new Menu(); IconId titleIconId = null; ItemsIconId itemsIconId = null; Iterator iter = ctlvs.iterator(); ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, ctlvs); if (ctlv != null) { menu.title = ValueParser.retrieveAlphaId(ctlv); } while (true) { ctlv = searchForNextTag(ComprehensionTlvTag.ITEM, iter); if (ctlv != null) { menu.items.add(ValueParser.retrieveItem(ctlv)); } else { break; } } // We must have at least one menu item. if (menu.items.size() == 0) { throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); } ctlv = searchForTag(ComprehensionTlvTag.ITEM_ID, ctlvs); if (ctlv != null) { // CAT items are listed 1...n while list start at 0, need to // subtract one. menu.defaultItem = ValueParser.retrieveItemId(ctlv) - 1; } ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); if (ctlv != null) { mIconLoadState = LOAD_SINGLE_ICON; titleIconId = ValueParser.retrieveIconId(ctlv); menu.titleIconSelfExplanatory = titleIconId.selfExplanatory; } ctlv = searchForTag(ComprehensionTlvTag.ITEM_ICON_ID_LIST, ctlvs); if (ctlv != null) { mIconLoadState = LOAD_MULTI_ICONS; itemsIconId = ValueParser.retrieveItemsIconId(ctlv); menu.itemsIconSelfExplanatory = itemsIconId.selfExplanatory; } boolean presentTypeSpecified = (cmdDet.commandQualifier & 0x01) != 0; if (presentTypeSpecified) { if ((cmdDet.commandQualifier & 0x02) == 0) { menu.presentationType = PresentationType.DATA_VALUES; } else { menu.presentationType = PresentationType.NAVIGATION_OPTIONS; } } menu.softKeyPreferred = (cmdDet.commandQualifier & 0x04) != 0; menu.helpAvailable = (cmdDet.commandQualifier & 0x80) != 0; mCmdParams = new SelectItemParams(cmdDet, menu, titleIconId != null); // Load icons data if needed. switch(mIconLoadState) { case LOAD_NO_ICON: return false; case LOAD_SINGLE_ICON: mIconLoader.loadIcon(titleIconId.recordNumber, this .obtainMessage(MSG_ID_LOAD_ICON_DONE)); break; case LOAD_MULTI_ICONS: int[] recordNumbers = itemsIconId.recordNumbers; if (titleIconId != null) { // Create a new array for all the icons (title and items). recordNumbers = new int[itemsIconId.recordNumbers.length + 1]; recordNumbers[0] = titleIconId.recordNumber; System.arraycopy(itemsIconId.recordNumbers, 0, recordNumbers, 1, itemsIconId.recordNumbers.length); } mIconLoader.loadIcons(recordNumbers, this .obtainMessage(MSG_ID_LOAD_ICON_DONE)); break; } return true; } /** * 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 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) { mIconLoadState = LOAD_SINGLE_ICON; mIconLoader.loadIcon(iconId.recordNumber, this .obtainMessage(MSG_ID_LOAD_ICON_DONE)); return true; } return false; } /** * Processes SET_UP_EVENT_LIST proactive command from the SIM card. * * @param cmdDet Command Details object retrieved. * @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 processSetUpEventList(CommandDetails cmdDet, List ctlvs) { CatLog.d(this, "process SetUpEventList"); // // ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.EVENT_LIST, // ctlvs); // if (ctlv != null) { // try { // byte[] rawValue = ctlv.getRawValue(); // int valueIndex = ctlv.getValueIndex(); // int valueLen = ctlv.getLength(); // // } catch (IndexOutOfBoundsException e) {} // } return true; } /** * 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 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 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 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 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 ctlvs) throws ResultException { CatLog.d(this, "process SetupCall"); Iterator 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; } private boolean processProvideLocalInfo(CommandDetails cmdDet, List ctlvs) throws ResultException { CatLog.d(this, "process ProvideLocalInfo"); switch (cmdDet.commandQualifier) { case DTTZ_SETTING: CatLog.d(this, "PLI [DTTZ_SETTING]"); mCmdParams = new CommandParams(cmdDet); break; case LANGUAGE_SETTING: CatLog.d(this, "PLI [LANGUAGE_SETTING]"); mCmdParams = new CommandParams(cmdDet); break; default: CatLog.d(this, "PLI[" + cmdDet.commandQualifier + "] Command Not Supported"); mCmdParams = new CommandParams(cmdDet); throw new ResultException(ResultCode.BEYOND_TERMINAL_CAPABILITY); } return false; } private boolean processBIPClient(CommandDetails cmdDet, List 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; } }