From 35dbaf2c62073054790724fb0e06785a2c82b759 Mon Sep 17 00:00:00 2001 From: Alex Yakavenka Date: Mon, 12 Jul 2010 14:29:50 -0700 Subject: Cat: Move Stk imlpementation into Cat folder Change-Id: I18e9e2cd11570b7ca3692fa08543fd5f1db2d1bd --- .../internal/telephony/cat/AppInterface.java | 90 +++ .../com/android/internal/telephony/cat/BerTlv.java | 113 +++ .../internal/telephony/cat/CatCmdMessage.java | 175 +++++ .../internal/telephony/cat/CatException.java | 31 + .../com/android/internal/telephony/cat/CatLog.java | 41 + .../internal/telephony/cat/CatResponseMessage.java | 54 ++ .../android/internal/telephony/cat/CatService.java | 635 +++++++++++++++ .../internal/telephony/cat/CommandDetails.java | 106 +++ .../internal/telephony/cat/CommandParams.java | 169 ++++ .../telephony/cat/CommandParamsFactory.java | 866 +++++++++++++++++++++ .../internal/telephony/cat/ComprehensionTlv.java | 175 +++++ .../android/internal/telephony/cat/Duration.java | 79 ++ .../android/internal/telephony/cat/FontSize.java | 50 ++ .../android/internal/telephony/cat/IconLoader.java | 362 +++++++++ .../internal/telephony/cat/ImageDescriptor.java | 77 ++ .../com/android/internal/telephony/cat/Input.java | 97 +++ .../com/android/internal/telephony/cat/Item.java | 71 ++ .../internal/telephony/cat/LaunchBrowserMode.java | 35 + .../com/android/internal/telephony/cat/Menu.java | 105 +++ .../internal/telephony/cat/PresentationType.java | 32 + .../internal/telephony/cat/ResponseData.java | 140 ++++ .../android/internal/telephony/cat/ResultCode.java | 186 +++++ .../internal/telephony/cat/ResultException.java | 76 ++ .../internal/telephony/cat/RilMessageDecoder.java | 174 +++++ .../internal/telephony/cat/TextAlignment.java | 52 ++ .../internal/telephony/cat/TextAttribute.java | 49 ++ .../android/internal/telephony/cat/TextColor.java | 63 ++ .../internal/telephony/cat/TextMessage.java | 71 ++ .../com/android/internal/telephony/cat/Tone.java | 190 +++++ .../internal/telephony/cat/ToneSettings.java | 62 ++ .../internal/telephony/cat/ValueParser.java | 336 ++++++++ .../android/internal/telephony/cat/package.html | 5 + .../internal/telephony/gsm/stk/AppInterface.java | 90 --- .../android/internal/telephony/gsm/stk/BerTlv.java | 113 --- .../internal/telephony/gsm/stk/CommandDetails.java | 106 --- .../internal/telephony/gsm/stk/CommandParams.java | 169 ---- .../telephony/gsm/stk/CommandParamsFactory.java | 866 --------------------- .../telephony/gsm/stk/ComprehensionTlv.java | 175 ----- .../internal/telephony/gsm/stk/Duration.java | 79 -- .../internal/telephony/gsm/stk/FontSize.java | 50 -- .../internal/telephony/gsm/stk/IconLoader.java | 362 --------- .../telephony/gsm/stk/ImageDescriptor.java | 77 -- .../android/internal/telephony/gsm/stk/Input.java | 97 --- .../android/internal/telephony/gsm/stk/Item.java | 71 -- .../telephony/gsm/stk/LaunchBrowserMode.java | 35 - .../android/internal/telephony/gsm/stk/Menu.java | 105 --- .../telephony/gsm/stk/PresentationType.java | 32 - .../internal/telephony/gsm/stk/ResponseData.java | 140 ---- .../internal/telephony/gsm/stk/ResultCode.java | 186 ----- .../telephony/gsm/stk/ResultException.java | 76 -- .../telephony/gsm/stk/RilMessageDecoder.java | 174 ----- .../internal/telephony/gsm/stk/StkCmdMessage.java | 175 ----- .../internal/telephony/gsm/stk/StkException.java | 31 - .../android/internal/telephony/gsm/stk/StkLog.java | 41 - .../telephony/gsm/stk/StkResponseMessage.java | 54 -- .../internal/telephony/gsm/stk/StkService.java | 635 --------------- .../internal/telephony/gsm/stk/TextAlignment.java | 52 -- .../internal/telephony/gsm/stk/TextAttribute.java | 49 -- .../internal/telephony/gsm/stk/TextColor.java | 63 -- .../internal/telephony/gsm/stk/TextMessage.java | 71 -- .../android/internal/telephony/gsm/stk/Tone.java | 190 ----- .../internal/telephony/gsm/stk/ToneSettings.java | 62 -- .../internal/telephony/gsm/stk/ValueParser.java | 336 -------- .../internal/telephony/gsm/stk/package.html | 5 - 64 files changed, 4767 insertions(+), 4767 deletions(-) create mode 100644 telephony/java/com/android/internal/telephony/cat/AppInterface.java create mode 100644 telephony/java/com/android/internal/telephony/cat/BerTlv.java create mode 100644 telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java create mode 100644 telephony/java/com/android/internal/telephony/cat/CatException.java create mode 100644 telephony/java/com/android/internal/telephony/cat/CatLog.java create mode 100644 telephony/java/com/android/internal/telephony/cat/CatResponseMessage.java create mode 100644 telephony/java/com/android/internal/telephony/cat/CatService.java create mode 100644 telephony/java/com/android/internal/telephony/cat/CommandDetails.java create mode 100644 telephony/java/com/android/internal/telephony/cat/CommandParams.java create mode 100644 telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java create mode 100644 telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java create mode 100644 telephony/java/com/android/internal/telephony/cat/Duration.java create mode 100644 telephony/java/com/android/internal/telephony/cat/FontSize.java create mode 100644 telephony/java/com/android/internal/telephony/cat/IconLoader.java create mode 100644 telephony/java/com/android/internal/telephony/cat/ImageDescriptor.java create mode 100644 telephony/java/com/android/internal/telephony/cat/Input.java create mode 100644 telephony/java/com/android/internal/telephony/cat/Item.java create mode 100644 telephony/java/com/android/internal/telephony/cat/LaunchBrowserMode.java create mode 100644 telephony/java/com/android/internal/telephony/cat/Menu.java create mode 100644 telephony/java/com/android/internal/telephony/cat/PresentationType.java create mode 100644 telephony/java/com/android/internal/telephony/cat/ResponseData.java create mode 100644 telephony/java/com/android/internal/telephony/cat/ResultCode.java create mode 100644 telephony/java/com/android/internal/telephony/cat/ResultException.java create mode 100644 telephony/java/com/android/internal/telephony/cat/RilMessageDecoder.java create mode 100644 telephony/java/com/android/internal/telephony/cat/TextAlignment.java create mode 100644 telephony/java/com/android/internal/telephony/cat/TextAttribute.java create mode 100644 telephony/java/com/android/internal/telephony/cat/TextColor.java create mode 100644 telephony/java/com/android/internal/telephony/cat/TextMessage.java create mode 100644 telephony/java/com/android/internal/telephony/cat/Tone.java create mode 100644 telephony/java/com/android/internal/telephony/cat/ToneSettings.java create mode 100644 telephony/java/com/android/internal/telephony/cat/ValueParser.java create mode 100644 telephony/java/com/android/internal/telephony/cat/package.html delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/BerTlv.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/Duration.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/FontSize.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/IconLoader.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/ImageDescriptor.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/Input.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/Item.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/LaunchBrowserMode.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/Menu.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/PresentationType.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/ResultCode.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/ResultException.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/RilMessageDecoder.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/StkException.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/StkResponseMessage.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/StkService.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/TextAlignment.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/TextAttribute.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/TextColor.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/TextMessage.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/Tone.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java delete mode 100644 telephony/java/com/android/internal/telephony/gsm/stk/package.html (limited to 'telephony') diff --git a/telephony/java/com/android/internal/telephony/cat/AppInterface.java b/telephony/java/com/android/internal/telephony/cat/AppInterface.java new file mode 100644 index 0000000..58f1f97 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/AppInterface.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2006 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.gsm.stk; + +/** + * Interface for communication between STK App and STK Telephony + * + * {@hide} + */ +public interface AppInterface { + + /* + * Intent's actions which are broadcasted by the Telephony once a new STK + * proactive command, session end arrive. + */ + public static final String STK_CMD_ACTION = + "android.intent.action.stk.command"; + public static final String STK_SESSION_END_ACTION = + "android.intent.action.stk.session_end"; + + /* + * Callback function from app to telephony to pass a result code and user's + * input back to the SIM. + */ + void onCmdResponse(StkResponseMessage resMsg); + + /* + * Enumeration for representing "Type of Command" of proactive commands. + * Those are the only commands which are supported by the Telephony. Any app + * implementation should support those. + */ + public static enum CommandType { + DISPLAY_TEXT(0x21), + GET_INKEY(0x22), + GET_INPUT(0x23), + LAUNCH_BROWSER(0x15), + PLAY_TONE(0x20), + REFRESH(0x01), + SELECT_ITEM(0x24), + SEND_SS(0x11), + SEND_USSD(0x12), + SEND_SMS(0x13), + SEND_DTMF(0x14), + SET_UP_EVENT_LIST(0x05), + SET_UP_IDLE_MODE_TEXT(0x28), + SET_UP_MENU(0x25), + SET_UP_CALL(0x10); + + private int mValue; + + CommandType(int value) { + mValue = value; + } + + public int value() { + return mValue; + } + + /** + * Create a CommandType object. + * + * @param value Integer value to be converted to a CommandType object. + * @return CommandType object whose "Type of Command" value is {@code + * value}. If no CommandType object has that value, null is + * returned. + */ + public static CommandType fromInt(int value) { + for (CommandType e : CommandType.values()) { + if (e.mValue == value) { + return e; + } + } + return null; + } + } +} diff --git a/telephony/java/com/android/internal/telephony/cat/BerTlv.java b/telephony/java/com/android/internal/telephony/cat/BerTlv.java new file mode 100644 index 0000000..19d3279 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/BerTlv.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2006 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.gsm.stk; + +import java.util.List; + +/** + * Class for representing BER-TLV objects. + * + * @see "ETSI TS 102 223 Annex C" for more information. + * + * {@hide} + */ +class BerTlv { + private int mTag = BER_UNKNOWN_TAG; + private List mCompTlvs = null; + + public static final int BER_UNKNOWN_TAG = 0x00; + public static final int BER_PROACTIVE_COMMAND_TAG = 0xd0; + public static final int BER_MENU_SELECTION_TAG = 0xd3; + public static final int BER_EVENT_DOWNLOAD_TAG = 0xd6; + + private BerTlv(int tag, List ctlvs) { + mTag = tag; + mCompTlvs = ctlvs; + } + + /** + * Gets a list of ComprehensionTlv objects contained in this BER-TLV object. + * + * @return A list of COMPREHENSION-TLV object + */ + public List getComprehensionTlvs() { + return mCompTlvs; + } + + /** + * Gets a tag id of the BER-TLV object. + * + * @return A tag integer. + */ + public int getTag() { + return mTag; + } + + /** + * Decodes a BER-TLV object from a byte array. + * + * @param data A byte array to decode from + * @return A BER-TLV object decoded + * @throws ResultException + */ + public static BerTlv decode(byte[] data) throws ResultException { + int curIndex = 0; + int endIndex = data.length; + int tag, length = 0; + + try { + /* tag */ + tag = data[curIndex++] & 0xff; + if (tag == BER_PROACTIVE_COMMAND_TAG) { + /* length */ + int temp = data[curIndex++] & 0xff; + if (temp < 0x80) { + length = temp; + } else if (temp == 0x81) { + temp = data[curIndex++] & 0xff; + if (temp < 0x80) { + throw new ResultException( + ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + length = temp; + } else { + throw new ResultException( + ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + } else { + if (ComprehensionTlvTag.COMMAND_DETAILS.value() == (tag & ~0x80)) { + tag = BER_UNKNOWN_TAG; + curIndex = 0; + } + } + } catch (IndexOutOfBoundsException e) { + throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); + } catch (ResultException e) { + throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + + /* COMPREHENSION-TLVs */ + if (endIndex - curIndex < length) { + throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + + List ctlvs = ComprehensionTlv.decodeMany(data, + curIndex); + + return new BerTlv(tag, ctlvs); + } +} diff --git a/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java b/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java new file mode 100644 index 0000000..5425a43 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java @@ -0,0 +1,175 @@ +/* + * 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.gsm.stk; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Class used to pass STK messages from telephony to application. Application + * should call getXXX() to get commands's specific values. + * + */ +public class StkCmdMessage implements Parcelable { + // members + CommandDetails mCmdDet; + private TextMessage mTextMsg; + private Menu mMenu; + private Input mInput; + private BrowserSettings mBrowserSettings = null; + private ToneSettings mToneSettings = null; + private CallSettings mCallSettings = null; + + /* + * Container for Launch Browser command settings. + */ + public class BrowserSettings { + public String url; + public LaunchBrowserMode mode; + } + + /* + * Container for Call Setup command settings. + */ + public class CallSettings { + public TextMessage confirmMsg; + public TextMessage callMsg; + } + + StkCmdMessage(CommandParams cmdParams) { + mCmdDet = cmdParams.cmdDet; + switch(getCmdType()) { + case SET_UP_MENU: + case SELECT_ITEM: + mMenu = ((SelectItemParams) cmdParams).menu; + break; + case DISPLAY_TEXT: + case SET_UP_IDLE_MODE_TEXT: + case SEND_DTMF: + case SEND_SMS: + case SEND_SS: + case SEND_USSD: + mTextMsg = ((DisplayTextParams) cmdParams).textMsg; + break; + case GET_INPUT: + case GET_INKEY: + mInput = ((GetInputParams) cmdParams).input; + break; + case LAUNCH_BROWSER: + mTextMsg = ((LaunchBrowserParams) cmdParams).confirmMsg; + mBrowserSettings = new BrowserSettings(); + mBrowserSettings.url = ((LaunchBrowserParams) cmdParams).url; + mBrowserSettings.mode = ((LaunchBrowserParams) cmdParams).mode; + break; + case PLAY_TONE: + PlayToneParams params = (PlayToneParams) cmdParams; + mToneSettings = params.settings; + mTextMsg = params.textMsg; + break; + case SET_UP_CALL: + mCallSettings = new CallSettings(); + mCallSettings.confirmMsg = ((CallSetupParams) cmdParams).confirmMsg; + mCallSettings.callMsg = ((CallSetupParams) cmdParams).callMsg; + break; + } + } + + public StkCmdMessage(Parcel in) { + mCmdDet = in.readParcelable(null); + mTextMsg = in.readParcelable(null); + mMenu = in.readParcelable(null); + mInput = in.readParcelable(null); + switch (getCmdType()) { + case LAUNCH_BROWSER: + mBrowserSettings = new BrowserSettings(); + mBrowserSettings.url = in.readString(); + mBrowserSettings.mode = LaunchBrowserMode.values()[in.readInt()]; + break; + case PLAY_TONE: + mToneSettings = in.readParcelable(null); + break; + case SET_UP_CALL: + mCallSettings = new CallSettings(); + mCallSettings.confirmMsg = in.readParcelable(null); + mCallSettings.callMsg = in.readParcelable(null); + break; + } + } + + public void writeToParcel(Parcel dest, int flags) { + dest.writeParcelable(mCmdDet, 0); + dest.writeParcelable(mTextMsg, 0); + dest.writeParcelable(mMenu, 0); + dest.writeParcelable(mInput, 0); + switch(getCmdType()) { + case LAUNCH_BROWSER: + dest.writeString(mBrowserSettings.url); + dest.writeInt(mBrowserSettings.mode.ordinal()); + break; + case PLAY_TONE: + dest.writeParcelable(mToneSettings, 0); + break; + case SET_UP_CALL: + dest.writeParcelable(mCallSettings.confirmMsg, 0); + dest.writeParcelable(mCallSettings.callMsg, 0); + break; + } + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public StkCmdMessage createFromParcel(Parcel in) { + return new StkCmdMessage(in); + } + + public StkCmdMessage[] newArray(int size) { + return new StkCmdMessage[size]; + } + }; + + public int describeContents() { + return 0; + } + + /* external API to be used by application */ + public AppInterface.CommandType getCmdType() { + return AppInterface.CommandType.fromInt(mCmdDet.typeOfCommand); + } + + public Menu getMenu() { + return mMenu; + } + + public Input geInput() { + return mInput; + } + + public TextMessage geTextMessage() { + return mTextMsg; + } + + public BrowserSettings getBrowserSettings() { + return mBrowserSettings; + } + + public ToneSettings getToneSettings() { + return mToneSettings; + } + + public CallSettings getCallSettings() { + return mCallSettings; + } +} diff --git a/telephony/java/com/android/internal/telephony/cat/CatException.java b/telephony/java/com/android/internal/telephony/cat/CatException.java new file mode 100644 index 0000000..86de366 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/CatException.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2006 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.gsm.stk; + +import android.util.AndroidException; + + +/** + * Base class for all the exceptions in STK service. + * + * {@hide} + */ +class StkException extends AndroidException { + public StkException() { + super(); + } +} diff --git a/telephony/java/com/android/internal/telephony/cat/CatLog.java b/telephony/java/com/android/internal/telephony/cat/CatLog.java new file mode 100644 index 0000000..bd6bc8f --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/CatLog.java @@ -0,0 +1,41 @@ +/* + * 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.gsm.stk; + +import android.util.Log; + +public abstract class StkLog { + static final boolean DEBUG = true; + + public static void d(Object caller, String msg) { + if (!DEBUG) { + return; + } + + String className = caller.getClass().getName(); + Log.d("STK", className.substring(className.lastIndexOf('.') + 1) + ": " + + msg); + } + + public static void d(String caller, String msg) { + if (!DEBUG) { + return; + } + + Log.d("STK", caller + ": " + msg); + } +} diff --git a/telephony/java/com/android/internal/telephony/cat/CatResponseMessage.java b/telephony/java/com/android/internal/telephony/cat/CatResponseMessage.java new file mode 100644 index 0000000..04a52e6 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/CatResponseMessage.java @@ -0,0 +1,54 @@ +/* + * 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.gsm.stk; + +public class StkResponseMessage { + CommandDetails cmdDet = null; + ResultCode resCode = ResultCode.OK; + int usersMenuSelection = 0; + String usersInput = null; + boolean usersYesNoSelection = false; + boolean usersConfirm = false; + + public StkResponseMessage(StkCmdMessage cmdMsg) { + this.cmdDet = cmdMsg.mCmdDet; + } + + public void setResultCode(ResultCode resCode) { + this.resCode = resCode; + } + + public void setMenuSelection(int selection) { + this.usersMenuSelection = selection; + } + + public void setInput(String input) { + this.usersInput = input; + } + + public void setYesNo(boolean yesNo) { + usersYesNoSelection = yesNo; + } + + public void setConfirmation(boolean confirm) { + usersConfirm = confirm; + } + + CommandDetails getCmdDetails() { + return cmdDet; + } + } \ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/cat/CatService.java b/telephony/java/com/android/internal/telephony/cat/CatService.java new file mode 100644 index 0000000..5efa7a6 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/CatService.java @@ -0,0 +1,635 @@ +/* + * 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.gsm.stk; + +import android.content.Context; +import android.content.Intent; +import android.os.AsyncResult; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Message; + +import com.android.internal.telephony.IccUtils; +import com.android.internal.telephony.CommandsInterface; +import com.android.internal.telephony.IccCard; +import com.android.internal.telephony.IccFileHandler; +import com.android.internal.telephony.IccRecords; + +import android.util.Config; + +import java.io.ByteArrayOutputStream; + +/** + * Enumeration for representing the tag value of COMPREHENSION-TLV objects. If + * you want to get the actual value, call {@link #value() value} method. + * + * {@hide} + */ +enum ComprehensionTlvTag { + COMMAND_DETAILS(0x01), + DEVICE_IDENTITIES(0x02), + RESULT(0x03), + DURATION(0x04), + ALPHA_ID(0x05), + USSD_STRING(0x0a), + TEXT_STRING(0x0d), + TONE(0x0e), + ITEM(0x0f), + ITEM_ID(0x10), + RESPONSE_LENGTH(0x11), + FILE_LIST(0x12), + HELP_REQUEST(0x15), + DEFAULT_TEXT(0x17), + EVENT_LIST(0x19), + ICON_ID(0x1e), + ITEM_ICON_ID_LIST(0x1f), + IMMEDIATE_RESPONSE(0x2b), + LANGUAGE(0x2d), + URL(0x31), + BROWSER_TERMINATION_CAUSE(0x34), + TEXT_ATTRIBUTE(0x50); + + private int mValue; + + ComprehensionTlvTag(int value) { + mValue = value; + } + + /** + * Returns the actual value of this COMPREHENSION-TLV object. + * + * @return Actual tag value of this object + */ + public int value() { + return mValue; + } + + public static ComprehensionTlvTag fromInt(int value) { + for (ComprehensionTlvTag e : ComprehensionTlvTag.values()) { + if (e.mValue == value) { + return e; + } + } + return null; + } +} + +class RilMessage { + int mId; + Object mData; + ResultCode mResCode; + + RilMessage(int msgId, String rawData) { + mId = msgId; + mData = rawData; + } + + RilMessage(RilMessage other) { + this.mId = other.mId; + this.mData = other.mData; + this.mResCode = other.mResCode; + } +} + +/** + * Class that implements SIM Toolkit Telephony Service. Interacts with the RIL + * and application. + * + * {@hide} + */ +public class StkService extends Handler implements AppInterface { + + // Class members + private static IccRecords mIccRecords; + + // Service members. + private static StkService sInstance; + private CommandsInterface mCmdIf; + private Context mContext; + private StkCmdMessage mCurrntCmd = null; + private StkCmdMessage mMenuCmd = null; + + private RilMessageDecoder mMsgDecoder = null; + + // Service constants. + static final int MSG_ID_SESSION_END = 1; + static final int MSG_ID_PROACTIVE_COMMAND = 2; + static final int MSG_ID_EVENT_NOTIFY = 3; + static final int MSG_ID_CALL_SETUP = 4; + static final int MSG_ID_REFRESH = 5; + static final int MSG_ID_RESPONSE = 6; + + static final int MSG_ID_RIL_MSG_DECODED = 10; + + // Events to signal SIM presence or absent in the device. + private static final int MSG_ID_ICC_RECORDS_LOADED = 20; + + private static final int DEV_ID_KEYPAD = 0x01; + private static final int DEV_ID_DISPLAY = 0x02; + private static final int DEV_ID_EARPIECE = 0x03; + private static final int DEV_ID_UICC = 0x81; + private static final int DEV_ID_TERMINAL = 0x82; + private static final int DEV_ID_NETWORK = 0x83; + + /* Intentionally private for singleton */ + private StkService(CommandsInterface ci, IccRecords ir, Context context, + IccFileHandler fh, IccCard ic) { + if (ci == null || ir == null || context == null || fh == null + || ic == null) { + throw new NullPointerException( + "Service: Input parameters must not be null"); + } + mCmdIf = ci; + mContext = context; + + // Get the RilMessagesDecoder for decoding the messages. + mMsgDecoder = RilMessageDecoder.getInstance(this, fh); + + // Register ril events handling. + mCmdIf.setOnStkSessionEnd(this, MSG_ID_SESSION_END, null); + mCmdIf.setOnStkProactiveCmd(this, MSG_ID_PROACTIVE_COMMAND, null); + mCmdIf.setOnStkEvent(this, MSG_ID_EVENT_NOTIFY, null); + mCmdIf.setOnStkCallSetUp(this, MSG_ID_CALL_SETUP, null); + //mCmdIf.setOnSimRefresh(this, MSG_ID_REFRESH, null); + + mIccRecords = ir; + + // Register for SIM ready event. + mIccRecords.registerForRecordsLoaded(this, MSG_ID_ICC_RECORDS_LOADED, null); + + mCmdIf.reportStkServiceIsRunning(null); + StkLog.d(this, "StkService: is running"); + } + + public void dispose() { + mIccRecords.unregisterForRecordsLoaded(this); + mCmdIf.unSetOnStkSessionEnd(this); + mCmdIf.unSetOnStkProactiveCmd(this); + mCmdIf.unSetOnStkEvent(this); + mCmdIf.unSetOnStkCallSetUp(this); + + this.removeCallbacksAndMessages(null); + } + + protected void finalize() { + StkLog.d(this, "Service finalized"); + } + + private void handleRilMsg(RilMessage rilMsg) { + if (rilMsg == null) { + return; + } + + // dispatch messages + CommandParams cmdParams = null; + switch (rilMsg.mId) { + case MSG_ID_EVENT_NOTIFY: + if (rilMsg.mResCode == ResultCode.OK) { + cmdParams = (CommandParams) rilMsg.mData; + if (cmdParams != null) { + handleProactiveCommand(cmdParams); + } + } + break; + case MSG_ID_PROACTIVE_COMMAND: + cmdParams = (CommandParams) rilMsg.mData; + if (cmdParams != null) { + if (rilMsg.mResCode == ResultCode.OK) { + handleProactiveCommand(cmdParams); + } else { + // for proactive commands that couldn't be decoded + // successfully respond with the code generated by the + // message decoder. + sendTerminalResponse(cmdParams.cmdDet, rilMsg.mResCode, + false, 0, null); + } + } + break; + case MSG_ID_REFRESH: + cmdParams = (CommandParams) rilMsg.mData; + if (cmdParams != null) { + handleProactiveCommand(cmdParams); + } + break; + case MSG_ID_SESSION_END: + handleSessionEnd(); + break; + case MSG_ID_CALL_SETUP: + // prior event notify command supplied all the information + // needed for set up call processing. + break; + } + } + + /** + * Handles RIL_UNSOL_STK_PROACTIVE_COMMAND unsolicited command from RIL. + * Sends valid proactive command data to the application using intents. + * + */ + private void handleProactiveCommand(CommandParams cmdParams) { + StkLog.d(this, cmdParams.getCommandType().name()); + + StkCmdMessage cmdMsg = new StkCmdMessage(cmdParams); + switch (cmdParams.getCommandType()) { + case SET_UP_MENU: + if (removeMenu(cmdMsg.getMenu())) { + mMenuCmd = null; + } else { + mMenuCmd = cmdMsg; + } + sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, + null); + break; + case DISPLAY_TEXT: + // when application is not required to respond, send an immediate + // response. + if (!cmdMsg.geTextMessage().responseNeeded) { + sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, + 0, null); + } + break; + case REFRESH: + // ME side only handles refresh commands which meant to remove IDLE + // MODE TEXT. + cmdParams.cmdDet.typeOfCommand = CommandType.SET_UP_IDLE_MODE_TEXT + .value(); + break; + case SET_UP_IDLE_MODE_TEXT: + sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, + 0, null); + break; + case LAUNCH_BROWSER: + case SELECT_ITEM: + case GET_INPUT: + case GET_INKEY: + case SEND_DTMF: + case SEND_SMS: + case SEND_SS: + case SEND_USSD: + case PLAY_TONE: + case SET_UP_CALL: + // nothing to do on telephony! + break; + default: + StkLog.d(this, "Unsupported command"); + return; + } + mCurrntCmd = cmdMsg; + Intent intent = new Intent(AppInterface.STK_CMD_ACTION); + intent.putExtra("STK CMD", cmdMsg); + mContext.sendBroadcast(intent); + } + + /** + * Handles RIL_UNSOL_STK_SESSION_END unsolicited command from RIL. + * + */ + private void handleSessionEnd() { + StkLog.d(this, "SESSION END"); + + mCurrntCmd = mMenuCmd; + Intent intent = new Intent(AppInterface.STK_SESSION_END_ACTION); + mContext.sendBroadcast(intent); + } + + private void sendTerminalResponse(CommandDetails cmdDet, + ResultCode resultCode, boolean includeAdditionalInfo, + int additionalInfo, ResponseData resp) { + + if (cmdDet == null) { + return; + } + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + + // command details + int tag = ComprehensionTlvTag.COMMAND_DETAILS.value(); + if (cmdDet.compRequired) { + tag |= 0x80; + } + buf.write(tag); + buf.write(0x03); // length + buf.write(cmdDet.commandNumber); + buf.write(cmdDet.typeOfCommand); + buf.write(cmdDet.commandQualifier); + + // device identities + tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value(); + buf.write(tag); + buf.write(0x02); // length + buf.write(DEV_ID_TERMINAL); // source device id + buf.write(DEV_ID_UICC); // destination device id + + // result + tag = 0x80 | ComprehensionTlvTag.RESULT.value(); + buf.write(tag); + int length = includeAdditionalInfo ? 2 : 1; + buf.write(length); + buf.write(resultCode.value()); + + // additional info + if (includeAdditionalInfo) { + buf.write(additionalInfo); + } + + // Fill optional data for each corresponding command + if (resp != null) { + resp.format(buf); + } + + byte[] rawData = buf.toByteArray(); + String hexString = IccUtils.bytesToHexString(rawData); + if (Config.LOGD) { + StkLog.d(this, "TERMINAL RESPONSE: " + hexString); + } + + mCmdIf.sendTerminalResponse(hexString, null); + } + + + private void sendMenuSelection(int menuId, boolean helpRequired) { + + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + + // tag + int tag = BerTlv.BER_MENU_SELECTION_TAG; + buf.write(tag); + + // length + buf.write(0x00); // place holder + + // device identities + tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value(); + buf.write(tag); + buf.write(0x02); // length + buf.write(DEV_ID_KEYPAD); // source device id + buf.write(DEV_ID_UICC); // destination device id + + // item identifier + tag = 0x80 | ComprehensionTlvTag.ITEM_ID.value(); + buf.write(tag); + buf.write(0x01); // length + buf.write(menuId); // menu identifier chosen + + // help request + if (helpRequired) { + tag = ComprehensionTlvTag.HELP_REQUEST.value(); + buf.write(tag); + buf.write(0x00); // length + } + + byte[] rawData = buf.toByteArray(); + + // write real length + int len = rawData.length - 2; // minus (tag + length) + rawData[1] = (byte) len; + + String hexString = IccUtils.bytesToHexString(rawData); + + mCmdIf.sendEnvelope(hexString, null); + } + + private void eventDownload(int event, int sourceId, int destinationId, + byte[] additionalInfo, boolean oneShot) { + + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + + // tag + int tag = BerTlv.BER_EVENT_DOWNLOAD_TAG; + buf.write(tag); + + // length + buf.write(0x00); // place holder, assume length < 128. + + // event list + tag = 0x80 | ComprehensionTlvTag.EVENT_LIST.value(); + buf.write(tag); + buf.write(0x01); // length + buf.write(event); // event value + + // device identities + tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value(); + buf.write(tag); + buf.write(0x02); // length + buf.write(sourceId); // source device id + buf.write(destinationId); // destination device id + + // additional information + if (additionalInfo != null) { + for (byte b : additionalInfo) { + buf.write(b); + } + } + + byte[] rawData = buf.toByteArray(); + + // write real length + int len = rawData.length - 2; // minus (tag + length) + rawData[1] = (byte) len; + + String hexString = IccUtils.bytesToHexString(rawData); + + mCmdIf.sendEnvelope(hexString, null); + } + + /** + * Used for instantiating/updating the Service from the GsmPhone or CdmaPhone constructor. + * + * @param ci CommandsInterface object + * @param ir IccRecords object + * @param context phone app context + * @param fh Icc file handler + * @param ic Icc card + * @return The only Service object in the system + */ + public static StkService getInstance(CommandsInterface ci, IccRecords ir, + Context context, IccFileHandler fh, IccCard ic) { + if (sInstance == null) { + if (ci == null || ir == null || context == null || fh == null + || ic == null) { + return null; + } + HandlerThread thread = new HandlerThread("Stk Telephony service"); + thread.start(); + sInstance = new StkService(ci, ir, context, fh, ic); + StkLog.d(sInstance, "NEW sInstance"); + } else if ((ir != null) && (mIccRecords != ir)) { + StkLog.d(sInstance, "Reinitialize the Service with SIMRecords"); + mIccRecords = ir; + + // re-Register for SIM ready event. + mIccRecords.registerForRecordsLoaded(sInstance, MSG_ID_ICC_RECORDS_LOADED, null); + StkLog.d(sInstance, "sr changed reinitialize and return current sInstance"); + } else { + StkLog.d(sInstance, "Return current sInstance"); + } + return sInstance; + } + + /** + * Used by application to get an AppInterface object. + * + * @return The only Service object in the system + */ + public static AppInterface getInstance() { + return getInstance(null, null, null, null, null); + } + + @Override + public void handleMessage(Message msg) { + + switch (msg.what) { + case MSG_ID_SESSION_END: + case MSG_ID_PROACTIVE_COMMAND: + case MSG_ID_EVENT_NOTIFY: + case MSG_ID_REFRESH: + StkLog.d(this, "ril message arrived"); + String data = null; + if (msg.obj != null) { + AsyncResult ar = (AsyncResult) msg.obj; + if (ar != null && ar.result != null) { + try { + data = (String) ar.result; + } catch (ClassCastException e) { + break; + } + } + } + mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, data)); + break; + case MSG_ID_CALL_SETUP: + mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, null)); + break; + case MSG_ID_ICC_RECORDS_LOADED: + break; + case MSG_ID_RIL_MSG_DECODED: + handleRilMsg((RilMessage) msg.obj); + break; + case MSG_ID_RESPONSE: + handleCmdResponse((StkResponseMessage) msg.obj); + break; + default: + throw new AssertionError("Unrecognized STK command: " + msg.what); + } + } + + public synchronized void onCmdResponse(StkResponseMessage resMsg) { + if (resMsg == null) { + return; + } + // queue a response message. + Message msg = this.obtainMessage(MSG_ID_RESPONSE, resMsg); + msg.sendToTarget(); + } + + private boolean validateResponse(StkResponseMessage resMsg) { + if (mCurrntCmd != null) { + return (resMsg.cmdDet.compareTo(mCurrntCmd.mCmdDet)); + } + return false; + } + + private boolean removeMenu(Menu menu) { + try { + if (menu.items.size() == 1 && menu.items.get(0) == null) { + return true; + } + } catch (NullPointerException e) { + StkLog.d(this, "Unable to get Menu's items size"); + return true; + } + return false; + } + + private void handleCmdResponse(StkResponseMessage resMsg) { + // Make sure the response details match the last valid command. An invalid + // response is a one that doesn't have a corresponding proactive command + // and sending it can "confuse" the baseband/ril. + // One reason for out of order responses can be UI glitches. For example, + // if the application launch an activity, and that activity is stored + // by the framework inside the history stack. That activity will be + // available for relaunch using the latest application dialog + // (long press on the home button). Relaunching that activity can send + // the same command's result again to the StkService and can cause it to + // get out of sync with the SIM. + if (!validateResponse(resMsg)) { + return; + } + ResponseData resp = null; + boolean helpRequired = false; + CommandDetails cmdDet = resMsg.getCmdDetails(); + + switch (resMsg.resCode) { + case HELP_INFO_REQUIRED: + helpRequired = true; + // fall through + case OK: + case PRFRMD_WITH_PARTIAL_COMPREHENSION: + case PRFRMD_WITH_MISSING_INFO: + case PRFRMD_WITH_ADDITIONAL_EFS_READ: + case PRFRMD_ICON_NOT_DISPLAYED: + case PRFRMD_MODIFIED_BY_NAA: + case PRFRMD_LIMITED_SERVICE: + case PRFRMD_WITH_MODIFICATION: + case PRFRMD_NAA_NOT_ACTIVE: + case PRFRMD_TONE_NOT_PLAYED: + switch (AppInterface.CommandType.fromInt(cmdDet.typeOfCommand)) { + case SET_UP_MENU: + helpRequired = resMsg.resCode == ResultCode.HELP_INFO_REQUIRED; + sendMenuSelection(resMsg.usersMenuSelection, helpRequired); + return; + case SELECT_ITEM: + resp = new SelectItemResponseData(resMsg.usersMenuSelection); + break; + case GET_INPUT: + case GET_INKEY: + Input input = mCurrntCmd.geInput(); + if (!input.yesNo) { + // when help is requested there is no need to send the text + // string object. + if (!helpRequired) { + resp = new GetInkeyInputResponseData(resMsg.usersInput, + input.ucs2, input.packed); + } + } else { + resp = new GetInkeyInputResponseData( + resMsg.usersYesNoSelection); + } + break; + case DISPLAY_TEXT: + case LAUNCH_BROWSER: + break; + case SET_UP_CALL: + mCmdIf.handleCallSetupRequestFromSim(resMsg.usersConfirm, null); + // No need to send terminal response for SET UP CALL. The user's + // confirmation result is send back using a dedicated ril message + // invoked by the CommandInterface call above. + mCurrntCmd = null; + return; + } + break; + case NO_RESPONSE_FROM_USER: + case UICC_SESSION_TERM_BY_USER: + case BACKWARD_MOVE_BY_USER: + resp = null; + break; + default: + return; + } + sendTerminalResponse(cmdDet, resMsg.resCode, false, 0, resp); + mCurrntCmd = null; + } +} diff --git a/telephony/java/com/android/internal/telephony/cat/CommandDetails.java b/telephony/java/com/android/internal/telephony/cat/CommandDetails.java new file mode 100644 index 0000000..e81ff98 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/CommandDetails.java @@ -0,0 +1,106 @@ +/* + * 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.gsm.stk; + +import android.os.Parcel; +import android.os.Parcelable; + +abstract class ValueObject { + abstract ComprehensionTlvTag getTag(); +} + +/** + * Class for Command Detailes object of proactive commands from SIM. + * {@hide} + */ +class CommandDetails extends ValueObject implements Parcelable { + public boolean compRequired; + public int commandNumber; + public int typeOfCommand; + public int commandQualifier; + + public ComprehensionTlvTag getTag() { + return ComprehensionTlvTag.COMMAND_DETAILS; + } + + CommandDetails() { + } + + public boolean compareTo(CommandDetails other) { + return (this.compRequired == other.compRequired && + this.commandNumber == other.commandNumber && + this.commandQualifier == other.commandQualifier && + this.typeOfCommand == other.typeOfCommand); + } + + public CommandDetails(Parcel in) { + compRequired = true; + commandNumber = in.readInt(); + typeOfCommand = in.readInt(); + commandQualifier = in.readInt(); + } + + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(commandNumber); + dest.writeInt(typeOfCommand); + dest.writeInt(commandQualifier); + } + + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + public CommandDetails createFromParcel(Parcel in) { + return new CommandDetails(in); + } + + public CommandDetails[] newArray(int size) { + return new CommandDetails[size]; + } + }; + + public int describeContents() { + return 0; + } +} + +class DeviceIdentities extends ValueObject { + public int sourceId; + public int destinationId; + + ComprehensionTlvTag getTag() { + return ComprehensionTlvTag.DEVICE_IDENTITIES; + } +} + +// Container class to hold icon identifier value. +class IconId extends ValueObject { + int recordNumber; + boolean selfExplanatory; + + ComprehensionTlvTag getTag() { + return ComprehensionTlvTag.ICON_ID; + } +} + +// Container class to hold item icon identifier list value. +class ItemsIconId extends ValueObject { + int [] recordNumbers; + boolean selfExplanatory; + + ComprehensionTlvTag getTag() { + return ComprehensionTlvTag.ITEM_ICON_ID_LIST; + } +} \ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/cat/CommandParams.java b/telephony/java/com/android/internal/telephony/cat/CommandParams.java new file mode 100644 index 0000000..3da652f --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/CommandParams.java @@ -0,0 +1,169 @@ +/* + * 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.gsm.stk; + +import android.graphics.Bitmap; + +/** + * Container class for proactive command parameters. + * + */ +class CommandParams { + CommandDetails cmdDet; + + CommandParams(CommandDetails cmdDet) { + this.cmdDet = cmdDet; + } + + AppInterface.CommandType getCommandType() { + return AppInterface.CommandType.fromInt(cmdDet.typeOfCommand); + } + + boolean setIcon(Bitmap icon) { return true; } +} + +class DisplayTextParams extends CommandParams { + TextMessage textMsg; + + DisplayTextParams(CommandDetails cmdDet, TextMessage textMsg) { + super(cmdDet); + this.textMsg = textMsg; + } + + boolean setIcon(Bitmap icon) { + if (icon != null && textMsg != null) { + textMsg.icon = icon; + return true; + } + return false; + } +} + +class LaunchBrowserParams extends CommandParams { + TextMessage confirmMsg; + LaunchBrowserMode mode; + String url; + + LaunchBrowserParams(CommandDetails cmdDet, TextMessage confirmMsg, + String url, LaunchBrowserMode mode) { + super(cmdDet); + this.confirmMsg = confirmMsg; + this.mode = mode; + this.url = url; + } + + boolean setIcon(Bitmap icon) { + if (icon != null && confirmMsg != null) { + confirmMsg.icon = icon; + return true; + } + return false; + } +} + +class PlayToneParams extends CommandParams { + TextMessage textMsg; + ToneSettings settings; + + PlayToneParams(CommandDetails cmdDet, TextMessage textMsg, + Tone tone, Duration duration, boolean vibrate) { + super(cmdDet); + this.textMsg = textMsg; + this.settings = new ToneSettings(duration, tone, vibrate); + } + + boolean setIcon(Bitmap icon) { + if (icon != null && textMsg != null) { + textMsg.icon = icon; + return true; + } + return false; + } +} + +class CallSetupParams extends CommandParams { + TextMessage confirmMsg; + TextMessage callMsg; + + CallSetupParams(CommandDetails cmdDet, TextMessage confirmMsg, + TextMessage callMsg) { + super(cmdDet); + this.confirmMsg = confirmMsg; + this.callMsg = callMsg; + } + + boolean setIcon(Bitmap icon) { + if (icon == null) { + return false; + } + if (confirmMsg != null && confirmMsg.icon == null) { + confirmMsg.icon = icon; + return true; + } else if (callMsg != null && callMsg.icon == null) { + callMsg.icon = icon; + return true; + } + return false; + } +} + +class SelectItemParams extends CommandParams { + Menu menu = null; + boolean loadTitleIcon = false; + + SelectItemParams(CommandDetails cmdDet, Menu menu, boolean loadTitleIcon) { + super(cmdDet); + this.menu = menu; + this.loadTitleIcon = loadTitleIcon; + } + + boolean setIcon(Bitmap icon) { + if (icon != null && menu != null) { + if (loadTitleIcon && menu.titleIcon == null) { + menu.titleIcon = icon; + } else { + for (Item item : menu.items) { + if (item.icon != null) { + continue; + } + item.icon = icon; + break; + } + } + return true; + } + return false; + } +} + +class GetInputParams extends CommandParams { + Input input = null; + + GetInputParams(CommandDetails cmdDet, Input input) { + super(cmdDet); + this.input = input; + } + + boolean setIcon(Bitmap icon) { + if (icon != null && input != null) { + input.icon = icon; + } + return true; + } +} + + diff --git a/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java b/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java new file mode 100644 index 0000000..2364387 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java @@ -0,0 +1,866 @@ +/* + * 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.gsm.stk; + +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; + + 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) { + StkLog.d(this, "Failed to procees command details"); + } + } + } + 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) { + sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD); + 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; + default: + // unsupported proactive commands + mCmdParams = new CommandParams(cmdDet); + sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD); + return; + } + } catch (ResultException 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 { + + StkLog.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 { + + StkLog.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 { + + StkLog.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); + } + + 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; + + 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 { + + StkLog.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) { + + StkLog.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 { + + StkLog.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) { + // STK 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 { + + StkLog.d(this, "process EventNotify"); + + TextMessage textMsg = new TextMessage(); + IconId iconId = null; + + ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, + ctlvs); + if (ctlv != null) { + textMsg.text = ValueParser.retrieveAlphaId(ctlv); + } else { + throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); + } + + 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) { + + StkLog.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 { + + StkLog.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); + if (ctlv != null) { + 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 { + + StkLog.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 { + StkLog.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); + if (ctlv != null) { + 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; + } +} diff --git a/telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java b/telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java new file mode 100644 index 0000000..ffde6a3 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2006 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.gsm.stk; + +import java.util.ArrayList; +import java.util.List; + + +/** + * Class for representing COMPREHENSION-TLV objects. + * + * @see "ETSI TS 101 220 subsection 7.1.1" + * + * {@hide} + */ +class ComprehensionTlv { + private int mTag; + private boolean mCr; + private int mLength; + private int mValueIndex; + private byte[] mRawValue; + + /** + * Constructor. Private on purpose. Use + * {@link #decodeMany(byte[], int) decodeMany} or + * {@link #decode(byte[], int) decode} method. + * + * @param tag The tag for this object + * @param cr Comprehension Required flag + * @param length Length of the value + * @param data Byte array containing the value + * @param valueIndex Index in data at which the value starts + */ + protected ComprehensionTlv(int tag, boolean cr, int length, byte[] data, + int valueIndex) { + mTag = tag; + mCr = cr; + mLength = length; + mValueIndex = valueIndex; + mRawValue = data; + } + + public int getTag() { + return mTag; + } + + public boolean isComprehensionRequired() { + return mCr; + } + + public int getLength() { + return mLength; + } + + public int getValueIndex() { + return mValueIndex; + } + + public byte[] getRawValue() { + return mRawValue; + } + + /** + * Parses a list of COMPREHENSION-TLV objects from a byte array. + * + * @param data A byte array containing data to be parsed + * @param startIndex Index in data at which to start parsing + * @return A list of COMPREHENSION-TLV objects parsed + * @throws ResultException + */ + public static List decodeMany(byte[] data, int startIndex) + throws ResultException { + ArrayList items = new ArrayList(); + int endIndex = data.length; + while (startIndex < endIndex) { + ComprehensionTlv ctlv = ComprehensionTlv.decode(data, startIndex); + items.add(ctlv); + startIndex = ctlv.mValueIndex + ctlv.mLength; + } + + return items; + } + + /** + * Parses an COMPREHENSION-TLV object from a byte array. + * + * @param data A byte array containing data to be parsed + * @param startIndex Index in data at which to start parsing + * @return A COMPREHENSION-TLV object parsed + * @throws ResultException + */ + public static ComprehensionTlv decode(byte[] data, int startIndex) + throws ResultException { + try { + int curIndex = startIndex; + int endIndex = data.length; + + /* tag */ + int tag; + boolean cr; // Comprehension required flag + int temp = data[curIndex++] & 0xff; + switch (temp) { + case 0: + case 0xff: + case 0x80: + throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); + + case 0x7f: // tag is in three-byte format + tag = ((data[curIndex] & 0xff) << 8) + | (data[curIndex + 1] & 0xff); + cr = (tag & 0x8000) != 0; + tag &= ~0x8000; + curIndex += 2; + break; + + default: // tag is in single-byte format + tag = temp; + cr = (tag & 0x80) != 0; + tag &= ~0x80; + break; + } + + /* length */ + int length; + temp = data[curIndex++] & 0xff; + if (temp < 0x80) { + length = temp; + } else if (temp == 0x81) { + length = data[curIndex++] & 0xff; + if (length < 0x80) { + throw new ResultException( + ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + } else if (temp == 0x82) { + length = ((data[curIndex] & 0xff) << 8) + | (data[curIndex + 1] & 0xff); + curIndex += 2; + if (length < 0x100) { + throw new ResultException( + ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + } else if (temp == 0x83) { + length = ((data[curIndex] & 0xff) << 16) + | ((data[curIndex + 1] & 0xff) << 8) + | (data[curIndex + 2] & 0xff); + curIndex += 3; + if (length < 0x10000) { + throw new ResultException( + ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + } else { + throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + + return new ComprehensionTlv(tag, cr, length, data, curIndex); + + } catch (IndexOutOfBoundsException e) { + throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + } +} diff --git a/telephony/java/com/android/internal/telephony/cat/Duration.java b/telephony/java/com/android/internal/telephony/cat/Duration.java new file mode 100644 index 0000000..9d8cc97 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/Duration.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2006 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.gsm.stk; + +import android.os.Parcel; +import android.os.Parcelable; + + +/** + * Class for representing "Duration" object for STK. + * + * {@hide} + */ +public class Duration implements Parcelable { + public int timeInterval; + public TimeUnit timeUnit; + + public enum TimeUnit { + MINUTE(0x00), + SECOND(0x01), + TENTH_SECOND(0x02); + + private int mValue; + + TimeUnit(int value) { + mValue = value; + } + + public int value() { + return mValue; + } + } + + /** + * @param timeInterval Between 1 and 255 inclusive. + */ + public Duration(int timeInterval, TimeUnit timeUnit) { + this.timeInterval = timeInterval; + this.timeUnit = timeUnit; + } + + private Duration(Parcel in) { + timeInterval = in.readInt(); + timeUnit = TimeUnit.values()[in.readInt()]; + } + + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(timeInterval); + dest.writeInt(timeUnit.ordinal()); + } + + public int describeContents() { + return 0; + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public Duration createFromParcel(Parcel in) { + return new Duration(in); + } + + public Duration[] newArray(int size) { + return new Duration[size]; + } + }; +} diff --git a/telephony/java/com/android/internal/telephony/cat/FontSize.java b/telephony/java/com/android/internal/telephony/cat/FontSize.java new file mode 100644 index 0000000..bd4f49f --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/FontSize.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2006 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.gsm.stk; + + +/** + * Enumeration for representing text font size. + * + * {@hide} + */ +public enum FontSize { + NORMAL(0x0), + LARGE(0x1), + SMALL(0x2); + + private int mValue; + + FontSize(int value) { + mValue = value; + } + + /** + * Create a FontSize object. + * @param value Integer value to be converted to a FontSize object. + * @return FontSize object whose value is {@code value}. If no + * FontSize object has that value, null is returned. + */ + public static FontSize fromInt(int value) { + for (FontSize e : FontSize.values()) { + if (e.mValue == value) { + return e; + } + } + return null; + } +} diff --git a/telephony/java/com/android/internal/telephony/cat/IconLoader.java b/telephony/java/com/android/internal/telephony/cat/IconLoader.java new file mode 100644 index 0000000..500b8f6 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/IconLoader.java @@ -0,0 +1,362 @@ +/* + * Copyright (C) 2006 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.gsm.stk; + +import com.android.internal.telephony.IccFileHandler; + +import android.graphics.Bitmap; +import android.graphics.Color; +import android.os.AsyncResult; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Looper; +import android.os.Message; +import android.util.Log; + +import java.util.HashMap; + +/** + * Class for loading icons from the SIM card. Has two states: single, for loading + * one icon. Multi, for loading icons list. + * + */ +class IconLoader extends Handler { + // members + private int mState = STATE_SINGLE_ICON; + private ImageDescriptor mId = null; + private Bitmap mCurrentIcon = null; + private int mRecordNumber; + private IccFileHandler mSimFH = null; + private Message mEndMsg = null; + private byte[] mIconData = null; + // multi icons state members + private int[] mRecordNumbers = null; + private int mCurrentRecordIndex = 0; + private Bitmap[] mIcons = null; + private HashMap mIconsCache = null; + + private static IconLoader sLoader = null; + + // Loader state values. + private static final int STATE_SINGLE_ICON = 1; + private static final int STATE_MULTI_ICONS = 2; + + // Finished loading single record from a linear-fixed EF-IMG. + private static final int EVENT_READ_EF_IMG_RECOED_DONE = 1; + // Finished loading single icon from a Transparent DF-Graphics. + private static final int EVENT_READ_ICON_DONE = 2; + // Finished loading single colour icon lookup table. + private static final int EVENT_READ_CLUT_DONE = 3; + + // Color lookup table offset inside the EF. + private static final int CLUT_LOCATION_OFFSET = 4; + // CLUT entry size, {Red, Green, Black} + private static final int CLUT_ENTRY_SIZE = 3; + + + private IconLoader(Looper looper , IccFileHandler fh) { + super(looper); + mSimFH = fh; + + mIconsCache = new HashMap(50); + } + + static IconLoader getInstance(Handler caller, IccFileHandler fh) { + if (sLoader != null) { + return sLoader; + } + if (fh != null) { + HandlerThread thread = new HandlerThread("Stk Icon Loader"); + thread.start(); + return new IconLoader(thread.getLooper(), fh); + } + return null; + } + + void loadIcons(int[] recordNumbers, Message msg) { + if (recordNumbers == null || recordNumbers.length == 0 || msg == null) { + return; + } + mEndMsg = msg; + // initialize multi icons load variables. + mIcons = new Bitmap[recordNumbers.length]; + mRecordNumbers = recordNumbers; + mCurrentRecordIndex = 0; + mState = STATE_MULTI_ICONS; + startLoadingIcon(recordNumbers[0]); + } + + void loadIcon(int recordNumber, Message msg) { + if (msg == null) { + return; + } + mEndMsg = msg; + mState = STATE_SINGLE_ICON; + startLoadingIcon(recordNumber); + } + + private void startLoadingIcon(int recordNumber) { + // Reset the load variables. + mId = null; + mIconData = null; + mCurrentIcon = null; + mRecordNumber = recordNumber; + + // make sure the icon was not already loaded and saved in the local cache. + if (mIconsCache.containsKey(recordNumber)) { + mCurrentIcon = mIconsCache.get(recordNumber); + postIcon(); + return; + } + + // start the first phase ==> loading Image Descriptor. + readId(); + } + + @Override + public void handleMessage(Message msg) { + AsyncResult ar; + + try { + switch (msg.what) { + case EVENT_READ_EF_IMG_RECOED_DONE: + ar = (AsyncResult) msg.obj; + if (handleImageDescriptor((byte[]) ar.result)) { + readIconData(); + } else { + throw new Exception("Unable to parse image descriptor"); + } + break; + case EVENT_READ_ICON_DONE: + ar = (AsyncResult) msg.obj; + byte[] rawData = ((byte[]) ar.result); + if (mId.codingScheme == ImageDescriptor.CODING_SCHEME_BASIC) { + mCurrentIcon = parseToBnW(rawData, rawData.length); + mIconsCache.put(mRecordNumber, mCurrentIcon); + postIcon(); + } else if (mId.codingScheme == ImageDescriptor.CODING_SCHEME_COLOUR) { + mIconData = rawData; + readClut(); + } + break; + case EVENT_READ_CLUT_DONE: + ar = (AsyncResult) msg.obj; + byte [] clut = ((byte[]) ar.result); + mCurrentIcon = parseToRGB(mIconData, mIconData.length, + false, clut); + mIconsCache.put(mRecordNumber, mCurrentIcon); + postIcon(); + break; + } + } catch (Exception e) { + StkLog.d(this, "Icon load failed"); + // post null icon back to the caller. + postIcon(); + } + } + + /** + * Handles Image descriptor parsing and required processing. This is the + * first step required to handle retrieving icons from the SIM. + * + * @param data byte [] containing Image Instance descriptor as defined in + * TS 51.011. + */ + private boolean handleImageDescriptor(byte[] rawData) { + mId = ImageDescriptor.parse(rawData, 1); + if (mId == null) { + return false; + } + return true; + } + + // Start reading colour lookup table from SIM card. + private void readClut() { + int length = mIconData[3] * CLUT_ENTRY_SIZE; + Message msg = this.obtainMessage(EVENT_READ_CLUT_DONE); + mSimFH.loadEFImgTransparent(mId.imageId, + mIconData[CLUT_LOCATION_OFFSET], + mIconData[CLUT_LOCATION_OFFSET + 1], length, msg); + } + + // Start reading Image Descriptor from SIM card. + private void readId() { + if (mRecordNumber < 0) { + mCurrentIcon = null; + postIcon(); + return; + } + Message msg = this.obtainMessage(EVENT_READ_EF_IMG_RECOED_DONE); + mSimFH.loadEFImgLinearFixed(mRecordNumber, msg); + } + + // Start reading icon bytes array from SIM card. + private void readIconData() { + Message msg = this.obtainMessage(EVENT_READ_ICON_DONE); + mSimFH.loadEFImgTransparent(mId.imageId, 0, 0, mId.length ,msg); + } + + // When all is done pass icon back to caller. + private void postIcon() { + if (mState == STATE_SINGLE_ICON) { + mEndMsg.obj = mCurrentIcon; + mEndMsg.sendToTarget(); + } else if (mState == STATE_MULTI_ICONS) { + mIcons[mCurrentRecordIndex++] = mCurrentIcon; + // If not all icons were loaded, start loading the next one. + if (mCurrentRecordIndex < mRecordNumbers.length) { + startLoadingIcon(mRecordNumbers[mCurrentRecordIndex]); + } else { + mEndMsg.obj = mIcons; + mEndMsg.sendToTarget(); + } + } + } + + /** + * Convert a TS 131.102 image instance of code scheme '11' into Bitmap + * @param data The raw data + * @param length The length of image body + * @return The bitmap + */ + public static Bitmap parseToBnW(byte[] data, int length){ + int valueIndex = 0; + int width = data[valueIndex++] & 0xFF; + int height = data[valueIndex++] & 0xFF; + int numOfPixels = width*height; + + int[] pixels = new int[numOfPixels]; + + int pixelIndex = 0; + int bitIndex = 7; + byte currentByte = 0x00; + while (pixelIndex < numOfPixels) { + // reassign data and index for every byte (8 bits). + if (pixelIndex % 8 == 0) { + currentByte = data[valueIndex++]; + bitIndex = 7; + } + pixels[pixelIndex++] = bitToBnW((currentByte >> bitIndex-- ) & 0x01); + } + + if (pixelIndex != numOfPixels) { + StkLog.d("IconLoader", "parseToBnW; size error"); + } + return Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888); + } + + /** + * Decode one bit to a black and white color: + * 0 is black + * 1 is white + * @param bit to decode + * @return RGB color + */ + private static int bitToBnW(int bit){ + if(bit == 1){ + return Color.WHITE; + } else { + return Color.BLACK; + } + } + + /** + * a TS 131.102 image instance of code scheme '11' into color Bitmap + * + * @param data The raw data + * @param length the length of image body + * @param transparency with or without transparency + * @param clut coulor lookup table + * @return The color bitmap + */ + public static Bitmap parseToRGB(byte[] data, int length, + boolean transparency, byte[] clut) { + int valueIndex = 0; + int width = data[valueIndex++] & 0xFF; + int height = data[valueIndex++] & 0xFF; + int bitsPerImg = data[valueIndex++] & 0xFF; + int numOfClutEntries = data[valueIndex++] & 0xFF; + + if (true == transparency) { + clut[numOfClutEntries - 1] = Color.TRANSPARENT; + } + + int numOfPixels = width * height; + int[] pixels = new int[numOfPixels]; + + valueIndex = 6; + int pixelIndex = 0; + int bitsStartOffset = 8 - bitsPerImg; + int bitIndex = bitsStartOffset; + byte currentByte = data[valueIndex++]; + int mask = getMask(bitsPerImg); + boolean bitsOverlaps = (8 % bitsPerImg == 0); + while (pixelIndex < numOfPixels) { + // reassign data and index for every byte (8 bits). + if (bitIndex < 0) { + currentByte = data[valueIndex++]; + bitIndex = bitsOverlaps ? (bitsStartOffset) : (bitIndex * -1); + } + int clutEntry = ((currentByte >> bitIndex) & mask); + int clutIndex = clutEntry * CLUT_ENTRY_SIZE; + pixels[pixelIndex++] = Color.rgb(clut[clutIndex], + clut[clutIndex + 1], clut[clutIndex + 2]); + bitIndex -= bitsPerImg; + } + + return Bitmap.createBitmap(pixels, width, height, + Bitmap.Config.ARGB_8888); + } + + /** + * Calculate bit mask for a given number of bits. The mask should enable to + * make a bitwise and to the given number of bits. + * @param numOfBits number of bits to calculate mask for. + * @return bit mask + */ + private static int getMask(int numOfBits) { + int mask = 0x00; + + switch (numOfBits) { + case 1: + mask = 0x01; + break; + case 2: + mask = 0x03; + break; + case 3: + mask = 0x07; + break; + case 4: + mask = 0x0F; + break; + case 5: + mask = 0x1F; + break; + case 6: + mask = 0x3F; + break; + case 7: + mask = 0x7F; + break; + case 8: + mask = 0xFF; + break; + } + return mask; + } +} diff --git a/telephony/java/com/android/internal/telephony/cat/ImageDescriptor.java b/telephony/java/com/android/internal/telephony/cat/ImageDescriptor.java new file mode 100644 index 0000000..880b9e5 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/ImageDescriptor.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2006 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.gsm.stk; + +/** + * {@hide} + */ +public class ImageDescriptor { + // members + int width; + int height; + int codingScheme; + int imageId; + int highOffset; + int lowOffset; + int length; + + // constants + static final int CODING_SCHEME_BASIC = 0x11; + static final int CODING_SCHEME_COLOUR = 0x21; + + // public static final int ID_LENGTH = 9; + // ID_LENGTH substituted by IccFileHandlerBase.GET_RESPONSE_EF_IMG_SIZE_BYTES + + ImageDescriptor() { + width = 0; + height = 0; + codingScheme = 0; + imageId = 0; + highOffset = 0; + lowOffset = 0; + length = 0; + } + + /** + * Extract descriptor information about image instance. + * + * @param rawData + * @param valueIndex + * @return ImageDescriptor + */ + static ImageDescriptor parse(byte[] rawData, int valueIndex) { + ImageDescriptor d = new ImageDescriptor(); + try { + d.width = rawData[valueIndex++] & 0xff; + d.height = rawData[valueIndex++] & 0xff; + d.codingScheme = rawData[valueIndex++] & 0xff; + + // parse image id + d.imageId = (rawData[valueIndex++] & 0xff) << 8; + d.imageId |= rawData[valueIndex++] & 0xff; + // parse offset + d.highOffset = (rawData[valueIndex++] & 0xff); // high byte offset + d.lowOffset = rawData[valueIndex++] & 0xff; // low byte offset + + d.length = ((rawData[valueIndex++] & 0xff) << 8 | (rawData[valueIndex++] & 0xff)); + } catch (IndexOutOfBoundsException e) { + StkLog.d("ImageDescripter", "parse; failed parsing image descriptor"); + d = null; + } + return d; + } +} diff --git a/telephony/java/com/android/internal/telephony/cat/Input.java b/telephony/java/com/android/internal/telephony/cat/Input.java new file mode 100644 index 0000000..19f724b --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/Input.java @@ -0,0 +1,97 @@ +/* + * 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.gsm.stk; + +import android.graphics.Bitmap; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Container class for STK GET INPUT, GET IN KEY commands parameters. + * + */ +public class Input implements Parcelable { + public String text; + public String defaultText; + public Bitmap icon; + public int minLen; + public int maxLen; + public boolean ucs2; + public boolean packed; + public boolean digitOnly; + public boolean echo; + public boolean yesNo; + public boolean helpAvailable; + + Input() { + text = ""; + defaultText = null; + icon = null; + minLen = 0; + maxLen = 1; + ucs2 = false; + packed = false; + digitOnly = false; + echo = false; + yesNo = false; + helpAvailable = false; + } + + private Input(Parcel in) { + text = in.readString(); + defaultText = in.readString(); + icon = in.readParcelable(null); + minLen = in.readInt(); + maxLen = in.readInt(); + ucs2 = in.readInt() == 1 ? true : false; + packed = in.readInt() == 1 ? true : false; + digitOnly = in.readInt() == 1 ? true : false; + echo = in.readInt() == 1 ? true : false; + yesNo = in.readInt() == 1 ? true : false; + helpAvailable = in.readInt() == 1 ? true : false; + } + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(text); + dest.writeString(defaultText); + dest.writeParcelable(icon, 0); + dest.writeInt(minLen); + dest.writeInt(maxLen); + dest.writeInt(ucs2 ? 1 : 0); + dest.writeInt(packed ? 1 : 0); + dest.writeInt(digitOnly ? 1 : 0); + dest.writeInt(echo ? 1 : 0); + dest.writeInt(yesNo ? 1 : 0); + dest.writeInt(helpAvailable ? 1 : 0); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public Input createFromParcel(Parcel in) { + return new Input(in); + } + + public Input[] newArray(int size) { + return new Input[size]; + } + }; + + boolean setIcon(Bitmap Icon) { return true; } +} \ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/cat/Item.java b/telephony/java/com/android/internal/telephony/cat/Item.java new file mode 100644 index 0000000..b2f338c --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/Item.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2006 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.gsm.stk; + +import android.graphics.Bitmap; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Represents an Item COMPREHENSION-TLV object. + * + * {@hide} + */ +public class Item implements Parcelable { + /** Identifier of the item. */ + public int id; + /** Text string of the item. */ + public String text; + /** Icon of the item */ + public Bitmap icon; + + public Item(int id, String text) { + this.id = id; + this.text = text; + this.icon = null; + } + + public Item(Parcel in) { + id = in.readInt(); + text = in.readString(); + icon = in.readParcelable(null); + } + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(id); + dest.writeString(text); + dest.writeParcelable(icon, flags); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public Item createFromParcel(Parcel in) { + return new Item(in); + } + + public Item[] newArray(int size) { + return new Item[size]; + } + }; + + public String toString() { + return text; + } +} diff --git a/telephony/java/com/android/internal/telephony/cat/LaunchBrowserMode.java b/telephony/java/com/android/internal/telephony/cat/LaunchBrowserMode.java new file mode 100644 index 0000000..302273c --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/LaunchBrowserMode.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2006 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.gsm.stk; + + +/** + * Browser launch mode for LAUNCH BROWSER proactive command. + * + * {@hide} + */ +public enum LaunchBrowserMode { + /** Launch browser if not already launched. */ + LAUNCH_IF_NOT_ALREADY_LAUNCHED, + /** + * Use the existing browser (the browser shall not use the active existing + * secured session). + */ + USE_EXISTING_BROWSER, + /** Close the existing browser session and launch new browser session. */ + LAUNCH_NEW_BROWSER; +} diff --git a/telephony/java/com/android/internal/telephony/cat/Menu.java b/telephony/java/com/android/internal/telephony/cat/Menu.java new file mode 100644 index 0000000..331f69d --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/Menu.java @@ -0,0 +1,105 @@ +/* + * 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.gsm.stk; + +import android.graphics.Bitmap; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.ArrayList; +import java.util.List; + +/** + * Container class for STK menu (SET UP MENU, SELECT ITEM) parameters. + * + */ +public class Menu implements Parcelable { + public List items; + public List titleAttrs; + public PresentationType presentationType; + public String title; + public Bitmap titleIcon; + public int defaultItem; + public boolean softKeyPreferred; + public boolean helpAvailable; + public boolean titleIconSelfExplanatory; + public boolean itemsIconSelfExplanatory; + + public Menu() { + // Create an empty list. + items = new ArrayList(); + title = null; + titleAttrs = null; + defaultItem = 0; + softKeyPreferred = false; + helpAvailable = false; + titleIconSelfExplanatory = false; + itemsIconSelfExplanatory = false; + titleIcon = null; + // set default style to be navigation menu. + presentationType = PresentationType.NAVIGATION_OPTIONS; + } + + private Menu(Parcel in) { + title = in.readString(); + titleIcon = in.readParcelable(null); + // rebuild items list. + items = new ArrayList(); + int size = in.readInt(); + for (int i=0; i CREATOR = new Parcelable.Creator() { + public Menu createFromParcel(Parcel in) { + return new Menu(in); + } + + public Menu[] newArray(int size) { + return new Menu[size]; + } + }; +} diff --git a/telephony/java/com/android/internal/telephony/cat/PresentationType.java b/telephony/java/com/android/internal/telephony/cat/PresentationType.java new file mode 100644 index 0000000..71bdcdc --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/PresentationType.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2006 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.gsm.stk; + + +/** + * Presentation types for SELECT TYPE proactive command. + * + * {@hide} + */ +public enum PresentationType { + /** Presentation type is not specified */ + NOT_SPECIFIED, + /** Presentation as a choice of data values */ + DATA_VALUES, + /** Presentation as a choice of navigation options */ + NAVIGATION_OPTIONS; +} diff --git a/telephony/java/com/android/internal/telephony/cat/ResponseData.java b/telephony/java/com/android/internal/telephony/cat/ResponseData.java new file mode 100644 index 0000000..afd1bba --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/ResponseData.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2006-2007 Google Inc. + * + * 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.gsm.stk; + +import com.android.internal.telephony.EncodeException; +import com.android.internal.telephony.GsmAlphabet; + +import java.io.ByteArrayOutputStream; +import java.io.UnsupportedEncodingException; + +abstract class ResponseData { + /** + * Format the data appropriate for TERMINAL RESPONSE and write it into + * the ByteArrayOutputStream object. + */ + public abstract void format(ByteArrayOutputStream buf); +} + +class SelectItemResponseData extends ResponseData { + // members + private int id; + + public SelectItemResponseData(int id) { + super(); + this.id = id; + } + + @Override + public void format(ByteArrayOutputStream buf) { + // Item identifier object + int tag = 0x80 | ComprehensionTlvTag.ITEM_ID.value(); + buf.write(tag); // tag + buf.write(1); // length + buf.write(id); // identifier of item chosen + } +} + +class GetInkeyInputResponseData extends ResponseData { + // members + private boolean mIsUcs2; + private boolean mIsPacked; + private boolean mIsYesNo; + private boolean mYesNoResponse; + public String mInData; + + // GetInKey Yes/No response characters constants. + protected static final byte GET_INKEY_YES = 0x01; + protected static final byte GET_INKEY_NO = 0x00; + + public GetInkeyInputResponseData(String inData, boolean ucs2, boolean packed) { + super(); + this.mIsUcs2 = ucs2; + this.mIsPacked = packed; + this.mInData = inData; + this.mIsYesNo = false; + } + + public GetInkeyInputResponseData(boolean yesNoResponse) { + super(); + this.mIsUcs2 = false; + this.mIsPacked = false; + this.mInData = ""; + this.mIsYesNo = true; + this.mYesNoResponse = yesNoResponse; + } + + @Override + public void format(ByteArrayOutputStream buf) { + if (buf == null) { + return; + } + + // Text string object + int tag = 0x80 | ComprehensionTlvTag.TEXT_STRING.value(); + buf.write(tag); // tag + + byte[] data; + + if (mIsYesNo) { + data = new byte[1]; + data[0] = mYesNoResponse ? GET_INKEY_YES : GET_INKEY_NO; + } else if (mInData != null && mInData.length() > 0) { + try { + if (mIsUcs2) { + data = mInData.getBytes("UTF-16"); + } else if (mIsPacked) { + int size = mInData.length(); + + byte[] tempData = GsmAlphabet + .stringToGsm7BitPacked(mInData); + data = new byte[size]; + // Since stringToGsm7BitPacked() set byte 0 in the + // returned byte array to the count of septets used... + // copy to a new array without byte 0. + System.arraycopy(tempData, 1, data, 0, size); + } else { + data = GsmAlphabet.stringToGsm8BitPacked(mInData); + } + } catch (UnsupportedEncodingException e) { + data = new byte[0]; + } catch (EncodeException e) { + data = new byte[0]; + } + } else { + data = new byte[0]; + } + + // length - one more for data coding scheme. + buf.write(data.length + 1); + + // data coding scheme + if (mIsUcs2) { + buf.write(0x08); // UCS2 + } else if (mIsPacked) { + buf.write(0x00); // 7 bit packed + } else { + buf.write(0x04); // 8 bit unpacked + } + + for (byte b : data) { + buf.write(b); + } + } +} + + diff --git a/telephony/java/com/android/internal/telephony/cat/ResultCode.java b/telephony/java/com/android/internal/telephony/cat/ResultCode.java new file mode 100644 index 0000000..b96a524 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/ResultCode.java @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2006 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.gsm.stk; + + +/** + * Enumeration for the return code in TERMINAL RESPONSE. + * To get the actual return code for each enum value, call {@link #code() code} + * method. + * + * {@hide} + */ +public enum ResultCode { + + /* + * Results '0X' and '1X' indicate that the command has been performed. + */ + + /** Command performed successfully */ + OK(0x00), + + /** Command performed with partial comprehension */ + PRFRMD_WITH_PARTIAL_COMPREHENSION(0x01), + + /** Command performed, with missing information */ + PRFRMD_WITH_MISSING_INFO(0x02), + + /** REFRESH performed with additional EFs read */ + PRFRMD_WITH_ADDITIONAL_EFS_READ(0x03), + + /** + * Command performed successfully, but requested icon could not be + * displayed + */ + PRFRMD_ICON_NOT_DISPLAYED(0x04), + + /** Command performed, but modified by call control by NAA */ + PRFRMD_MODIFIED_BY_NAA(0x05), + + /** Command performed successfully, limited service */ + PRFRMD_LIMITED_SERVICE(0x06), + + /** Command performed with modification */ + PRFRMD_WITH_MODIFICATION(0x07), + + /** REFRESH performed but indicated NAA was not active */ + PRFRMD_NAA_NOT_ACTIVE(0x08), + + /** Command performed successfully, tone not played */ + PRFRMD_TONE_NOT_PLAYED(0x09), + + /** Proactive UICC session terminated by the user */ + UICC_SESSION_TERM_BY_USER(0x10), + + /** Backward move in the proactive UICC session requested by the user */ + BACKWARD_MOVE_BY_USER(0x11), + + /** No response from user */ + NO_RESPONSE_FROM_USER(0x12), + + /** Help information required by the user */ + HELP_INFO_REQUIRED(0x13), + + /** USSD or SS transaction terminated by the user */ + USSD_SS_SESSION_TERM_BY_USER(0x14), + + + /* + * Results '2X' indicate to the UICC that it may be worth re-trying the + * command at a later opportunity. + */ + + /** Terminal currently unable to process command */ + TERMINAL_CRNTLY_UNABLE_TO_PROCESS(0x20), + + /** Network currently unable to process command */ + NETWORK_CRNTLY_UNABLE_TO_PROCESS(0x21), + + /** User did not accept the proactive command */ + USER_NOT_ACCEPT(0x22), + + /** User cleared down call before connection or network release */ + USER_CLEAR_DOWN_CALL(0x23), + + /** Action in contradiction with the current timer state */ + CONTRADICTION_WITH_TIMER(0x24), + + /** Interaction with call control by NAA, temporary problem */ + NAA_CALL_CONTROL_TEMPORARY(0x25), + + /** Launch browser generic error code */ + LAUNCH_BROWSER_ERROR(0x26), + + /** MMS temporary problem. */ + MMS_TEMPORARY(0x27), + + + /* + * Results '3X' indicate that it is not worth the UICC re-trying with an + * identical command, as it will only get the same response. However, the + * decision to retry lies with the application. + */ + + /** Command beyond terminal's capabilities */ + BEYOND_TERMINAL_CAPABILITY(0x30), + + /** Command type not understood by terminal */ + CMD_TYPE_NOT_UNDERSTOOD(0x31), + + /** Command data not understood by terminal */ + CMD_DATA_NOT_UNDERSTOOD(0x32), + + /** Command number not known by terminal */ + CMD_NUM_NOT_KNOWN(0x33), + + /** SS Return Error */ + SS_RETURN_ERROR(0x34), + + /** SMS RP-ERROR */ + SMS_RP_ERROR(0x35), + + /** Error, required values are missing */ + REQUIRED_VALUES_MISSING(0x36), + + /** USSD Return Error */ + USSD_RETURN_ERROR(0x37), + + /** MultipleCard commands error */ + MULTI_CARDS_CMD_ERROR(0x38), + + /** + * Interaction with call control by USIM or MO short message control by + * USIM, permanent problem + */ + USIM_CALL_CONTROL_PERMANENT(0x39), + + /** Bearer Independent Protocol error */ + BIP_ERROR(0x3a), + + /** Access Technology unable to process command */ + ACCESS_TECH_UNABLE_TO_PROCESS(0x3b), + + /** Frames error */ + FRAMES_ERROR(0x3c), + + /** MMS Error */ + MMS_ERROR(0x3d); + + + private int mCode; + + ResultCode(int code) { + mCode = code; + } + + /** + * Retrieves the actual result code that this object represents. + * @return Actual result code + */ + public int value() { + return mCode; + } + + public static ResultCode fromInt(int value) { + for (ResultCode r : ResultCode.values()) { + if (r.mCode == value) { + return r; + } + } + return null; + } +} diff --git a/telephony/java/com/android/internal/telephony/cat/ResultException.java b/telephony/java/com/android/internal/telephony/cat/ResultException.java new file mode 100644 index 0000000..2eb16c9 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/ResultException.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2006 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.gsm.stk; + + +/** + * Class for errors in the Result object. + * + * {@hide} + */ +public class ResultException extends StkException { + private ResultCode mResult; + private int mAdditionalInfo; + + public ResultException(ResultCode result) { + super(); + + // ETSI TS 102 223, 8.12 -- For the general results '20', '21', '26', + // '38', '39', '3A', '3C', and '3D', it is mandatory for the terminal + // to provide a specific cause value as additional information. + switch (result) { + case TERMINAL_CRNTLY_UNABLE_TO_PROCESS: // 0x20 + case NETWORK_CRNTLY_UNABLE_TO_PROCESS: // 0x21 + case LAUNCH_BROWSER_ERROR: // 0x26 + case MULTI_CARDS_CMD_ERROR: // 0x38 + case USIM_CALL_CONTROL_PERMANENT: // 0x39 + case BIP_ERROR: // 0x3a + case FRAMES_ERROR: // 0x3c + case MMS_ERROR: // 0x3d + throw new AssertionError( + "For result code, " + result + + ", additional information must be given!"); + } + + mResult = result; + mAdditionalInfo = -1; + } + + public ResultException(ResultCode result, int additionalInfo) { + super(); + + if (additionalInfo < 0) { + throw new AssertionError( + "Additional info must be greater than zero!"); + } + + mResult = result; + mAdditionalInfo = additionalInfo; + } + + public ResultCode result() { + return mResult; + } + + public boolean hasAdditionalInfo() { + return mAdditionalInfo >= 0; + } + + public int additionalInfo() { + return mAdditionalInfo; + } +} diff --git a/telephony/java/com/android/internal/telephony/cat/RilMessageDecoder.java b/telephony/java/com/android/internal/telephony/cat/RilMessageDecoder.java new file mode 100644 index 0000000..02852cc --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/RilMessageDecoder.java @@ -0,0 +1,174 @@ +/* + * 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.gsm.stk; + +import com.android.internal.telephony.IccFileHandler; +import com.android.internal.telephony.IccUtils; + +import android.os.Handler; +import com.android.internal.util.HierarchicalState; +import com.android.internal.util.HierarchicalStateMachine; +import android.os.Message; + +/** + * Class used for queuing raw ril messages, decoding them into CommanParams + * objects and sending the result back to the STK Service. + */ +class RilMessageDecoder extends HierarchicalStateMachine { + + // constants + private static final int CMD_START = 1; + private static final int CMD_PARAMS_READY = 2; + + // members + private static RilMessageDecoder sInstance = null; + private CommandParamsFactory mCmdParamsFactory = null; + private RilMessage mCurrentRilMessage = null; + private Handler mCaller = null; + + // States + private StateStart mStateStart = new StateStart(); + private StateCmdParamsReady mStateCmdParamsReady = new StateCmdParamsReady(); + + /** + * Get the singleton instance, constructing if necessary. + * + * @param caller + * @param fh + * @return RilMesssageDecoder + */ + public static synchronized RilMessageDecoder getInstance(Handler caller, IccFileHandler fh) { + if (sInstance == null) { + sInstance = new RilMessageDecoder(caller, fh); + sInstance.start(); + } + return sInstance; + } + + /** + * Start decoding the message parameters, + * when complete MSG_ID_RIL_MSG_DECODED will be returned to caller. + * + * @param rilMsg + */ + public void sendStartDecodingMessageParams(RilMessage rilMsg) { + Message msg = obtainMessage(CMD_START); + msg.obj = rilMsg; + sendMessage(msg); + } + + /** + * The command parameters have been decoded. + * + * @param resCode + * @param cmdParams + */ + public void sendMsgParamsDecoded(ResultCode resCode, CommandParams cmdParams) { + Message msg = obtainMessage(RilMessageDecoder.CMD_PARAMS_READY); + msg.arg1 = resCode.value(); + msg.obj = cmdParams; + sendMessage(msg); + } + + private void sendCmdForExecution(RilMessage rilMsg) { + Message msg = mCaller.obtainMessage(StkService.MSG_ID_RIL_MSG_DECODED, + new RilMessage(rilMsg)); + msg.sendToTarget(); + } + + private RilMessageDecoder(Handler caller, IccFileHandler fh) { + super("RilMessageDecoder"); + + addState(mStateStart); + addState(mStateCmdParamsReady); + setInitialState(mStateStart); + + mCaller = caller; + mCmdParamsFactory = CommandParamsFactory.getInstance(this, fh); + } + + private class StateStart extends HierarchicalState { + @Override protected boolean processMessage(Message msg) { + if (msg.what == CMD_START) { + if (decodeMessageParams((RilMessage)msg.obj)) { + transitionTo(mStateCmdParamsReady); + } + } else { + StkLog.d(this, "StateStart unexpected expecting START=" + + CMD_START + " got " + msg.what); + } + return true; + } + } + + private class StateCmdParamsReady extends HierarchicalState { + @Override protected boolean processMessage(Message msg) { + if (msg.what == CMD_PARAMS_READY) { + mCurrentRilMessage.mResCode = ResultCode.fromInt(msg.arg1); + mCurrentRilMessage.mData = msg.obj; + sendCmdForExecution(mCurrentRilMessage); + transitionTo(mStateStart); + } else { + StkLog.d(this, "StateCmdParamsReady expecting CMD_PARAMS_READY=" + + CMD_PARAMS_READY + " got " + msg.what); + deferMessage(msg); + } + return true; + } + } + + private boolean decodeMessageParams(RilMessage rilMsg) { + boolean decodingStarted; + + mCurrentRilMessage = rilMsg; + switch(rilMsg.mId) { + case StkService.MSG_ID_SESSION_END: + case StkService.MSG_ID_CALL_SETUP: + mCurrentRilMessage.mResCode = ResultCode.OK; + sendCmdForExecution(mCurrentRilMessage); + decodingStarted = false; + break; + case StkService.MSG_ID_PROACTIVE_COMMAND: + case StkService.MSG_ID_EVENT_NOTIFY: + case StkService.MSG_ID_REFRESH: + byte[] rawData = null; + try { + rawData = IccUtils.hexStringToBytes((String) rilMsg.mData); + } catch (Exception e) { + // zombie messages are dropped + StkLog.d(this, "decodeMessageParams dropping zombie messages"); + decodingStarted = false; + break; + } + try { + // Start asynch parsing of the command parameters. + mCmdParamsFactory.make(BerTlv.decode(rawData)); + decodingStarted = true; + } catch (ResultException e) { + // send to Service for proper RIL communication. + mCurrentRilMessage.mResCode = e.result(); + sendCmdForExecution(mCurrentRilMessage); + decodingStarted = false; + } + break; + default: + decodingStarted = false; + break; + } + return decodingStarted; + } +} diff --git a/telephony/java/com/android/internal/telephony/cat/TextAlignment.java b/telephony/java/com/android/internal/telephony/cat/TextAlignment.java new file mode 100644 index 0000000..c5dd50e --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/TextAlignment.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2006 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.gsm.stk; + + +/** + * Enumeration for representing text alignment. + * + * {@hide} + */ +public enum TextAlignment { + LEFT(0x0), + CENTER(0x1), + RIGHT(0x2), + /** Language dependent (default) */ + DEFAULT(0x3); + + private int mValue; + + TextAlignment(int value) { + mValue = value; + } + + /** + * Create a TextAlignment object. + * @param value Integer value to be converted to a TextAlignment object. + * @return TextAlignment object whose value is {@code value}. If no + * TextAlignment object has that value, null is returned. + */ + public static TextAlignment fromInt(int value) { + for (TextAlignment e : TextAlignment.values()) { + if (e.mValue == value) { + return e; + } + } + return null; + } +} diff --git a/telephony/java/com/android/internal/telephony/cat/TextAttribute.java b/telephony/java/com/android/internal/telephony/cat/TextAttribute.java new file mode 100644 index 0000000..ace4300 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/TextAttribute.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2006 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.gsm.stk; + + +/** + * Class for representing text attributes for SIM Toolkit. + * + * {@hide} + */ +public class TextAttribute { + public int start; + public int length; + public TextAlignment align; + public FontSize size; + public boolean bold; + public boolean italic; + public boolean underlined; + public boolean strikeThrough; + public TextColor color; + + public TextAttribute(int start, int length, TextAlignment align, + FontSize size, boolean bold, boolean italic, boolean underlined, + boolean strikeThrough, TextColor color) { + this.start = start; + this.length = length; + this.align = align; + this.size = size; + this.bold = bold; + this.italic = italic; + this.underlined = underlined; + this.strikeThrough = strikeThrough; + this.color = color; + } +} diff --git a/telephony/java/com/android/internal/telephony/cat/TextColor.java b/telephony/java/com/android/internal/telephony/cat/TextColor.java new file mode 100644 index 0000000..126fc62 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/TextColor.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2006 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.gsm.stk; + + +/** + * Enumeration for representing text color. + * + * {@hide} + */ +public enum TextColor { + BLACK(0x0), + DARK_GRAY(0x1), + DARK_RED(0x2), + DARK_YELLOW(0x3), + DARK_GREEN(0x4), + DARK_CYAN(0x5), + DARK_BLUE(0x6), + DARK_MAGENTA(0x7), + GRAY(0x8), + WHITE(0x9), + BRIGHT_RED(0xa), + BRIGHT_YELLOW(0xb), + BRIGHT_GREEN(0xc), + BRIGHT_CYAN(0xd), + BRIGHT_BLUE(0xe), + BRIGHT_MAGENTA(0xf); + + private int mValue; + + TextColor(int value) { + mValue = value; + } + + /** + * Create a TextColor object. + * @param value Integer value to be converted to a TextColor object. + * @return TextColor object whose value is {@code value}. If no TextColor + * object has that value, null is returned. + */ + public static TextColor fromInt(int value) { + for (TextColor e : TextColor.values()) { + if (e.mValue == value) { + return e; + } + } + return null; + } +} diff --git a/telephony/java/com/android/internal/telephony/cat/TextMessage.java b/telephony/java/com/android/internal/telephony/cat/TextMessage.java new file mode 100644 index 0000000..3b6a09a --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/TextMessage.java @@ -0,0 +1,71 @@ +/* + * 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.gsm.stk; + +import android.graphics.Bitmap; +import android.os.Parcel; +import android.os.Parcelable; + +public class TextMessage implements Parcelable { + public String title = ""; + public String text = null; + public Bitmap icon = null; + public boolean iconSelfExplanatory = false; + public boolean isHighPriority = false; + public boolean responseNeeded = true; + public boolean userClear = false; + public Duration duration = null; + + TextMessage() { + } + + private TextMessage(Parcel in) { + title = in.readString(); + text = in.readString(); + icon = in.readParcelable(null); + iconSelfExplanatory = in.readInt() == 1 ? true : false; + isHighPriority = in.readInt() == 1 ? true : false; + responseNeeded = in.readInt() == 1 ? true : false; + userClear = in.readInt() == 1 ? true : false; + duration = in.readParcelable(null); + } + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(title); + dest.writeString(text); + dest.writeParcelable(icon, 0); + dest.writeInt(iconSelfExplanatory ? 1 : 0); + dest.writeInt(isHighPriority ? 1 : 0); + dest.writeInt(responseNeeded ? 1 : 0); + dest.writeInt(userClear ? 1 : 0); + dest.writeParcelable(duration, 0); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public TextMessage createFromParcel(Parcel in) { + return new TextMessage(in); + } + + public TextMessage[] newArray(int size) { + return new TextMessage[size]; + } + }; +} \ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/cat/Tone.java b/telephony/java/com/android/internal/telephony/cat/Tone.java new file mode 100644 index 0000000..b64e777 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/Tone.java @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2006 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.gsm.stk; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Enumeration for representing the tone values for use with PLAY TONE + * proactive commands. + * + * {@hide} + */ +public enum Tone implements Parcelable { + // Standard supervisory tones + + /** + * Dial tone. + */ + DIAL(0x01), + + /** + * Called subscriber busy. + */ + BUSY(0x02), + + /** + * Congestion. + */ + CONGESTION(0x03), + + /** + * Radio path acknowledge. + */ + RADIO_PATH_ACK(0x04), + + /** + * Radio path not available / Call dropped. + */ + RADIO_PATH_NOT_AVAILABLE(0x05), + + /** + * Error/Special information. + */ + ERROR_SPECIAL_INFO(0x06), + + /** + * Call waiting tone. + */ + CALL_WAITING(0x07), + + /** + * Ringing tone. + */ + RINGING(0x08), + + // Terminal proprietary tones + + /** + * General beep. + */ + GENERAL_BEEP(0x10), + + /** + * Positive acknowledgement tone. + */ + POSITIVE_ACK(0x11), + + /** + * Negative acknowledgement tone. + */ + NEGATIVE_ACK(0x12), + + /** + * Ringing tone as selected by the user for incoming speech call. + */ + INCOMING_SPEECH_CALL(0x13), + + /** + * Alert tone as selected by the user for incoming SMS. + */ + INCOMING_SMS(0x14), + + /** + * Critical alert. + * This tone is to be used in critical situations. The terminal shall make + * every effort to alert the user when this tone is indicated independent + * from the volume setting in the terminal. + */ + CRITICAL_ALERT(0x15), + + /** + * Vibrate only, if available. + */ + VIBRATE_ONLY(0x20), + + // Themed tones + + /** + * Happy tone. + */ + HAPPY(0x30), + + /** + * Sad tone. + */ + SAD(0x31), + + /** + * Urgent action tone. + */ + URGENT(0x32), + + /** + * Question tone. + */ + QUESTION(0x33), + + /** + * Message received tone. + */ + MESSAGE_RECEIVED(0x34), + + // Melody tones + MELODY_1(0x40), + MELODY_2(0x41), + MELODY_3(0x42), + MELODY_4(0x43), + MELODY_5(0x44), + MELODY_6(0x45), + MELODY_7(0x46), + MELODY_8(0x47); + + private int mValue; + + Tone(int value) { + mValue = value; + } + + /** + * Create a Tone object. + * @param value Integer value to be converted to a Tone object. + * @return Tone object whose value is {@code value}. If no Tone object has + * that value, null is returned. + */ + public static Tone fromInt(int value) { + for (Tone e : Tone.values()) { + if (e.mValue == value) { + return e; + } + } + return null; + } + + Tone(Parcel in) { + mValue = in.readInt(); + } + + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(ordinal()); + } + + public int describeContents() { + return 0; + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public Tone createFromParcel(Parcel in) { + return Tone.values()[in.readInt()]; + } + + public Tone[] newArray(int size) { + return new Tone[size]; + } + }; +} diff --git a/telephony/java/com/android/internal/telephony/cat/ToneSettings.java b/telephony/java/com/android/internal/telephony/cat/ToneSettings.java new file mode 100644 index 0000000..90cc6c1 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/ToneSettings.java @@ -0,0 +1,62 @@ +/* + * 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.gsm.stk; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Container class for PlayTone commands parameters. + * + */ +public class ToneSettings implements Parcelable { + public Duration duration; + public Tone tone; + public boolean vibrate; + + public ToneSettings(Duration duration, Tone tone, boolean vibrate) { + this.duration = duration; + this.tone = tone; + this.vibrate = vibrate; + } + + private ToneSettings(Parcel in) { + duration = in.readParcelable(null); + tone = in.readParcelable(null); + vibrate = in.readInt() == 1; + } + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel dest, int flags) { + dest.writeParcelable(duration, 0); + dest.writeParcelable(tone, 0); + dest.writeInt(vibrate ? 1 : 0); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public ToneSettings createFromParcel(Parcel in) { + return new ToneSettings(in); + } + + public ToneSettings[] newArray(int size) { + return new ToneSettings[size]; + } + }; +} \ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/cat/ValueParser.java b/telephony/java/com/android/internal/telephony/cat/ValueParser.java new file mode 100644 index 0000000..09a860e --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/ValueParser.java @@ -0,0 +1,336 @@ +/* + * Copyright (C) 2006-2007 Google Inc. + * + * 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.gsm.stk; + +import com.android.internal.telephony.GsmAlphabet; +import com.android.internal.telephony.IccUtils; +import com.android.internal.telephony.gsm.stk.Duration.TimeUnit; + +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.List; + +abstract class ValueParser { + + /** + * Search for a Command Details object from a list. + * + * @param ctlvs List of ComprehensionTlv objects used for search + * @return An CtlvCommandDetails object found from the objects. If no + * Command Details object is found, ResultException is thrown. + * @throws ResultException + */ + static CommandDetails retrieveCommandDetails(ComprehensionTlv ctlv) + throws ResultException { + + CommandDetails cmdDet = new CommandDetails(); + byte[] rawValue = ctlv.getRawValue(); + int valueIndex = ctlv.getValueIndex(); + try { + cmdDet.compRequired = ctlv.isComprehensionRequired(); + cmdDet.commandNumber = rawValue[valueIndex] & 0xff; + cmdDet.typeOfCommand = rawValue[valueIndex + 1] & 0xff; + cmdDet.commandQualifier = rawValue[valueIndex + 2] & 0xff; + return cmdDet; + } catch (IndexOutOfBoundsException e) { + throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + } + + /** + * Search for a Device Identities object from a list. + * + * @param ctlvs List of ComprehensionTlv objects used for search + * @return An CtlvDeviceIdentities object found from the objects. If no + * Command Details object is found, ResultException is thrown. + * @throws ResultException + */ + static DeviceIdentities retrieveDeviceIdentities(ComprehensionTlv ctlv) + throws ResultException { + + DeviceIdentities devIds = new DeviceIdentities(); + byte[] rawValue = ctlv.getRawValue(); + int valueIndex = ctlv.getValueIndex(); + try { + devIds.sourceId = rawValue[valueIndex] & 0xff; + devIds.destinationId = rawValue[valueIndex + 1] & 0xff; + return devIds; + } catch (IndexOutOfBoundsException e) { + throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); + } + } + + /** + * Retrieves Duration information from the Duration COMPREHENSION-TLV + * object. + * + * @param ctlv A Text Attribute COMPREHENSION-TLV object + * @return A Duration object + * @throws ResultException + */ + static Duration retrieveDuration(ComprehensionTlv ctlv) throws ResultException { + int timeInterval = 0; + TimeUnit timeUnit = TimeUnit.SECOND; + + byte[] rawValue = ctlv.getRawValue(); + int valueIndex = ctlv.getValueIndex(); + + try { + timeUnit = TimeUnit.values()[(rawValue[valueIndex] & 0xff)]; + timeInterval = rawValue[valueIndex + 1] & 0xff; + } catch (IndexOutOfBoundsException e) { + throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + return new Duration(timeInterval, timeUnit); + } + + /** + * Retrieves Item information from the COMPREHENSION-TLV object. + * + * @param ctlv A Text Attribute COMPREHENSION-TLV object + * @return An Item + * @throws ResultException + */ + static Item retrieveItem(ComprehensionTlv ctlv) throws ResultException { + Item item = null; + + byte[] rawValue = ctlv.getRawValue(); + int valueIndex = ctlv.getValueIndex(); + int length = ctlv.getLength(); + + if (length != 0) { + int textLen = length - 1; + + try { + int id = rawValue[valueIndex] & 0xff; + String text = IccUtils.adnStringFieldToString(rawValue, + valueIndex + 1, textLen); + item = new Item(id, text); + } catch (IndexOutOfBoundsException e) { + throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + } + + return item; + } + + /** + * Retrieves Item id information from the COMPREHENSION-TLV object. + * + * @param ctlv A Text Attribute COMPREHENSION-TLV object + * @return An Item id + * @throws ResultException + */ + static int retrieveItemId(ComprehensionTlv ctlv) throws ResultException { + int id = 0; + + byte[] rawValue = ctlv.getRawValue(); + int valueIndex = ctlv.getValueIndex(); + + try { + id = rawValue[valueIndex] & 0xff; + } catch (IndexOutOfBoundsException e) { + throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + + return id; + } + + /** + * Retrieves icon id from an Icon Identifier COMPREHENSION-TLV object + * + * @param ctlv An Icon Identifier COMPREHENSION-TLV object + * @return IconId instance + * @throws ResultException + */ + static IconId retrieveIconId(ComprehensionTlv ctlv) throws ResultException { + IconId id = new IconId(); + + byte[] rawValue = ctlv.getRawValue(); + int valueIndex = ctlv.getValueIndex(); + try { + id.selfExplanatory = (rawValue[valueIndex++] & 0xff) == 0x00; + id.recordNumber = rawValue[valueIndex] & 0xff; + } catch (IndexOutOfBoundsException e) { + throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + + return id; + } + + /** + * Retrieves item icons id from an Icon Identifier List COMPREHENSION-TLV + * object + * + * @param ctlv An Item Icon List Identifier COMPREHENSION-TLV object + * @return ItemsIconId instance + * @throws ResultException + */ + static ItemsIconId retrieveItemsIconId(ComprehensionTlv ctlv) + throws ResultException { + StkLog.d("ValueParser", "retrieveItemsIconId:"); + ItemsIconId id = new ItemsIconId(); + + byte[] rawValue = ctlv.getRawValue(); + int valueIndex = ctlv.getValueIndex(); + int numOfItems = ctlv.getLength() - 1; + id.recordNumbers = new int[numOfItems]; + + try { + // get icon self-explanatory + id.selfExplanatory = (rawValue[valueIndex++] & 0xff) == 0x00; + + for (int index = 0; index < numOfItems;) { + id.recordNumbers[index++] = rawValue[valueIndex++]; + } + } catch (IndexOutOfBoundsException e) { + throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + return id; + } + + /** + * Retrieves text attribute information from the Text Attribute + * COMPREHENSION-TLV object. + * + * @param ctlv A Text Attribute COMPREHENSION-TLV object + * @return A list of TextAttribute objects + * @throws ResultException + */ + static List retrieveTextAttribute(ComprehensionTlv ctlv) + throws ResultException { + ArrayList lst = new ArrayList(); + + byte[] rawValue = ctlv.getRawValue(); + int valueIndex = ctlv.getValueIndex(); + int length = ctlv.getLength(); + + if (length != 0) { + // Each attribute is consisted of four bytes + int itemCount = length / 4; + + try { + for (int i = 0; i < itemCount; i++, valueIndex += 4) { + int start = rawValue[valueIndex] & 0xff; + int textLength = rawValue[valueIndex + 1] & 0xff; + int format = rawValue[valueIndex + 2] & 0xff; + int colorValue = rawValue[valueIndex + 3] & 0xff; + + int alignValue = format & 0x03; + TextAlignment align = TextAlignment.fromInt(alignValue); + + int sizeValue = (format >> 2) & 0x03; + FontSize size = FontSize.fromInt(sizeValue); + if (size == null) { + // Font size value is not defined. Use default. + size = FontSize.NORMAL; + } + + boolean bold = (format & 0x10) != 0; + boolean italic = (format & 0x20) != 0; + boolean underlined = (format & 0x40) != 0; + boolean strikeThrough = (format & 0x80) != 0; + + TextColor color = TextColor.fromInt(colorValue); + + TextAttribute attr = new TextAttribute(start, textLength, + align, size, bold, italic, underlined, + strikeThrough, color); + lst.add(attr); + } + + return lst; + + } catch (IndexOutOfBoundsException e) { + throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + } + return null; + } + + + /** + * Retrieves alpha identifier from an Alpha Identifier COMPREHENSION-TLV + * object. + * + * @param ctlv An Alpha Identifier COMPREHENSION-TLV object + * @return String corresponding to the alpha identifier + * @throws ResultException + */ + static String retrieveAlphaId(ComprehensionTlv ctlv) throws ResultException { + + byte[] rawValue = ctlv.getRawValue(); + int valueIndex = ctlv.getValueIndex(); + int length = ctlv.getLength(); + if (length != 0) { + try { + return IccUtils.adnStringFieldToString(rawValue, valueIndex, + length); + } catch (IndexOutOfBoundsException e) { + throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + } + return null; + } + + /** + * Retrieves text from the Text COMPREHENSION-TLV object, and decodes it + * into a Java String. + * + * @param ctlv A Text COMPREHENSION-TLV object + * @return A Java String object decoded from the Text object + * @throws ResultException + */ + static String retrieveTextString(ComprehensionTlv ctlv) throws ResultException { + byte[] rawValue = ctlv.getRawValue(); + int valueIndex = ctlv.getValueIndex(); + byte codingScheme = 0x00; + String text = null; + int textLen = ctlv.getLength(); + + // In case the text length is 0, return a null string. + if (textLen == 0) { + return text; + } else { + // one byte is coding scheme + textLen -= 1; + } + + try { + codingScheme = (byte) (rawValue[valueIndex] & 0x0c); + + if (codingScheme == 0x00) { // GSM 7-bit packed + text = GsmAlphabet.gsm7BitPackedToString(rawValue, + valueIndex + 1, (textLen * 8) / 7); + } else if (codingScheme == 0x04) { // GSM 8-bit unpacked + text = GsmAlphabet.gsm8BitUnpackedToString(rawValue, + valueIndex + 1, textLen); + } else if (codingScheme == 0x08) { // UCS2 + text = new String(rawValue, valueIndex + 1, textLen, "UTF-16"); + } else { + throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + + return text; + } catch (IndexOutOfBoundsException e) { + throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } catch (UnsupportedEncodingException e) { + // This should never happen. + throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + } +} diff --git a/telephony/java/com/android/internal/telephony/cat/package.html b/telephony/java/com/android/internal/telephony/cat/package.html new file mode 100644 index 0000000..c285b57 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cat/package.html @@ -0,0 +1,5 @@ + + +Provides classes for SIM Toolkit Service. + + diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java b/telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java deleted file mode 100644 index 58f1f97..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2006 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.gsm.stk; - -/** - * Interface for communication between STK App and STK Telephony - * - * {@hide} - */ -public interface AppInterface { - - /* - * Intent's actions which are broadcasted by the Telephony once a new STK - * proactive command, session end arrive. - */ - public static final String STK_CMD_ACTION = - "android.intent.action.stk.command"; - public static final String STK_SESSION_END_ACTION = - "android.intent.action.stk.session_end"; - - /* - * Callback function from app to telephony to pass a result code and user's - * input back to the SIM. - */ - void onCmdResponse(StkResponseMessage resMsg); - - /* - * Enumeration for representing "Type of Command" of proactive commands. - * Those are the only commands which are supported by the Telephony. Any app - * implementation should support those. - */ - public static enum CommandType { - DISPLAY_TEXT(0x21), - GET_INKEY(0x22), - GET_INPUT(0x23), - LAUNCH_BROWSER(0x15), - PLAY_TONE(0x20), - REFRESH(0x01), - SELECT_ITEM(0x24), - SEND_SS(0x11), - SEND_USSD(0x12), - SEND_SMS(0x13), - SEND_DTMF(0x14), - SET_UP_EVENT_LIST(0x05), - SET_UP_IDLE_MODE_TEXT(0x28), - SET_UP_MENU(0x25), - SET_UP_CALL(0x10); - - private int mValue; - - CommandType(int value) { - mValue = value; - } - - public int value() { - return mValue; - } - - /** - * Create a CommandType object. - * - * @param value Integer value to be converted to a CommandType object. - * @return CommandType object whose "Type of Command" value is {@code - * value}. If no CommandType object has that value, null is - * returned. - */ - public static CommandType fromInt(int value) { - for (CommandType e : CommandType.values()) { - if (e.mValue == value) { - return e; - } - } - return null; - } - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/BerTlv.java b/telephony/java/com/android/internal/telephony/gsm/stk/BerTlv.java deleted file mode 100644 index 19d3279..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/BerTlv.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2006 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.gsm.stk; - -import java.util.List; - -/** - * Class for representing BER-TLV objects. - * - * @see "ETSI TS 102 223 Annex C" for more information. - * - * {@hide} - */ -class BerTlv { - private int mTag = BER_UNKNOWN_TAG; - private List mCompTlvs = null; - - public static final int BER_UNKNOWN_TAG = 0x00; - public static final int BER_PROACTIVE_COMMAND_TAG = 0xd0; - public static final int BER_MENU_SELECTION_TAG = 0xd3; - public static final int BER_EVENT_DOWNLOAD_TAG = 0xd6; - - private BerTlv(int tag, List ctlvs) { - mTag = tag; - mCompTlvs = ctlvs; - } - - /** - * Gets a list of ComprehensionTlv objects contained in this BER-TLV object. - * - * @return A list of COMPREHENSION-TLV object - */ - public List getComprehensionTlvs() { - return mCompTlvs; - } - - /** - * Gets a tag id of the BER-TLV object. - * - * @return A tag integer. - */ - public int getTag() { - return mTag; - } - - /** - * Decodes a BER-TLV object from a byte array. - * - * @param data A byte array to decode from - * @return A BER-TLV object decoded - * @throws ResultException - */ - public static BerTlv decode(byte[] data) throws ResultException { - int curIndex = 0; - int endIndex = data.length; - int tag, length = 0; - - try { - /* tag */ - tag = data[curIndex++] & 0xff; - if (tag == BER_PROACTIVE_COMMAND_TAG) { - /* length */ - int temp = data[curIndex++] & 0xff; - if (temp < 0x80) { - length = temp; - } else if (temp == 0x81) { - temp = data[curIndex++] & 0xff; - if (temp < 0x80) { - throw new ResultException( - ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - length = temp; - } else { - throw new ResultException( - ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } else { - if (ComprehensionTlvTag.COMMAND_DETAILS.value() == (tag & ~0x80)) { - tag = BER_UNKNOWN_TAG; - curIndex = 0; - } - } - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); - } catch (ResultException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - - /* COMPREHENSION-TLVs */ - if (endIndex - curIndex < length) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - - List ctlvs = ComprehensionTlv.decodeMany(data, - curIndex); - - return new BerTlv(tag, ctlvs); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java b/telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java deleted file mode 100644 index e81ff98..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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.gsm.stk; - -import android.os.Parcel; -import android.os.Parcelable; - -abstract class ValueObject { - abstract ComprehensionTlvTag getTag(); -} - -/** - * Class for Command Detailes object of proactive commands from SIM. - * {@hide} - */ -class CommandDetails extends ValueObject implements Parcelable { - public boolean compRequired; - public int commandNumber; - public int typeOfCommand; - public int commandQualifier; - - public ComprehensionTlvTag getTag() { - return ComprehensionTlvTag.COMMAND_DETAILS; - } - - CommandDetails() { - } - - public boolean compareTo(CommandDetails other) { - return (this.compRequired == other.compRequired && - this.commandNumber == other.commandNumber && - this.commandQualifier == other.commandQualifier && - this.typeOfCommand == other.typeOfCommand); - } - - public CommandDetails(Parcel in) { - compRequired = true; - commandNumber = in.readInt(); - typeOfCommand = in.readInt(); - commandQualifier = in.readInt(); - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(commandNumber); - dest.writeInt(typeOfCommand); - dest.writeInt(commandQualifier); - } - - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - public CommandDetails createFromParcel(Parcel in) { - return new CommandDetails(in); - } - - public CommandDetails[] newArray(int size) { - return new CommandDetails[size]; - } - }; - - public int describeContents() { - return 0; - } -} - -class DeviceIdentities extends ValueObject { - public int sourceId; - public int destinationId; - - ComprehensionTlvTag getTag() { - return ComprehensionTlvTag.DEVICE_IDENTITIES; - } -} - -// Container class to hold icon identifier value. -class IconId extends ValueObject { - int recordNumber; - boolean selfExplanatory; - - ComprehensionTlvTag getTag() { - return ComprehensionTlvTag.ICON_ID; - } -} - -// Container class to hold item icon identifier list value. -class ItemsIconId extends ValueObject { - int [] recordNumbers; - boolean selfExplanatory; - - ComprehensionTlvTag getTag() { - return ComprehensionTlvTag.ITEM_ICON_ID_LIST; - } -} \ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java b/telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java deleted file mode 100644 index 3da652f..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * 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.gsm.stk; - -import android.graphics.Bitmap; - -/** - * Container class for proactive command parameters. - * - */ -class CommandParams { - CommandDetails cmdDet; - - CommandParams(CommandDetails cmdDet) { - this.cmdDet = cmdDet; - } - - AppInterface.CommandType getCommandType() { - return AppInterface.CommandType.fromInt(cmdDet.typeOfCommand); - } - - boolean setIcon(Bitmap icon) { return true; } -} - -class DisplayTextParams extends CommandParams { - TextMessage textMsg; - - DisplayTextParams(CommandDetails cmdDet, TextMessage textMsg) { - super(cmdDet); - this.textMsg = textMsg; - } - - boolean setIcon(Bitmap icon) { - if (icon != null && textMsg != null) { - textMsg.icon = icon; - return true; - } - return false; - } -} - -class LaunchBrowserParams extends CommandParams { - TextMessage confirmMsg; - LaunchBrowserMode mode; - String url; - - LaunchBrowserParams(CommandDetails cmdDet, TextMessage confirmMsg, - String url, LaunchBrowserMode mode) { - super(cmdDet); - this.confirmMsg = confirmMsg; - this.mode = mode; - this.url = url; - } - - boolean setIcon(Bitmap icon) { - if (icon != null && confirmMsg != null) { - confirmMsg.icon = icon; - return true; - } - return false; - } -} - -class PlayToneParams extends CommandParams { - TextMessage textMsg; - ToneSettings settings; - - PlayToneParams(CommandDetails cmdDet, TextMessage textMsg, - Tone tone, Duration duration, boolean vibrate) { - super(cmdDet); - this.textMsg = textMsg; - this.settings = new ToneSettings(duration, tone, vibrate); - } - - boolean setIcon(Bitmap icon) { - if (icon != null && textMsg != null) { - textMsg.icon = icon; - return true; - } - return false; - } -} - -class CallSetupParams extends CommandParams { - TextMessage confirmMsg; - TextMessage callMsg; - - CallSetupParams(CommandDetails cmdDet, TextMessage confirmMsg, - TextMessage callMsg) { - super(cmdDet); - this.confirmMsg = confirmMsg; - this.callMsg = callMsg; - } - - boolean setIcon(Bitmap icon) { - if (icon == null) { - return false; - } - if (confirmMsg != null && confirmMsg.icon == null) { - confirmMsg.icon = icon; - return true; - } else if (callMsg != null && callMsg.icon == null) { - callMsg.icon = icon; - return true; - } - return false; - } -} - -class SelectItemParams extends CommandParams { - Menu menu = null; - boolean loadTitleIcon = false; - - SelectItemParams(CommandDetails cmdDet, Menu menu, boolean loadTitleIcon) { - super(cmdDet); - this.menu = menu; - this.loadTitleIcon = loadTitleIcon; - } - - boolean setIcon(Bitmap icon) { - if (icon != null && menu != null) { - if (loadTitleIcon && menu.titleIcon == null) { - menu.titleIcon = icon; - } else { - for (Item item : menu.items) { - if (item.icon != null) { - continue; - } - item.icon = icon; - break; - } - } - return true; - } - return false; - } -} - -class GetInputParams extends CommandParams { - Input input = null; - - GetInputParams(CommandDetails cmdDet, Input input) { - super(cmdDet); - this.input = input; - } - - boolean setIcon(Bitmap icon) { - if (icon != null && input != null) { - input.icon = icon; - } - return true; - } -} - - diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java b/telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java deleted file mode 100644 index 2364387..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java +++ /dev/null @@ -1,866 +0,0 @@ -/* - * 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.gsm.stk; - -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; - - 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) { - StkLog.d(this, "Failed to procees command details"); - } - } - } - 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) { - sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD); - 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; - default: - // unsupported proactive commands - mCmdParams = new CommandParams(cmdDet); - sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD); - return; - } - } catch (ResultException 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 { - - StkLog.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 { - - StkLog.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 { - - StkLog.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); - } - - 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; - - 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 { - - StkLog.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) { - - StkLog.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 { - - StkLog.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) { - // STK 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 { - - StkLog.d(this, "process EventNotify"); - - TextMessage textMsg = new TextMessage(); - IconId iconId = null; - - ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, - ctlvs); - if (ctlv != null) { - textMsg.text = ValueParser.retrieveAlphaId(ctlv); - } else { - throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); - } - - 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) { - - StkLog.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 { - - StkLog.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); - if (ctlv != null) { - 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 { - - StkLog.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 { - StkLog.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); - if (ctlv != null) { - 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; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java b/telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java deleted file mode 100644 index ffde6a3..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (C) 2006 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.gsm.stk; - -import java.util.ArrayList; -import java.util.List; - - -/** - * Class for representing COMPREHENSION-TLV objects. - * - * @see "ETSI TS 101 220 subsection 7.1.1" - * - * {@hide} - */ -class ComprehensionTlv { - private int mTag; - private boolean mCr; - private int mLength; - private int mValueIndex; - private byte[] mRawValue; - - /** - * Constructor. Private on purpose. Use - * {@link #decodeMany(byte[], int) decodeMany} or - * {@link #decode(byte[], int) decode} method. - * - * @param tag The tag for this object - * @param cr Comprehension Required flag - * @param length Length of the value - * @param data Byte array containing the value - * @param valueIndex Index in data at which the value starts - */ - protected ComprehensionTlv(int tag, boolean cr, int length, byte[] data, - int valueIndex) { - mTag = tag; - mCr = cr; - mLength = length; - mValueIndex = valueIndex; - mRawValue = data; - } - - public int getTag() { - return mTag; - } - - public boolean isComprehensionRequired() { - return mCr; - } - - public int getLength() { - return mLength; - } - - public int getValueIndex() { - return mValueIndex; - } - - public byte[] getRawValue() { - return mRawValue; - } - - /** - * Parses a list of COMPREHENSION-TLV objects from a byte array. - * - * @param data A byte array containing data to be parsed - * @param startIndex Index in data at which to start parsing - * @return A list of COMPREHENSION-TLV objects parsed - * @throws ResultException - */ - public static List decodeMany(byte[] data, int startIndex) - throws ResultException { - ArrayList items = new ArrayList(); - int endIndex = data.length; - while (startIndex < endIndex) { - ComprehensionTlv ctlv = ComprehensionTlv.decode(data, startIndex); - items.add(ctlv); - startIndex = ctlv.mValueIndex + ctlv.mLength; - } - - return items; - } - - /** - * Parses an COMPREHENSION-TLV object from a byte array. - * - * @param data A byte array containing data to be parsed - * @param startIndex Index in data at which to start parsing - * @return A COMPREHENSION-TLV object parsed - * @throws ResultException - */ - public static ComprehensionTlv decode(byte[] data, int startIndex) - throws ResultException { - try { - int curIndex = startIndex; - int endIndex = data.length; - - /* tag */ - int tag; - boolean cr; // Comprehension required flag - int temp = data[curIndex++] & 0xff; - switch (temp) { - case 0: - case 0xff: - case 0x80: - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - - case 0x7f: // tag is in three-byte format - tag = ((data[curIndex] & 0xff) << 8) - | (data[curIndex + 1] & 0xff); - cr = (tag & 0x8000) != 0; - tag &= ~0x8000; - curIndex += 2; - break; - - default: // tag is in single-byte format - tag = temp; - cr = (tag & 0x80) != 0; - tag &= ~0x80; - break; - } - - /* length */ - int length; - temp = data[curIndex++] & 0xff; - if (temp < 0x80) { - length = temp; - } else if (temp == 0x81) { - length = data[curIndex++] & 0xff; - if (length < 0x80) { - throw new ResultException( - ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } else if (temp == 0x82) { - length = ((data[curIndex] & 0xff) << 8) - | (data[curIndex + 1] & 0xff); - curIndex += 2; - if (length < 0x100) { - throw new ResultException( - ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } else if (temp == 0x83) { - length = ((data[curIndex] & 0xff) << 16) - | ((data[curIndex + 1] & 0xff) << 8) - | (data[curIndex + 2] & 0xff); - curIndex += 3; - if (length < 0x10000) { - throw new ResultException( - ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } else { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - - return new ComprehensionTlv(tag, cr, length, data, curIndex); - - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Duration.java b/telephony/java/com/android/internal/telephony/gsm/stk/Duration.java deleted file mode 100644 index 9d8cc97..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/Duration.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2006 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.gsm.stk; - -import android.os.Parcel; -import android.os.Parcelable; - - -/** - * Class for representing "Duration" object for STK. - * - * {@hide} - */ -public class Duration implements Parcelable { - public int timeInterval; - public TimeUnit timeUnit; - - public enum TimeUnit { - MINUTE(0x00), - SECOND(0x01), - TENTH_SECOND(0x02); - - private int mValue; - - TimeUnit(int value) { - mValue = value; - } - - public int value() { - return mValue; - } - } - - /** - * @param timeInterval Between 1 and 255 inclusive. - */ - public Duration(int timeInterval, TimeUnit timeUnit) { - this.timeInterval = timeInterval; - this.timeUnit = timeUnit; - } - - private Duration(Parcel in) { - timeInterval = in.readInt(); - timeUnit = TimeUnit.values()[in.readInt()]; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(timeInterval); - dest.writeInt(timeUnit.ordinal()); - } - - public int describeContents() { - return 0; - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public Duration createFromParcel(Parcel in) { - return new Duration(in); - } - - public Duration[] newArray(int size) { - return new Duration[size]; - } - }; -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/FontSize.java b/telephony/java/com/android/internal/telephony/gsm/stk/FontSize.java deleted file mode 100644 index bd4f49f..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/FontSize.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2006 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.gsm.stk; - - -/** - * Enumeration for representing text font size. - * - * {@hide} - */ -public enum FontSize { - NORMAL(0x0), - LARGE(0x1), - SMALL(0x2); - - private int mValue; - - FontSize(int value) { - mValue = value; - } - - /** - * Create a FontSize object. - * @param value Integer value to be converted to a FontSize object. - * @return FontSize object whose value is {@code value}. If no - * FontSize object has that value, null is returned. - */ - public static FontSize fromInt(int value) { - for (FontSize e : FontSize.values()) { - if (e.mValue == value) { - return e; - } - } - return null; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/IconLoader.java b/telephony/java/com/android/internal/telephony/gsm/stk/IconLoader.java deleted file mode 100644 index 500b8f6..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/IconLoader.java +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Copyright (C) 2006 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.gsm.stk; - -import com.android.internal.telephony.IccFileHandler; - -import android.graphics.Bitmap; -import android.graphics.Color; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.Looper; -import android.os.Message; -import android.util.Log; - -import java.util.HashMap; - -/** - * Class for loading icons from the SIM card. Has two states: single, for loading - * one icon. Multi, for loading icons list. - * - */ -class IconLoader extends Handler { - // members - private int mState = STATE_SINGLE_ICON; - private ImageDescriptor mId = null; - private Bitmap mCurrentIcon = null; - private int mRecordNumber; - private IccFileHandler mSimFH = null; - private Message mEndMsg = null; - private byte[] mIconData = null; - // multi icons state members - private int[] mRecordNumbers = null; - private int mCurrentRecordIndex = 0; - private Bitmap[] mIcons = null; - private HashMap mIconsCache = null; - - private static IconLoader sLoader = null; - - // Loader state values. - private static final int STATE_SINGLE_ICON = 1; - private static final int STATE_MULTI_ICONS = 2; - - // Finished loading single record from a linear-fixed EF-IMG. - private static final int EVENT_READ_EF_IMG_RECOED_DONE = 1; - // Finished loading single icon from a Transparent DF-Graphics. - private static final int EVENT_READ_ICON_DONE = 2; - // Finished loading single colour icon lookup table. - private static final int EVENT_READ_CLUT_DONE = 3; - - // Color lookup table offset inside the EF. - private static final int CLUT_LOCATION_OFFSET = 4; - // CLUT entry size, {Red, Green, Black} - private static final int CLUT_ENTRY_SIZE = 3; - - - private IconLoader(Looper looper , IccFileHandler fh) { - super(looper); - mSimFH = fh; - - mIconsCache = new HashMap(50); - } - - static IconLoader getInstance(Handler caller, IccFileHandler fh) { - if (sLoader != null) { - return sLoader; - } - if (fh != null) { - HandlerThread thread = new HandlerThread("Stk Icon Loader"); - thread.start(); - return new IconLoader(thread.getLooper(), fh); - } - return null; - } - - void loadIcons(int[] recordNumbers, Message msg) { - if (recordNumbers == null || recordNumbers.length == 0 || msg == null) { - return; - } - mEndMsg = msg; - // initialize multi icons load variables. - mIcons = new Bitmap[recordNumbers.length]; - mRecordNumbers = recordNumbers; - mCurrentRecordIndex = 0; - mState = STATE_MULTI_ICONS; - startLoadingIcon(recordNumbers[0]); - } - - void loadIcon(int recordNumber, Message msg) { - if (msg == null) { - return; - } - mEndMsg = msg; - mState = STATE_SINGLE_ICON; - startLoadingIcon(recordNumber); - } - - private void startLoadingIcon(int recordNumber) { - // Reset the load variables. - mId = null; - mIconData = null; - mCurrentIcon = null; - mRecordNumber = recordNumber; - - // make sure the icon was not already loaded and saved in the local cache. - if (mIconsCache.containsKey(recordNumber)) { - mCurrentIcon = mIconsCache.get(recordNumber); - postIcon(); - return; - } - - // start the first phase ==> loading Image Descriptor. - readId(); - } - - @Override - public void handleMessage(Message msg) { - AsyncResult ar; - - try { - switch (msg.what) { - case EVENT_READ_EF_IMG_RECOED_DONE: - ar = (AsyncResult) msg.obj; - if (handleImageDescriptor((byte[]) ar.result)) { - readIconData(); - } else { - throw new Exception("Unable to parse image descriptor"); - } - break; - case EVENT_READ_ICON_DONE: - ar = (AsyncResult) msg.obj; - byte[] rawData = ((byte[]) ar.result); - if (mId.codingScheme == ImageDescriptor.CODING_SCHEME_BASIC) { - mCurrentIcon = parseToBnW(rawData, rawData.length); - mIconsCache.put(mRecordNumber, mCurrentIcon); - postIcon(); - } else if (mId.codingScheme == ImageDescriptor.CODING_SCHEME_COLOUR) { - mIconData = rawData; - readClut(); - } - break; - case EVENT_READ_CLUT_DONE: - ar = (AsyncResult) msg.obj; - byte [] clut = ((byte[]) ar.result); - mCurrentIcon = parseToRGB(mIconData, mIconData.length, - false, clut); - mIconsCache.put(mRecordNumber, mCurrentIcon); - postIcon(); - break; - } - } catch (Exception e) { - StkLog.d(this, "Icon load failed"); - // post null icon back to the caller. - postIcon(); - } - } - - /** - * Handles Image descriptor parsing and required processing. This is the - * first step required to handle retrieving icons from the SIM. - * - * @param data byte [] containing Image Instance descriptor as defined in - * TS 51.011. - */ - private boolean handleImageDescriptor(byte[] rawData) { - mId = ImageDescriptor.parse(rawData, 1); - if (mId == null) { - return false; - } - return true; - } - - // Start reading colour lookup table from SIM card. - private void readClut() { - int length = mIconData[3] * CLUT_ENTRY_SIZE; - Message msg = this.obtainMessage(EVENT_READ_CLUT_DONE); - mSimFH.loadEFImgTransparent(mId.imageId, - mIconData[CLUT_LOCATION_OFFSET], - mIconData[CLUT_LOCATION_OFFSET + 1], length, msg); - } - - // Start reading Image Descriptor from SIM card. - private void readId() { - if (mRecordNumber < 0) { - mCurrentIcon = null; - postIcon(); - return; - } - Message msg = this.obtainMessage(EVENT_READ_EF_IMG_RECOED_DONE); - mSimFH.loadEFImgLinearFixed(mRecordNumber, msg); - } - - // Start reading icon bytes array from SIM card. - private void readIconData() { - Message msg = this.obtainMessage(EVENT_READ_ICON_DONE); - mSimFH.loadEFImgTransparent(mId.imageId, 0, 0, mId.length ,msg); - } - - // When all is done pass icon back to caller. - private void postIcon() { - if (mState == STATE_SINGLE_ICON) { - mEndMsg.obj = mCurrentIcon; - mEndMsg.sendToTarget(); - } else if (mState == STATE_MULTI_ICONS) { - mIcons[mCurrentRecordIndex++] = mCurrentIcon; - // If not all icons were loaded, start loading the next one. - if (mCurrentRecordIndex < mRecordNumbers.length) { - startLoadingIcon(mRecordNumbers[mCurrentRecordIndex]); - } else { - mEndMsg.obj = mIcons; - mEndMsg.sendToTarget(); - } - } - } - - /** - * Convert a TS 131.102 image instance of code scheme '11' into Bitmap - * @param data The raw data - * @param length The length of image body - * @return The bitmap - */ - public static Bitmap parseToBnW(byte[] data, int length){ - int valueIndex = 0; - int width = data[valueIndex++] & 0xFF; - int height = data[valueIndex++] & 0xFF; - int numOfPixels = width*height; - - int[] pixels = new int[numOfPixels]; - - int pixelIndex = 0; - int bitIndex = 7; - byte currentByte = 0x00; - while (pixelIndex < numOfPixels) { - // reassign data and index for every byte (8 bits). - if (pixelIndex % 8 == 0) { - currentByte = data[valueIndex++]; - bitIndex = 7; - } - pixels[pixelIndex++] = bitToBnW((currentByte >> bitIndex-- ) & 0x01); - } - - if (pixelIndex != numOfPixels) { - StkLog.d("IconLoader", "parseToBnW; size error"); - } - return Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888); - } - - /** - * Decode one bit to a black and white color: - * 0 is black - * 1 is white - * @param bit to decode - * @return RGB color - */ - private static int bitToBnW(int bit){ - if(bit == 1){ - return Color.WHITE; - } else { - return Color.BLACK; - } - } - - /** - * a TS 131.102 image instance of code scheme '11' into color Bitmap - * - * @param data The raw data - * @param length the length of image body - * @param transparency with or without transparency - * @param clut coulor lookup table - * @return The color bitmap - */ - public static Bitmap parseToRGB(byte[] data, int length, - boolean transparency, byte[] clut) { - int valueIndex = 0; - int width = data[valueIndex++] & 0xFF; - int height = data[valueIndex++] & 0xFF; - int bitsPerImg = data[valueIndex++] & 0xFF; - int numOfClutEntries = data[valueIndex++] & 0xFF; - - if (true == transparency) { - clut[numOfClutEntries - 1] = Color.TRANSPARENT; - } - - int numOfPixels = width * height; - int[] pixels = new int[numOfPixels]; - - valueIndex = 6; - int pixelIndex = 0; - int bitsStartOffset = 8 - bitsPerImg; - int bitIndex = bitsStartOffset; - byte currentByte = data[valueIndex++]; - int mask = getMask(bitsPerImg); - boolean bitsOverlaps = (8 % bitsPerImg == 0); - while (pixelIndex < numOfPixels) { - // reassign data and index for every byte (8 bits). - if (bitIndex < 0) { - currentByte = data[valueIndex++]; - bitIndex = bitsOverlaps ? (bitsStartOffset) : (bitIndex * -1); - } - int clutEntry = ((currentByte >> bitIndex) & mask); - int clutIndex = clutEntry * CLUT_ENTRY_SIZE; - pixels[pixelIndex++] = Color.rgb(clut[clutIndex], - clut[clutIndex + 1], clut[clutIndex + 2]); - bitIndex -= bitsPerImg; - } - - return Bitmap.createBitmap(pixels, width, height, - Bitmap.Config.ARGB_8888); - } - - /** - * Calculate bit mask for a given number of bits. The mask should enable to - * make a bitwise and to the given number of bits. - * @param numOfBits number of bits to calculate mask for. - * @return bit mask - */ - private static int getMask(int numOfBits) { - int mask = 0x00; - - switch (numOfBits) { - case 1: - mask = 0x01; - break; - case 2: - mask = 0x03; - break; - case 3: - mask = 0x07; - break; - case 4: - mask = 0x0F; - break; - case 5: - mask = 0x1F; - break; - case 6: - mask = 0x3F; - break; - case 7: - mask = 0x7F; - break; - case 8: - mask = 0xFF; - break; - } - return mask; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ImageDescriptor.java b/telephony/java/com/android/internal/telephony/gsm/stk/ImageDescriptor.java deleted file mode 100644 index 880b9e5..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/ImageDescriptor.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2006 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.gsm.stk; - -/** - * {@hide} - */ -public class ImageDescriptor { - // members - int width; - int height; - int codingScheme; - int imageId; - int highOffset; - int lowOffset; - int length; - - // constants - static final int CODING_SCHEME_BASIC = 0x11; - static final int CODING_SCHEME_COLOUR = 0x21; - - // public static final int ID_LENGTH = 9; - // ID_LENGTH substituted by IccFileHandlerBase.GET_RESPONSE_EF_IMG_SIZE_BYTES - - ImageDescriptor() { - width = 0; - height = 0; - codingScheme = 0; - imageId = 0; - highOffset = 0; - lowOffset = 0; - length = 0; - } - - /** - * Extract descriptor information about image instance. - * - * @param rawData - * @param valueIndex - * @return ImageDescriptor - */ - static ImageDescriptor parse(byte[] rawData, int valueIndex) { - ImageDescriptor d = new ImageDescriptor(); - try { - d.width = rawData[valueIndex++] & 0xff; - d.height = rawData[valueIndex++] & 0xff; - d.codingScheme = rawData[valueIndex++] & 0xff; - - // parse image id - d.imageId = (rawData[valueIndex++] & 0xff) << 8; - d.imageId |= rawData[valueIndex++] & 0xff; - // parse offset - d.highOffset = (rawData[valueIndex++] & 0xff); // high byte offset - d.lowOffset = rawData[valueIndex++] & 0xff; // low byte offset - - d.length = ((rawData[valueIndex++] & 0xff) << 8 | (rawData[valueIndex++] & 0xff)); - } catch (IndexOutOfBoundsException e) { - StkLog.d("ImageDescripter", "parse; failed parsing image descriptor"); - d = null; - } - return d; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Input.java b/telephony/java/com/android/internal/telephony/gsm/stk/Input.java deleted file mode 100644 index 19f724b..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/Input.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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.gsm.stk; - -import android.graphics.Bitmap; -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Container class for STK GET INPUT, GET IN KEY commands parameters. - * - */ -public class Input implements Parcelable { - public String text; - public String defaultText; - public Bitmap icon; - public int minLen; - public int maxLen; - public boolean ucs2; - public boolean packed; - public boolean digitOnly; - public boolean echo; - public boolean yesNo; - public boolean helpAvailable; - - Input() { - text = ""; - defaultText = null; - icon = null; - minLen = 0; - maxLen = 1; - ucs2 = false; - packed = false; - digitOnly = false; - echo = false; - yesNo = false; - helpAvailable = false; - } - - private Input(Parcel in) { - text = in.readString(); - defaultText = in.readString(); - icon = in.readParcelable(null); - minLen = in.readInt(); - maxLen = in.readInt(); - ucs2 = in.readInt() == 1 ? true : false; - packed = in.readInt() == 1 ? true : false; - digitOnly = in.readInt() == 1 ? true : false; - echo = in.readInt() == 1 ? true : false; - yesNo = in.readInt() == 1 ? true : false; - helpAvailable = in.readInt() == 1 ? true : false; - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(text); - dest.writeString(defaultText); - dest.writeParcelable(icon, 0); - dest.writeInt(minLen); - dest.writeInt(maxLen); - dest.writeInt(ucs2 ? 1 : 0); - dest.writeInt(packed ? 1 : 0); - dest.writeInt(digitOnly ? 1 : 0); - dest.writeInt(echo ? 1 : 0); - dest.writeInt(yesNo ? 1 : 0); - dest.writeInt(helpAvailable ? 1 : 0); - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public Input createFromParcel(Parcel in) { - return new Input(in); - } - - public Input[] newArray(int size) { - return new Input[size]; - } - }; - - boolean setIcon(Bitmap Icon) { return true; } -} \ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Item.java b/telephony/java/com/android/internal/telephony/gsm/stk/Item.java deleted file mode 100644 index b2f338c..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/Item.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2006 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.gsm.stk; - -import android.graphics.Bitmap; -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Represents an Item COMPREHENSION-TLV object. - * - * {@hide} - */ -public class Item implements Parcelable { - /** Identifier of the item. */ - public int id; - /** Text string of the item. */ - public String text; - /** Icon of the item */ - public Bitmap icon; - - public Item(int id, String text) { - this.id = id; - this.text = text; - this.icon = null; - } - - public Item(Parcel in) { - id = in.readInt(); - text = in.readString(); - icon = in.readParcelable(null); - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(id); - dest.writeString(text); - dest.writeParcelable(icon, flags); - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public Item createFromParcel(Parcel in) { - return new Item(in); - } - - public Item[] newArray(int size) { - return new Item[size]; - } - }; - - public String toString() { - return text; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/LaunchBrowserMode.java b/telephony/java/com/android/internal/telephony/gsm/stk/LaunchBrowserMode.java deleted file mode 100644 index 302273c..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/LaunchBrowserMode.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2006 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.gsm.stk; - - -/** - * Browser launch mode for LAUNCH BROWSER proactive command. - * - * {@hide} - */ -public enum LaunchBrowserMode { - /** Launch browser if not already launched. */ - LAUNCH_IF_NOT_ALREADY_LAUNCHED, - /** - * Use the existing browser (the browser shall not use the active existing - * secured session). - */ - USE_EXISTING_BROWSER, - /** Close the existing browser session and launch new browser session. */ - LAUNCH_NEW_BROWSER; -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Menu.java b/telephony/java/com/android/internal/telephony/gsm/stk/Menu.java deleted file mode 100644 index 331f69d..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/Menu.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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.gsm.stk; - -import android.graphics.Bitmap; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.ArrayList; -import java.util.List; - -/** - * Container class for STK menu (SET UP MENU, SELECT ITEM) parameters. - * - */ -public class Menu implements Parcelable { - public List items; - public List titleAttrs; - public PresentationType presentationType; - public String title; - public Bitmap titleIcon; - public int defaultItem; - public boolean softKeyPreferred; - public boolean helpAvailable; - public boolean titleIconSelfExplanatory; - public boolean itemsIconSelfExplanatory; - - public Menu() { - // Create an empty list. - items = new ArrayList(); - title = null; - titleAttrs = null; - defaultItem = 0; - softKeyPreferred = false; - helpAvailable = false; - titleIconSelfExplanatory = false; - itemsIconSelfExplanatory = false; - titleIcon = null; - // set default style to be navigation menu. - presentationType = PresentationType.NAVIGATION_OPTIONS; - } - - private Menu(Parcel in) { - title = in.readString(); - titleIcon = in.readParcelable(null); - // rebuild items list. - items = new ArrayList(); - int size = in.readInt(); - for (int i=0; i CREATOR = new Parcelable.Creator() { - public Menu createFromParcel(Parcel in) { - return new Menu(in); - } - - public Menu[] newArray(int size) { - return new Menu[size]; - } - }; -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/PresentationType.java b/telephony/java/com/android/internal/telephony/gsm/stk/PresentationType.java deleted file mode 100644 index 71bdcdc..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/PresentationType.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2006 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.gsm.stk; - - -/** - * Presentation types for SELECT TYPE proactive command. - * - * {@hide} - */ -public enum PresentationType { - /** Presentation type is not specified */ - NOT_SPECIFIED, - /** Presentation as a choice of data values */ - DATA_VALUES, - /** Presentation as a choice of navigation options */ - NAVIGATION_OPTIONS; -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java b/telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java deleted file mode 100644 index afd1bba..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2006-2007 Google Inc. - * - * 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.gsm.stk; - -import com.android.internal.telephony.EncodeException; -import com.android.internal.telephony.GsmAlphabet; - -import java.io.ByteArrayOutputStream; -import java.io.UnsupportedEncodingException; - -abstract class ResponseData { - /** - * Format the data appropriate for TERMINAL RESPONSE and write it into - * the ByteArrayOutputStream object. - */ - public abstract void format(ByteArrayOutputStream buf); -} - -class SelectItemResponseData extends ResponseData { - // members - private int id; - - public SelectItemResponseData(int id) { - super(); - this.id = id; - } - - @Override - public void format(ByteArrayOutputStream buf) { - // Item identifier object - int tag = 0x80 | ComprehensionTlvTag.ITEM_ID.value(); - buf.write(tag); // tag - buf.write(1); // length - buf.write(id); // identifier of item chosen - } -} - -class GetInkeyInputResponseData extends ResponseData { - // members - private boolean mIsUcs2; - private boolean mIsPacked; - private boolean mIsYesNo; - private boolean mYesNoResponse; - public String mInData; - - // GetInKey Yes/No response characters constants. - protected static final byte GET_INKEY_YES = 0x01; - protected static final byte GET_INKEY_NO = 0x00; - - public GetInkeyInputResponseData(String inData, boolean ucs2, boolean packed) { - super(); - this.mIsUcs2 = ucs2; - this.mIsPacked = packed; - this.mInData = inData; - this.mIsYesNo = false; - } - - public GetInkeyInputResponseData(boolean yesNoResponse) { - super(); - this.mIsUcs2 = false; - this.mIsPacked = false; - this.mInData = ""; - this.mIsYesNo = true; - this.mYesNoResponse = yesNoResponse; - } - - @Override - public void format(ByteArrayOutputStream buf) { - if (buf == null) { - return; - } - - // Text string object - int tag = 0x80 | ComprehensionTlvTag.TEXT_STRING.value(); - buf.write(tag); // tag - - byte[] data; - - if (mIsYesNo) { - data = new byte[1]; - data[0] = mYesNoResponse ? GET_INKEY_YES : GET_INKEY_NO; - } else if (mInData != null && mInData.length() > 0) { - try { - if (mIsUcs2) { - data = mInData.getBytes("UTF-16"); - } else if (mIsPacked) { - int size = mInData.length(); - - byte[] tempData = GsmAlphabet - .stringToGsm7BitPacked(mInData); - data = new byte[size]; - // Since stringToGsm7BitPacked() set byte 0 in the - // returned byte array to the count of septets used... - // copy to a new array without byte 0. - System.arraycopy(tempData, 1, data, 0, size); - } else { - data = GsmAlphabet.stringToGsm8BitPacked(mInData); - } - } catch (UnsupportedEncodingException e) { - data = new byte[0]; - } catch (EncodeException e) { - data = new byte[0]; - } - } else { - data = new byte[0]; - } - - // length - one more for data coding scheme. - buf.write(data.length + 1); - - // data coding scheme - if (mIsUcs2) { - buf.write(0x08); // UCS2 - } else if (mIsPacked) { - buf.write(0x00); // 7 bit packed - } else { - buf.write(0x04); // 8 bit unpacked - } - - for (byte b : data) { - buf.write(b); - } - } -} - - diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ResultCode.java b/telephony/java/com/android/internal/telephony/gsm/stk/ResultCode.java deleted file mode 100644 index b96a524..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/ResultCode.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) 2006 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.gsm.stk; - - -/** - * Enumeration for the return code in TERMINAL RESPONSE. - * To get the actual return code for each enum value, call {@link #code() code} - * method. - * - * {@hide} - */ -public enum ResultCode { - - /* - * Results '0X' and '1X' indicate that the command has been performed. - */ - - /** Command performed successfully */ - OK(0x00), - - /** Command performed with partial comprehension */ - PRFRMD_WITH_PARTIAL_COMPREHENSION(0x01), - - /** Command performed, with missing information */ - PRFRMD_WITH_MISSING_INFO(0x02), - - /** REFRESH performed with additional EFs read */ - PRFRMD_WITH_ADDITIONAL_EFS_READ(0x03), - - /** - * Command performed successfully, but requested icon could not be - * displayed - */ - PRFRMD_ICON_NOT_DISPLAYED(0x04), - - /** Command performed, but modified by call control by NAA */ - PRFRMD_MODIFIED_BY_NAA(0x05), - - /** Command performed successfully, limited service */ - PRFRMD_LIMITED_SERVICE(0x06), - - /** Command performed with modification */ - PRFRMD_WITH_MODIFICATION(0x07), - - /** REFRESH performed but indicated NAA was not active */ - PRFRMD_NAA_NOT_ACTIVE(0x08), - - /** Command performed successfully, tone not played */ - PRFRMD_TONE_NOT_PLAYED(0x09), - - /** Proactive UICC session terminated by the user */ - UICC_SESSION_TERM_BY_USER(0x10), - - /** Backward move in the proactive UICC session requested by the user */ - BACKWARD_MOVE_BY_USER(0x11), - - /** No response from user */ - NO_RESPONSE_FROM_USER(0x12), - - /** Help information required by the user */ - HELP_INFO_REQUIRED(0x13), - - /** USSD or SS transaction terminated by the user */ - USSD_SS_SESSION_TERM_BY_USER(0x14), - - - /* - * Results '2X' indicate to the UICC that it may be worth re-trying the - * command at a later opportunity. - */ - - /** Terminal currently unable to process command */ - TERMINAL_CRNTLY_UNABLE_TO_PROCESS(0x20), - - /** Network currently unable to process command */ - NETWORK_CRNTLY_UNABLE_TO_PROCESS(0x21), - - /** User did not accept the proactive command */ - USER_NOT_ACCEPT(0x22), - - /** User cleared down call before connection or network release */ - USER_CLEAR_DOWN_CALL(0x23), - - /** Action in contradiction with the current timer state */ - CONTRADICTION_WITH_TIMER(0x24), - - /** Interaction with call control by NAA, temporary problem */ - NAA_CALL_CONTROL_TEMPORARY(0x25), - - /** Launch browser generic error code */ - LAUNCH_BROWSER_ERROR(0x26), - - /** MMS temporary problem. */ - MMS_TEMPORARY(0x27), - - - /* - * Results '3X' indicate that it is not worth the UICC re-trying with an - * identical command, as it will only get the same response. However, the - * decision to retry lies with the application. - */ - - /** Command beyond terminal's capabilities */ - BEYOND_TERMINAL_CAPABILITY(0x30), - - /** Command type not understood by terminal */ - CMD_TYPE_NOT_UNDERSTOOD(0x31), - - /** Command data not understood by terminal */ - CMD_DATA_NOT_UNDERSTOOD(0x32), - - /** Command number not known by terminal */ - CMD_NUM_NOT_KNOWN(0x33), - - /** SS Return Error */ - SS_RETURN_ERROR(0x34), - - /** SMS RP-ERROR */ - SMS_RP_ERROR(0x35), - - /** Error, required values are missing */ - REQUIRED_VALUES_MISSING(0x36), - - /** USSD Return Error */ - USSD_RETURN_ERROR(0x37), - - /** MultipleCard commands error */ - MULTI_CARDS_CMD_ERROR(0x38), - - /** - * Interaction with call control by USIM or MO short message control by - * USIM, permanent problem - */ - USIM_CALL_CONTROL_PERMANENT(0x39), - - /** Bearer Independent Protocol error */ - BIP_ERROR(0x3a), - - /** Access Technology unable to process command */ - ACCESS_TECH_UNABLE_TO_PROCESS(0x3b), - - /** Frames error */ - FRAMES_ERROR(0x3c), - - /** MMS Error */ - MMS_ERROR(0x3d); - - - private int mCode; - - ResultCode(int code) { - mCode = code; - } - - /** - * Retrieves the actual result code that this object represents. - * @return Actual result code - */ - public int value() { - return mCode; - } - - public static ResultCode fromInt(int value) { - for (ResultCode r : ResultCode.values()) { - if (r.mCode == value) { - return r; - } - } - return null; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ResultException.java b/telephony/java/com/android/internal/telephony/gsm/stk/ResultException.java deleted file mode 100644 index 2eb16c9..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/ResultException.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2006 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.gsm.stk; - - -/** - * Class for errors in the Result object. - * - * {@hide} - */ -public class ResultException extends StkException { - private ResultCode mResult; - private int mAdditionalInfo; - - public ResultException(ResultCode result) { - super(); - - // ETSI TS 102 223, 8.12 -- For the general results '20', '21', '26', - // '38', '39', '3A', '3C', and '3D', it is mandatory for the terminal - // to provide a specific cause value as additional information. - switch (result) { - case TERMINAL_CRNTLY_UNABLE_TO_PROCESS: // 0x20 - case NETWORK_CRNTLY_UNABLE_TO_PROCESS: // 0x21 - case LAUNCH_BROWSER_ERROR: // 0x26 - case MULTI_CARDS_CMD_ERROR: // 0x38 - case USIM_CALL_CONTROL_PERMANENT: // 0x39 - case BIP_ERROR: // 0x3a - case FRAMES_ERROR: // 0x3c - case MMS_ERROR: // 0x3d - throw new AssertionError( - "For result code, " + result + - ", additional information must be given!"); - } - - mResult = result; - mAdditionalInfo = -1; - } - - public ResultException(ResultCode result, int additionalInfo) { - super(); - - if (additionalInfo < 0) { - throw new AssertionError( - "Additional info must be greater than zero!"); - } - - mResult = result; - mAdditionalInfo = additionalInfo; - } - - public ResultCode result() { - return mResult; - } - - public boolean hasAdditionalInfo() { - return mAdditionalInfo >= 0; - } - - public int additionalInfo() { - return mAdditionalInfo; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/RilMessageDecoder.java b/telephony/java/com/android/internal/telephony/gsm/stk/RilMessageDecoder.java deleted file mode 100644 index 02852cc..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/RilMessageDecoder.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * 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.gsm.stk; - -import com.android.internal.telephony.IccFileHandler; -import com.android.internal.telephony.IccUtils; - -import android.os.Handler; -import com.android.internal.util.HierarchicalState; -import com.android.internal.util.HierarchicalStateMachine; -import android.os.Message; - -/** - * Class used for queuing raw ril messages, decoding them into CommanParams - * objects and sending the result back to the STK Service. - */ -class RilMessageDecoder extends HierarchicalStateMachine { - - // constants - private static final int CMD_START = 1; - private static final int CMD_PARAMS_READY = 2; - - // members - private static RilMessageDecoder sInstance = null; - private CommandParamsFactory mCmdParamsFactory = null; - private RilMessage mCurrentRilMessage = null; - private Handler mCaller = null; - - // States - private StateStart mStateStart = new StateStart(); - private StateCmdParamsReady mStateCmdParamsReady = new StateCmdParamsReady(); - - /** - * Get the singleton instance, constructing if necessary. - * - * @param caller - * @param fh - * @return RilMesssageDecoder - */ - public static synchronized RilMessageDecoder getInstance(Handler caller, IccFileHandler fh) { - if (sInstance == null) { - sInstance = new RilMessageDecoder(caller, fh); - sInstance.start(); - } - return sInstance; - } - - /** - * Start decoding the message parameters, - * when complete MSG_ID_RIL_MSG_DECODED will be returned to caller. - * - * @param rilMsg - */ - public void sendStartDecodingMessageParams(RilMessage rilMsg) { - Message msg = obtainMessage(CMD_START); - msg.obj = rilMsg; - sendMessage(msg); - } - - /** - * The command parameters have been decoded. - * - * @param resCode - * @param cmdParams - */ - public void sendMsgParamsDecoded(ResultCode resCode, CommandParams cmdParams) { - Message msg = obtainMessage(RilMessageDecoder.CMD_PARAMS_READY); - msg.arg1 = resCode.value(); - msg.obj = cmdParams; - sendMessage(msg); - } - - private void sendCmdForExecution(RilMessage rilMsg) { - Message msg = mCaller.obtainMessage(StkService.MSG_ID_RIL_MSG_DECODED, - new RilMessage(rilMsg)); - msg.sendToTarget(); - } - - private RilMessageDecoder(Handler caller, IccFileHandler fh) { - super("RilMessageDecoder"); - - addState(mStateStart); - addState(mStateCmdParamsReady); - setInitialState(mStateStart); - - mCaller = caller; - mCmdParamsFactory = CommandParamsFactory.getInstance(this, fh); - } - - private class StateStart extends HierarchicalState { - @Override protected boolean processMessage(Message msg) { - if (msg.what == CMD_START) { - if (decodeMessageParams((RilMessage)msg.obj)) { - transitionTo(mStateCmdParamsReady); - } - } else { - StkLog.d(this, "StateStart unexpected expecting START=" + - CMD_START + " got " + msg.what); - } - return true; - } - } - - private class StateCmdParamsReady extends HierarchicalState { - @Override protected boolean processMessage(Message msg) { - if (msg.what == CMD_PARAMS_READY) { - mCurrentRilMessage.mResCode = ResultCode.fromInt(msg.arg1); - mCurrentRilMessage.mData = msg.obj; - sendCmdForExecution(mCurrentRilMessage); - transitionTo(mStateStart); - } else { - StkLog.d(this, "StateCmdParamsReady expecting CMD_PARAMS_READY=" - + CMD_PARAMS_READY + " got " + msg.what); - deferMessage(msg); - } - return true; - } - } - - private boolean decodeMessageParams(RilMessage rilMsg) { - boolean decodingStarted; - - mCurrentRilMessage = rilMsg; - switch(rilMsg.mId) { - case StkService.MSG_ID_SESSION_END: - case StkService.MSG_ID_CALL_SETUP: - mCurrentRilMessage.mResCode = ResultCode.OK; - sendCmdForExecution(mCurrentRilMessage); - decodingStarted = false; - break; - case StkService.MSG_ID_PROACTIVE_COMMAND: - case StkService.MSG_ID_EVENT_NOTIFY: - case StkService.MSG_ID_REFRESH: - byte[] rawData = null; - try { - rawData = IccUtils.hexStringToBytes((String) rilMsg.mData); - } catch (Exception e) { - // zombie messages are dropped - StkLog.d(this, "decodeMessageParams dropping zombie messages"); - decodingStarted = false; - break; - } - try { - // Start asynch parsing of the command parameters. - mCmdParamsFactory.make(BerTlv.decode(rawData)); - decodingStarted = true; - } catch (ResultException e) { - // send to Service for proper RIL communication. - mCurrentRilMessage.mResCode = e.result(); - sendCmdForExecution(mCurrentRilMessage); - decodingStarted = false; - } - break; - default: - decodingStarted = false; - break; - } - return decodingStarted; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java b/telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java deleted file mode 100644 index 5425a43..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * 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.gsm.stk; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Class used to pass STK messages from telephony to application. Application - * should call getXXX() to get commands's specific values. - * - */ -public class StkCmdMessage implements Parcelable { - // members - CommandDetails mCmdDet; - private TextMessage mTextMsg; - private Menu mMenu; - private Input mInput; - private BrowserSettings mBrowserSettings = null; - private ToneSettings mToneSettings = null; - private CallSettings mCallSettings = null; - - /* - * Container for Launch Browser command settings. - */ - public class BrowserSettings { - public String url; - public LaunchBrowserMode mode; - } - - /* - * Container for Call Setup command settings. - */ - public class CallSettings { - public TextMessage confirmMsg; - public TextMessage callMsg; - } - - StkCmdMessage(CommandParams cmdParams) { - mCmdDet = cmdParams.cmdDet; - switch(getCmdType()) { - case SET_UP_MENU: - case SELECT_ITEM: - mMenu = ((SelectItemParams) cmdParams).menu; - break; - case DISPLAY_TEXT: - case SET_UP_IDLE_MODE_TEXT: - case SEND_DTMF: - case SEND_SMS: - case SEND_SS: - case SEND_USSD: - mTextMsg = ((DisplayTextParams) cmdParams).textMsg; - break; - case GET_INPUT: - case GET_INKEY: - mInput = ((GetInputParams) cmdParams).input; - break; - case LAUNCH_BROWSER: - mTextMsg = ((LaunchBrowserParams) cmdParams).confirmMsg; - mBrowserSettings = new BrowserSettings(); - mBrowserSettings.url = ((LaunchBrowserParams) cmdParams).url; - mBrowserSettings.mode = ((LaunchBrowserParams) cmdParams).mode; - break; - case PLAY_TONE: - PlayToneParams params = (PlayToneParams) cmdParams; - mToneSettings = params.settings; - mTextMsg = params.textMsg; - break; - case SET_UP_CALL: - mCallSettings = new CallSettings(); - mCallSettings.confirmMsg = ((CallSetupParams) cmdParams).confirmMsg; - mCallSettings.callMsg = ((CallSetupParams) cmdParams).callMsg; - break; - } - } - - public StkCmdMessage(Parcel in) { - mCmdDet = in.readParcelable(null); - mTextMsg = in.readParcelable(null); - mMenu = in.readParcelable(null); - mInput = in.readParcelable(null); - switch (getCmdType()) { - case LAUNCH_BROWSER: - mBrowserSettings = new BrowserSettings(); - mBrowserSettings.url = in.readString(); - mBrowserSettings.mode = LaunchBrowserMode.values()[in.readInt()]; - break; - case PLAY_TONE: - mToneSettings = in.readParcelable(null); - break; - case SET_UP_CALL: - mCallSettings = new CallSettings(); - mCallSettings.confirmMsg = in.readParcelable(null); - mCallSettings.callMsg = in.readParcelable(null); - break; - } - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeParcelable(mCmdDet, 0); - dest.writeParcelable(mTextMsg, 0); - dest.writeParcelable(mMenu, 0); - dest.writeParcelable(mInput, 0); - switch(getCmdType()) { - case LAUNCH_BROWSER: - dest.writeString(mBrowserSettings.url); - dest.writeInt(mBrowserSettings.mode.ordinal()); - break; - case PLAY_TONE: - dest.writeParcelable(mToneSettings, 0); - break; - case SET_UP_CALL: - dest.writeParcelable(mCallSettings.confirmMsg, 0); - dest.writeParcelable(mCallSettings.callMsg, 0); - break; - } - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public StkCmdMessage createFromParcel(Parcel in) { - return new StkCmdMessage(in); - } - - public StkCmdMessage[] newArray(int size) { - return new StkCmdMessage[size]; - } - }; - - public int describeContents() { - return 0; - } - - /* external API to be used by application */ - public AppInterface.CommandType getCmdType() { - return AppInterface.CommandType.fromInt(mCmdDet.typeOfCommand); - } - - public Menu getMenu() { - return mMenu; - } - - public Input geInput() { - return mInput; - } - - public TextMessage geTextMessage() { - return mTextMsg; - } - - public BrowserSettings getBrowserSettings() { - return mBrowserSettings; - } - - public ToneSettings getToneSettings() { - return mToneSettings; - } - - public CallSettings getCallSettings() { - return mCallSettings; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkException.java b/telephony/java/com/android/internal/telephony/gsm/stk/StkException.java deleted file mode 100644 index 86de366..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/StkException.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2006 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.gsm.stk; - -import android.util.AndroidException; - - -/** - * Base class for all the exceptions in STK service. - * - * {@hide} - */ -class StkException extends AndroidException { - public StkException() { - super(); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java b/telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java deleted file mode 100644 index bd6bc8f..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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.gsm.stk; - -import android.util.Log; - -public abstract class StkLog { - static final boolean DEBUG = true; - - public static void d(Object caller, String msg) { - if (!DEBUG) { - return; - } - - String className = caller.getClass().getName(); - Log.d("STK", className.substring(className.lastIndexOf('.') + 1) + ": " - + msg); - } - - public static void d(String caller, String msg) { - if (!DEBUG) { - return; - } - - Log.d("STK", caller + ": " + msg); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkResponseMessage.java b/telephony/java/com/android/internal/telephony/gsm/stk/StkResponseMessage.java deleted file mode 100644 index 04a52e6..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/StkResponseMessage.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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.gsm.stk; - -public class StkResponseMessage { - CommandDetails cmdDet = null; - ResultCode resCode = ResultCode.OK; - int usersMenuSelection = 0; - String usersInput = null; - boolean usersYesNoSelection = false; - boolean usersConfirm = false; - - public StkResponseMessage(StkCmdMessage cmdMsg) { - this.cmdDet = cmdMsg.mCmdDet; - } - - public void setResultCode(ResultCode resCode) { - this.resCode = resCode; - } - - public void setMenuSelection(int selection) { - this.usersMenuSelection = selection; - } - - public void setInput(String input) { - this.usersInput = input; - } - - public void setYesNo(boolean yesNo) { - usersYesNoSelection = yesNo; - } - - public void setConfirmation(boolean confirm) { - usersConfirm = confirm; - } - - CommandDetails getCmdDetails() { - return cmdDet; - } - } \ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java b/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java deleted file mode 100644 index 5efa7a6..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java +++ /dev/null @@ -1,635 +0,0 @@ -/* - * 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.gsm.stk; - -import android.content.Context; -import android.content.Intent; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.Message; - -import com.android.internal.telephony.IccUtils; -import com.android.internal.telephony.CommandsInterface; -import com.android.internal.telephony.IccCard; -import com.android.internal.telephony.IccFileHandler; -import com.android.internal.telephony.IccRecords; - -import android.util.Config; - -import java.io.ByteArrayOutputStream; - -/** - * Enumeration for representing the tag value of COMPREHENSION-TLV objects. If - * you want to get the actual value, call {@link #value() value} method. - * - * {@hide} - */ -enum ComprehensionTlvTag { - COMMAND_DETAILS(0x01), - DEVICE_IDENTITIES(0x02), - RESULT(0x03), - DURATION(0x04), - ALPHA_ID(0x05), - USSD_STRING(0x0a), - TEXT_STRING(0x0d), - TONE(0x0e), - ITEM(0x0f), - ITEM_ID(0x10), - RESPONSE_LENGTH(0x11), - FILE_LIST(0x12), - HELP_REQUEST(0x15), - DEFAULT_TEXT(0x17), - EVENT_LIST(0x19), - ICON_ID(0x1e), - ITEM_ICON_ID_LIST(0x1f), - IMMEDIATE_RESPONSE(0x2b), - LANGUAGE(0x2d), - URL(0x31), - BROWSER_TERMINATION_CAUSE(0x34), - TEXT_ATTRIBUTE(0x50); - - private int mValue; - - ComprehensionTlvTag(int value) { - mValue = value; - } - - /** - * Returns the actual value of this COMPREHENSION-TLV object. - * - * @return Actual tag value of this object - */ - public int value() { - return mValue; - } - - public static ComprehensionTlvTag fromInt(int value) { - for (ComprehensionTlvTag e : ComprehensionTlvTag.values()) { - if (e.mValue == value) { - return e; - } - } - return null; - } -} - -class RilMessage { - int mId; - Object mData; - ResultCode mResCode; - - RilMessage(int msgId, String rawData) { - mId = msgId; - mData = rawData; - } - - RilMessage(RilMessage other) { - this.mId = other.mId; - this.mData = other.mData; - this.mResCode = other.mResCode; - } -} - -/** - * Class that implements SIM Toolkit Telephony Service. Interacts with the RIL - * and application. - * - * {@hide} - */ -public class StkService extends Handler implements AppInterface { - - // Class members - private static IccRecords mIccRecords; - - // Service members. - private static StkService sInstance; - private CommandsInterface mCmdIf; - private Context mContext; - private StkCmdMessage mCurrntCmd = null; - private StkCmdMessage mMenuCmd = null; - - private RilMessageDecoder mMsgDecoder = null; - - // Service constants. - static final int MSG_ID_SESSION_END = 1; - static final int MSG_ID_PROACTIVE_COMMAND = 2; - static final int MSG_ID_EVENT_NOTIFY = 3; - static final int MSG_ID_CALL_SETUP = 4; - static final int MSG_ID_REFRESH = 5; - static final int MSG_ID_RESPONSE = 6; - - static final int MSG_ID_RIL_MSG_DECODED = 10; - - // Events to signal SIM presence or absent in the device. - private static final int MSG_ID_ICC_RECORDS_LOADED = 20; - - private static final int DEV_ID_KEYPAD = 0x01; - private static final int DEV_ID_DISPLAY = 0x02; - private static final int DEV_ID_EARPIECE = 0x03; - private static final int DEV_ID_UICC = 0x81; - private static final int DEV_ID_TERMINAL = 0x82; - private static final int DEV_ID_NETWORK = 0x83; - - /* Intentionally private for singleton */ - private StkService(CommandsInterface ci, IccRecords ir, Context context, - IccFileHandler fh, IccCard ic) { - if (ci == null || ir == null || context == null || fh == null - || ic == null) { - throw new NullPointerException( - "Service: Input parameters must not be null"); - } - mCmdIf = ci; - mContext = context; - - // Get the RilMessagesDecoder for decoding the messages. - mMsgDecoder = RilMessageDecoder.getInstance(this, fh); - - // Register ril events handling. - mCmdIf.setOnStkSessionEnd(this, MSG_ID_SESSION_END, null); - mCmdIf.setOnStkProactiveCmd(this, MSG_ID_PROACTIVE_COMMAND, null); - mCmdIf.setOnStkEvent(this, MSG_ID_EVENT_NOTIFY, null); - mCmdIf.setOnStkCallSetUp(this, MSG_ID_CALL_SETUP, null); - //mCmdIf.setOnSimRefresh(this, MSG_ID_REFRESH, null); - - mIccRecords = ir; - - // Register for SIM ready event. - mIccRecords.registerForRecordsLoaded(this, MSG_ID_ICC_RECORDS_LOADED, null); - - mCmdIf.reportStkServiceIsRunning(null); - StkLog.d(this, "StkService: is running"); - } - - public void dispose() { - mIccRecords.unregisterForRecordsLoaded(this); - mCmdIf.unSetOnStkSessionEnd(this); - mCmdIf.unSetOnStkProactiveCmd(this); - mCmdIf.unSetOnStkEvent(this); - mCmdIf.unSetOnStkCallSetUp(this); - - this.removeCallbacksAndMessages(null); - } - - protected void finalize() { - StkLog.d(this, "Service finalized"); - } - - private void handleRilMsg(RilMessage rilMsg) { - if (rilMsg == null) { - return; - } - - // dispatch messages - CommandParams cmdParams = null; - switch (rilMsg.mId) { - case MSG_ID_EVENT_NOTIFY: - if (rilMsg.mResCode == ResultCode.OK) { - cmdParams = (CommandParams) rilMsg.mData; - if (cmdParams != null) { - handleProactiveCommand(cmdParams); - } - } - break; - case MSG_ID_PROACTIVE_COMMAND: - cmdParams = (CommandParams) rilMsg.mData; - if (cmdParams != null) { - if (rilMsg.mResCode == ResultCode.OK) { - handleProactiveCommand(cmdParams); - } else { - // for proactive commands that couldn't be decoded - // successfully respond with the code generated by the - // message decoder. - sendTerminalResponse(cmdParams.cmdDet, rilMsg.mResCode, - false, 0, null); - } - } - break; - case MSG_ID_REFRESH: - cmdParams = (CommandParams) rilMsg.mData; - if (cmdParams != null) { - handleProactiveCommand(cmdParams); - } - break; - case MSG_ID_SESSION_END: - handleSessionEnd(); - break; - case MSG_ID_CALL_SETUP: - // prior event notify command supplied all the information - // needed for set up call processing. - break; - } - } - - /** - * Handles RIL_UNSOL_STK_PROACTIVE_COMMAND unsolicited command from RIL. - * Sends valid proactive command data to the application using intents. - * - */ - private void handleProactiveCommand(CommandParams cmdParams) { - StkLog.d(this, cmdParams.getCommandType().name()); - - StkCmdMessage cmdMsg = new StkCmdMessage(cmdParams); - switch (cmdParams.getCommandType()) { - case SET_UP_MENU: - if (removeMenu(cmdMsg.getMenu())) { - mMenuCmd = null; - } else { - mMenuCmd = cmdMsg; - } - sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, - null); - break; - case DISPLAY_TEXT: - // when application is not required to respond, send an immediate - // response. - if (!cmdMsg.geTextMessage().responseNeeded) { - sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, - 0, null); - } - break; - case REFRESH: - // ME side only handles refresh commands which meant to remove IDLE - // MODE TEXT. - cmdParams.cmdDet.typeOfCommand = CommandType.SET_UP_IDLE_MODE_TEXT - .value(); - break; - case SET_UP_IDLE_MODE_TEXT: - sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, - 0, null); - break; - case LAUNCH_BROWSER: - case SELECT_ITEM: - case GET_INPUT: - case GET_INKEY: - case SEND_DTMF: - case SEND_SMS: - case SEND_SS: - case SEND_USSD: - case PLAY_TONE: - case SET_UP_CALL: - // nothing to do on telephony! - break; - default: - StkLog.d(this, "Unsupported command"); - return; - } - mCurrntCmd = cmdMsg; - Intent intent = new Intent(AppInterface.STK_CMD_ACTION); - intent.putExtra("STK CMD", cmdMsg); - mContext.sendBroadcast(intent); - } - - /** - * Handles RIL_UNSOL_STK_SESSION_END unsolicited command from RIL. - * - */ - private void handleSessionEnd() { - StkLog.d(this, "SESSION END"); - - mCurrntCmd = mMenuCmd; - Intent intent = new Intent(AppInterface.STK_SESSION_END_ACTION); - mContext.sendBroadcast(intent); - } - - private void sendTerminalResponse(CommandDetails cmdDet, - ResultCode resultCode, boolean includeAdditionalInfo, - int additionalInfo, ResponseData resp) { - - if (cmdDet == null) { - return; - } - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - - // command details - int tag = ComprehensionTlvTag.COMMAND_DETAILS.value(); - if (cmdDet.compRequired) { - tag |= 0x80; - } - buf.write(tag); - buf.write(0x03); // length - buf.write(cmdDet.commandNumber); - buf.write(cmdDet.typeOfCommand); - buf.write(cmdDet.commandQualifier); - - // device identities - tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value(); - buf.write(tag); - buf.write(0x02); // length - buf.write(DEV_ID_TERMINAL); // source device id - buf.write(DEV_ID_UICC); // destination device id - - // result - tag = 0x80 | ComprehensionTlvTag.RESULT.value(); - buf.write(tag); - int length = includeAdditionalInfo ? 2 : 1; - buf.write(length); - buf.write(resultCode.value()); - - // additional info - if (includeAdditionalInfo) { - buf.write(additionalInfo); - } - - // Fill optional data for each corresponding command - if (resp != null) { - resp.format(buf); - } - - byte[] rawData = buf.toByteArray(); - String hexString = IccUtils.bytesToHexString(rawData); - if (Config.LOGD) { - StkLog.d(this, "TERMINAL RESPONSE: " + hexString); - } - - mCmdIf.sendTerminalResponse(hexString, null); - } - - - private void sendMenuSelection(int menuId, boolean helpRequired) { - - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - - // tag - int tag = BerTlv.BER_MENU_SELECTION_TAG; - buf.write(tag); - - // length - buf.write(0x00); // place holder - - // device identities - tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value(); - buf.write(tag); - buf.write(0x02); // length - buf.write(DEV_ID_KEYPAD); // source device id - buf.write(DEV_ID_UICC); // destination device id - - // item identifier - tag = 0x80 | ComprehensionTlvTag.ITEM_ID.value(); - buf.write(tag); - buf.write(0x01); // length - buf.write(menuId); // menu identifier chosen - - // help request - if (helpRequired) { - tag = ComprehensionTlvTag.HELP_REQUEST.value(); - buf.write(tag); - buf.write(0x00); // length - } - - byte[] rawData = buf.toByteArray(); - - // write real length - int len = rawData.length - 2; // minus (tag + length) - rawData[1] = (byte) len; - - String hexString = IccUtils.bytesToHexString(rawData); - - mCmdIf.sendEnvelope(hexString, null); - } - - private void eventDownload(int event, int sourceId, int destinationId, - byte[] additionalInfo, boolean oneShot) { - - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - - // tag - int tag = BerTlv.BER_EVENT_DOWNLOAD_TAG; - buf.write(tag); - - // length - buf.write(0x00); // place holder, assume length < 128. - - // event list - tag = 0x80 | ComprehensionTlvTag.EVENT_LIST.value(); - buf.write(tag); - buf.write(0x01); // length - buf.write(event); // event value - - // device identities - tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value(); - buf.write(tag); - buf.write(0x02); // length - buf.write(sourceId); // source device id - buf.write(destinationId); // destination device id - - // additional information - if (additionalInfo != null) { - for (byte b : additionalInfo) { - buf.write(b); - } - } - - byte[] rawData = buf.toByteArray(); - - // write real length - int len = rawData.length - 2; // minus (tag + length) - rawData[1] = (byte) len; - - String hexString = IccUtils.bytesToHexString(rawData); - - mCmdIf.sendEnvelope(hexString, null); - } - - /** - * Used for instantiating/updating the Service from the GsmPhone or CdmaPhone constructor. - * - * @param ci CommandsInterface object - * @param ir IccRecords object - * @param context phone app context - * @param fh Icc file handler - * @param ic Icc card - * @return The only Service object in the system - */ - public static StkService getInstance(CommandsInterface ci, IccRecords ir, - Context context, IccFileHandler fh, IccCard ic) { - if (sInstance == null) { - if (ci == null || ir == null || context == null || fh == null - || ic == null) { - return null; - } - HandlerThread thread = new HandlerThread("Stk Telephony service"); - thread.start(); - sInstance = new StkService(ci, ir, context, fh, ic); - StkLog.d(sInstance, "NEW sInstance"); - } else if ((ir != null) && (mIccRecords != ir)) { - StkLog.d(sInstance, "Reinitialize the Service with SIMRecords"); - mIccRecords = ir; - - // re-Register for SIM ready event. - mIccRecords.registerForRecordsLoaded(sInstance, MSG_ID_ICC_RECORDS_LOADED, null); - StkLog.d(sInstance, "sr changed reinitialize and return current sInstance"); - } else { - StkLog.d(sInstance, "Return current sInstance"); - } - return sInstance; - } - - /** - * Used by application to get an AppInterface object. - * - * @return The only Service object in the system - */ - public static AppInterface getInstance() { - return getInstance(null, null, null, null, null); - } - - @Override - public void handleMessage(Message msg) { - - switch (msg.what) { - case MSG_ID_SESSION_END: - case MSG_ID_PROACTIVE_COMMAND: - case MSG_ID_EVENT_NOTIFY: - case MSG_ID_REFRESH: - StkLog.d(this, "ril message arrived"); - String data = null; - if (msg.obj != null) { - AsyncResult ar = (AsyncResult) msg.obj; - if (ar != null && ar.result != null) { - try { - data = (String) ar.result; - } catch (ClassCastException e) { - break; - } - } - } - mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, data)); - break; - case MSG_ID_CALL_SETUP: - mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, null)); - break; - case MSG_ID_ICC_RECORDS_LOADED: - break; - case MSG_ID_RIL_MSG_DECODED: - handleRilMsg((RilMessage) msg.obj); - break; - case MSG_ID_RESPONSE: - handleCmdResponse((StkResponseMessage) msg.obj); - break; - default: - throw new AssertionError("Unrecognized STK command: " + msg.what); - } - } - - public synchronized void onCmdResponse(StkResponseMessage resMsg) { - if (resMsg == null) { - return; - } - // queue a response message. - Message msg = this.obtainMessage(MSG_ID_RESPONSE, resMsg); - msg.sendToTarget(); - } - - private boolean validateResponse(StkResponseMessage resMsg) { - if (mCurrntCmd != null) { - return (resMsg.cmdDet.compareTo(mCurrntCmd.mCmdDet)); - } - return false; - } - - private boolean removeMenu(Menu menu) { - try { - if (menu.items.size() == 1 && menu.items.get(0) == null) { - return true; - } - } catch (NullPointerException e) { - StkLog.d(this, "Unable to get Menu's items size"); - return true; - } - return false; - } - - private void handleCmdResponse(StkResponseMessage resMsg) { - // Make sure the response details match the last valid command. An invalid - // response is a one that doesn't have a corresponding proactive command - // and sending it can "confuse" the baseband/ril. - // One reason for out of order responses can be UI glitches. For example, - // if the application launch an activity, and that activity is stored - // by the framework inside the history stack. That activity will be - // available for relaunch using the latest application dialog - // (long press on the home button). Relaunching that activity can send - // the same command's result again to the StkService and can cause it to - // get out of sync with the SIM. - if (!validateResponse(resMsg)) { - return; - } - ResponseData resp = null; - boolean helpRequired = false; - CommandDetails cmdDet = resMsg.getCmdDetails(); - - switch (resMsg.resCode) { - case HELP_INFO_REQUIRED: - helpRequired = true; - // fall through - case OK: - case PRFRMD_WITH_PARTIAL_COMPREHENSION: - case PRFRMD_WITH_MISSING_INFO: - case PRFRMD_WITH_ADDITIONAL_EFS_READ: - case PRFRMD_ICON_NOT_DISPLAYED: - case PRFRMD_MODIFIED_BY_NAA: - case PRFRMD_LIMITED_SERVICE: - case PRFRMD_WITH_MODIFICATION: - case PRFRMD_NAA_NOT_ACTIVE: - case PRFRMD_TONE_NOT_PLAYED: - switch (AppInterface.CommandType.fromInt(cmdDet.typeOfCommand)) { - case SET_UP_MENU: - helpRequired = resMsg.resCode == ResultCode.HELP_INFO_REQUIRED; - sendMenuSelection(resMsg.usersMenuSelection, helpRequired); - return; - case SELECT_ITEM: - resp = new SelectItemResponseData(resMsg.usersMenuSelection); - break; - case GET_INPUT: - case GET_INKEY: - Input input = mCurrntCmd.geInput(); - if (!input.yesNo) { - // when help is requested there is no need to send the text - // string object. - if (!helpRequired) { - resp = new GetInkeyInputResponseData(resMsg.usersInput, - input.ucs2, input.packed); - } - } else { - resp = new GetInkeyInputResponseData( - resMsg.usersYesNoSelection); - } - break; - case DISPLAY_TEXT: - case LAUNCH_BROWSER: - break; - case SET_UP_CALL: - mCmdIf.handleCallSetupRequestFromSim(resMsg.usersConfirm, null); - // No need to send terminal response for SET UP CALL. The user's - // confirmation result is send back using a dedicated ril message - // invoked by the CommandInterface call above. - mCurrntCmd = null; - return; - } - break; - case NO_RESPONSE_FROM_USER: - case UICC_SESSION_TERM_BY_USER: - case BACKWARD_MOVE_BY_USER: - resp = null; - break; - default: - return; - } - sendTerminalResponse(cmdDet, resMsg.resCode, false, 0, resp); - mCurrntCmd = null; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/TextAlignment.java b/telephony/java/com/android/internal/telephony/gsm/stk/TextAlignment.java deleted file mode 100644 index c5dd50e..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/TextAlignment.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2006 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.gsm.stk; - - -/** - * Enumeration for representing text alignment. - * - * {@hide} - */ -public enum TextAlignment { - LEFT(0x0), - CENTER(0x1), - RIGHT(0x2), - /** Language dependent (default) */ - DEFAULT(0x3); - - private int mValue; - - TextAlignment(int value) { - mValue = value; - } - - /** - * Create a TextAlignment object. - * @param value Integer value to be converted to a TextAlignment object. - * @return TextAlignment object whose value is {@code value}. If no - * TextAlignment object has that value, null is returned. - */ - public static TextAlignment fromInt(int value) { - for (TextAlignment e : TextAlignment.values()) { - if (e.mValue == value) { - return e; - } - } - return null; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/TextAttribute.java b/telephony/java/com/android/internal/telephony/gsm/stk/TextAttribute.java deleted file mode 100644 index ace4300..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/TextAttribute.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2006 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.gsm.stk; - - -/** - * Class for representing text attributes for SIM Toolkit. - * - * {@hide} - */ -public class TextAttribute { - public int start; - public int length; - public TextAlignment align; - public FontSize size; - public boolean bold; - public boolean italic; - public boolean underlined; - public boolean strikeThrough; - public TextColor color; - - public TextAttribute(int start, int length, TextAlignment align, - FontSize size, boolean bold, boolean italic, boolean underlined, - boolean strikeThrough, TextColor color) { - this.start = start; - this.length = length; - this.align = align; - this.size = size; - this.bold = bold; - this.italic = italic; - this.underlined = underlined; - this.strikeThrough = strikeThrough; - this.color = color; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/TextColor.java b/telephony/java/com/android/internal/telephony/gsm/stk/TextColor.java deleted file mode 100644 index 126fc62..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/TextColor.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2006 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.gsm.stk; - - -/** - * Enumeration for representing text color. - * - * {@hide} - */ -public enum TextColor { - BLACK(0x0), - DARK_GRAY(0x1), - DARK_RED(0x2), - DARK_YELLOW(0x3), - DARK_GREEN(0x4), - DARK_CYAN(0x5), - DARK_BLUE(0x6), - DARK_MAGENTA(0x7), - GRAY(0x8), - WHITE(0x9), - BRIGHT_RED(0xa), - BRIGHT_YELLOW(0xb), - BRIGHT_GREEN(0xc), - BRIGHT_CYAN(0xd), - BRIGHT_BLUE(0xe), - BRIGHT_MAGENTA(0xf); - - private int mValue; - - TextColor(int value) { - mValue = value; - } - - /** - * Create a TextColor object. - * @param value Integer value to be converted to a TextColor object. - * @return TextColor object whose value is {@code value}. If no TextColor - * object has that value, null is returned. - */ - public static TextColor fromInt(int value) { - for (TextColor e : TextColor.values()) { - if (e.mValue == value) { - return e; - } - } - return null; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/TextMessage.java b/telephony/java/com/android/internal/telephony/gsm/stk/TextMessage.java deleted file mode 100644 index 3b6a09a..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/TextMessage.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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.gsm.stk; - -import android.graphics.Bitmap; -import android.os.Parcel; -import android.os.Parcelable; - -public class TextMessage implements Parcelable { - public String title = ""; - public String text = null; - public Bitmap icon = null; - public boolean iconSelfExplanatory = false; - public boolean isHighPriority = false; - public boolean responseNeeded = true; - public boolean userClear = false; - public Duration duration = null; - - TextMessage() { - } - - private TextMessage(Parcel in) { - title = in.readString(); - text = in.readString(); - icon = in.readParcelable(null); - iconSelfExplanatory = in.readInt() == 1 ? true : false; - isHighPriority = in.readInt() == 1 ? true : false; - responseNeeded = in.readInt() == 1 ? true : false; - userClear = in.readInt() == 1 ? true : false; - duration = in.readParcelable(null); - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(title); - dest.writeString(text); - dest.writeParcelable(icon, 0); - dest.writeInt(iconSelfExplanatory ? 1 : 0); - dest.writeInt(isHighPriority ? 1 : 0); - dest.writeInt(responseNeeded ? 1 : 0); - dest.writeInt(userClear ? 1 : 0); - dest.writeParcelable(duration, 0); - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public TextMessage createFromParcel(Parcel in) { - return new TextMessage(in); - } - - public TextMessage[] newArray(int size) { - return new TextMessage[size]; - } - }; -} \ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Tone.java b/telephony/java/com/android/internal/telephony/gsm/stk/Tone.java deleted file mode 100644 index b64e777..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/Tone.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (C) 2006 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.gsm.stk; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Enumeration for representing the tone values for use with PLAY TONE - * proactive commands. - * - * {@hide} - */ -public enum Tone implements Parcelable { - // Standard supervisory tones - - /** - * Dial tone. - */ - DIAL(0x01), - - /** - * Called subscriber busy. - */ - BUSY(0x02), - - /** - * Congestion. - */ - CONGESTION(0x03), - - /** - * Radio path acknowledge. - */ - RADIO_PATH_ACK(0x04), - - /** - * Radio path not available / Call dropped. - */ - RADIO_PATH_NOT_AVAILABLE(0x05), - - /** - * Error/Special information. - */ - ERROR_SPECIAL_INFO(0x06), - - /** - * Call waiting tone. - */ - CALL_WAITING(0x07), - - /** - * Ringing tone. - */ - RINGING(0x08), - - // Terminal proprietary tones - - /** - * General beep. - */ - GENERAL_BEEP(0x10), - - /** - * Positive acknowledgement tone. - */ - POSITIVE_ACK(0x11), - - /** - * Negative acknowledgement tone. - */ - NEGATIVE_ACK(0x12), - - /** - * Ringing tone as selected by the user for incoming speech call. - */ - INCOMING_SPEECH_CALL(0x13), - - /** - * Alert tone as selected by the user for incoming SMS. - */ - INCOMING_SMS(0x14), - - /** - * Critical alert. - * This tone is to be used in critical situations. The terminal shall make - * every effort to alert the user when this tone is indicated independent - * from the volume setting in the terminal. - */ - CRITICAL_ALERT(0x15), - - /** - * Vibrate only, if available. - */ - VIBRATE_ONLY(0x20), - - // Themed tones - - /** - * Happy tone. - */ - HAPPY(0x30), - - /** - * Sad tone. - */ - SAD(0x31), - - /** - * Urgent action tone. - */ - URGENT(0x32), - - /** - * Question tone. - */ - QUESTION(0x33), - - /** - * Message received tone. - */ - MESSAGE_RECEIVED(0x34), - - // Melody tones - MELODY_1(0x40), - MELODY_2(0x41), - MELODY_3(0x42), - MELODY_4(0x43), - MELODY_5(0x44), - MELODY_6(0x45), - MELODY_7(0x46), - MELODY_8(0x47); - - private int mValue; - - Tone(int value) { - mValue = value; - } - - /** - * Create a Tone object. - * @param value Integer value to be converted to a Tone object. - * @return Tone object whose value is {@code value}. If no Tone object has - * that value, null is returned. - */ - public static Tone fromInt(int value) { - for (Tone e : Tone.values()) { - if (e.mValue == value) { - return e; - } - } - return null; - } - - Tone(Parcel in) { - mValue = in.readInt(); - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(ordinal()); - } - - public int describeContents() { - return 0; - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public Tone createFromParcel(Parcel in) { - return Tone.values()[in.readInt()]; - } - - public Tone[] newArray(int size) { - return new Tone[size]; - } - }; -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java b/telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java deleted file mode 100644 index 90cc6c1..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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.gsm.stk; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Container class for PlayTone commands parameters. - * - */ -public class ToneSettings implements Parcelable { - public Duration duration; - public Tone tone; - public boolean vibrate; - - public ToneSettings(Duration duration, Tone tone, boolean vibrate) { - this.duration = duration; - this.tone = tone; - this.vibrate = vibrate; - } - - private ToneSettings(Parcel in) { - duration = in.readParcelable(null); - tone = in.readParcelable(null); - vibrate = in.readInt() == 1; - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeParcelable(duration, 0); - dest.writeParcelable(tone, 0); - dest.writeInt(vibrate ? 1 : 0); - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public ToneSettings createFromParcel(Parcel in) { - return new ToneSettings(in); - } - - public ToneSettings[] newArray(int size) { - return new ToneSettings[size]; - } - }; -} \ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java b/telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java deleted file mode 100644 index 09a860e..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright (C) 2006-2007 Google Inc. - * - * 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.gsm.stk; - -import com.android.internal.telephony.GsmAlphabet; -import com.android.internal.telephony.IccUtils; -import com.android.internal.telephony.gsm.stk.Duration.TimeUnit; - -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.List; - -abstract class ValueParser { - - /** - * Search for a Command Details object from a list. - * - * @param ctlvs List of ComprehensionTlv objects used for search - * @return An CtlvCommandDetails object found from the objects. If no - * Command Details object is found, ResultException is thrown. - * @throws ResultException - */ - static CommandDetails retrieveCommandDetails(ComprehensionTlv ctlv) - throws ResultException { - - CommandDetails cmdDet = new CommandDetails(); - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - try { - cmdDet.compRequired = ctlv.isComprehensionRequired(); - cmdDet.commandNumber = rawValue[valueIndex] & 0xff; - cmdDet.typeOfCommand = rawValue[valueIndex + 1] & 0xff; - cmdDet.commandQualifier = rawValue[valueIndex + 2] & 0xff; - return cmdDet; - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } - - /** - * Search for a Device Identities object from a list. - * - * @param ctlvs List of ComprehensionTlv objects used for search - * @return An CtlvDeviceIdentities object found from the objects. If no - * Command Details object is found, ResultException is thrown. - * @throws ResultException - */ - static DeviceIdentities retrieveDeviceIdentities(ComprehensionTlv ctlv) - throws ResultException { - - DeviceIdentities devIds = new DeviceIdentities(); - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - try { - devIds.sourceId = rawValue[valueIndex] & 0xff; - devIds.destinationId = rawValue[valueIndex + 1] & 0xff; - return devIds; - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); - } - } - - /** - * Retrieves Duration information from the Duration COMPREHENSION-TLV - * object. - * - * @param ctlv A Text Attribute COMPREHENSION-TLV object - * @return A Duration object - * @throws ResultException - */ - static Duration retrieveDuration(ComprehensionTlv ctlv) throws ResultException { - int timeInterval = 0; - TimeUnit timeUnit = TimeUnit.SECOND; - - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - - try { - timeUnit = TimeUnit.values()[(rawValue[valueIndex] & 0xff)]; - timeInterval = rawValue[valueIndex + 1] & 0xff; - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - return new Duration(timeInterval, timeUnit); - } - - /** - * Retrieves Item information from the COMPREHENSION-TLV object. - * - * @param ctlv A Text Attribute COMPREHENSION-TLV object - * @return An Item - * @throws ResultException - */ - static Item retrieveItem(ComprehensionTlv ctlv) throws ResultException { - Item item = null; - - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - int length = ctlv.getLength(); - - if (length != 0) { - int textLen = length - 1; - - try { - int id = rawValue[valueIndex] & 0xff; - String text = IccUtils.adnStringFieldToString(rawValue, - valueIndex + 1, textLen); - item = new Item(id, text); - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } - - return item; - } - - /** - * Retrieves Item id information from the COMPREHENSION-TLV object. - * - * @param ctlv A Text Attribute COMPREHENSION-TLV object - * @return An Item id - * @throws ResultException - */ - static int retrieveItemId(ComprehensionTlv ctlv) throws ResultException { - int id = 0; - - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - - try { - id = rawValue[valueIndex] & 0xff; - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - - return id; - } - - /** - * Retrieves icon id from an Icon Identifier COMPREHENSION-TLV object - * - * @param ctlv An Icon Identifier COMPREHENSION-TLV object - * @return IconId instance - * @throws ResultException - */ - static IconId retrieveIconId(ComprehensionTlv ctlv) throws ResultException { - IconId id = new IconId(); - - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - try { - id.selfExplanatory = (rawValue[valueIndex++] & 0xff) == 0x00; - id.recordNumber = rawValue[valueIndex] & 0xff; - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - - return id; - } - - /** - * Retrieves item icons id from an Icon Identifier List COMPREHENSION-TLV - * object - * - * @param ctlv An Item Icon List Identifier COMPREHENSION-TLV object - * @return ItemsIconId instance - * @throws ResultException - */ - static ItemsIconId retrieveItemsIconId(ComprehensionTlv ctlv) - throws ResultException { - StkLog.d("ValueParser", "retrieveItemsIconId:"); - ItemsIconId id = new ItemsIconId(); - - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - int numOfItems = ctlv.getLength() - 1; - id.recordNumbers = new int[numOfItems]; - - try { - // get icon self-explanatory - id.selfExplanatory = (rawValue[valueIndex++] & 0xff) == 0x00; - - for (int index = 0; index < numOfItems;) { - id.recordNumbers[index++] = rawValue[valueIndex++]; - } - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - return id; - } - - /** - * Retrieves text attribute information from the Text Attribute - * COMPREHENSION-TLV object. - * - * @param ctlv A Text Attribute COMPREHENSION-TLV object - * @return A list of TextAttribute objects - * @throws ResultException - */ - static List retrieveTextAttribute(ComprehensionTlv ctlv) - throws ResultException { - ArrayList lst = new ArrayList(); - - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - int length = ctlv.getLength(); - - if (length != 0) { - // Each attribute is consisted of four bytes - int itemCount = length / 4; - - try { - for (int i = 0; i < itemCount; i++, valueIndex += 4) { - int start = rawValue[valueIndex] & 0xff; - int textLength = rawValue[valueIndex + 1] & 0xff; - int format = rawValue[valueIndex + 2] & 0xff; - int colorValue = rawValue[valueIndex + 3] & 0xff; - - int alignValue = format & 0x03; - TextAlignment align = TextAlignment.fromInt(alignValue); - - int sizeValue = (format >> 2) & 0x03; - FontSize size = FontSize.fromInt(sizeValue); - if (size == null) { - // Font size value is not defined. Use default. - size = FontSize.NORMAL; - } - - boolean bold = (format & 0x10) != 0; - boolean italic = (format & 0x20) != 0; - boolean underlined = (format & 0x40) != 0; - boolean strikeThrough = (format & 0x80) != 0; - - TextColor color = TextColor.fromInt(colorValue); - - TextAttribute attr = new TextAttribute(start, textLength, - align, size, bold, italic, underlined, - strikeThrough, color); - lst.add(attr); - } - - return lst; - - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } - return null; - } - - - /** - * Retrieves alpha identifier from an Alpha Identifier COMPREHENSION-TLV - * object. - * - * @param ctlv An Alpha Identifier COMPREHENSION-TLV object - * @return String corresponding to the alpha identifier - * @throws ResultException - */ - static String retrieveAlphaId(ComprehensionTlv ctlv) throws ResultException { - - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - int length = ctlv.getLength(); - if (length != 0) { - try { - return IccUtils.adnStringFieldToString(rawValue, valueIndex, - length); - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } - return null; - } - - /** - * Retrieves text from the Text COMPREHENSION-TLV object, and decodes it - * into a Java String. - * - * @param ctlv A Text COMPREHENSION-TLV object - * @return A Java String object decoded from the Text object - * @throws ResultException - */ - static String retrieveTextString(ComprehensionTlv ctlv) throws ResultException { - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - byte codingScheme = 0x00; - String text = null; - int textLen = ctlv.getLength(); - - // In case the text length is 0, return a null string. - if (textLen == 0) { - return text; - } else { - // one byte is coding scheme - textLen -= 1; - } - - try { - codingScheme = (byte) (rawValue[valueIndex] & 0x0c); - - if (codingScheme == 0x00) { // GSM 7-bit packed - text = GsmAlphabet.gsm7BitPackedToString(rawValue, - valueIndex + 1, (textLen * 8) / 7); - } else if (codingScheme == 0x04) { // GSM 8-bit unpacked - text = GsmAlphabet.gsm8BitUnpackedToString(rawValue, - valueIndex + 1, textLen); - } else if (codingScheme == 0x08) { // UCS2 - text = new String(rawValue, valueIndex + 1, textLen, "UTF-16"); - } else { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - - return text; - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } catch (UnsupportedEncodingException e) { - // This should never happen. - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/package.html b/telephony/java/com/android/internal/telephony/gsm/stk/package.html deleted file mode 100644 index c285b57..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/package.html +++ /dev/null @@ -1,5 +0,0 @@ - - -Provides classes for SIM Toolkit Service. - - -- cgit v1.1