10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/* 20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2007 The Android Open Source Project 30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License"); 50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License. 60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at 70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * http://www.apache.org/licenses/LICENSE-2.0 90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software 110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS, 120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and 140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License. 150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony.cat; 180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Context; 200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Intent; 210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.pm.PackageManager; 220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.pm.ResolveInfo; 230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.AsyncResult; 240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler; 250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.HandlerThread; 260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message; 270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.SystemProperties; 280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 290825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.IccUtils; 300825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CommandsInterface; 310825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.IccFileHandler; 320825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.IccRecords; 33e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.UiccCard; 34e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenkaimport com.android.internal.telephony.UiccCardApplication; 350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 370825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.ByteArrayOutputStream; 380825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.List; 390825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Locale; 400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 410825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleclass RilMessage { 420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int mId; 430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Object mData; 440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ResultCode mResCode; 450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville RilMessage(int msgId, String rawData) { 470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mId = msgId; 480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mData = rawData; 490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville RilMessage(RilMessage other) { 520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this.mId = other.mId; 530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this.mData = other.mData; 540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this.mResCode = other.mResCode; 550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/** 590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Class that implements SIM Toolkit Telephony Service. Interacts with the RIL 600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * and application. 610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide} 630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 640825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic class CatService extends Handler implements AppInterface { 650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Class members 670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static IccRecords mIccRecords; 68e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private static UiccCardApplication mUiccApplication; 690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Service members. 710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Protects singleton instance lazy initialization. 720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final Object sInstanceLock = new Object(); 730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static CatService sInstance; 740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private CommandsInterface mCmdIf; 750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private Context mContext; 760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private CatCmdMessage mCurrntCmd = null; 770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private CatCmdMessage mMenuCmd = null; 780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private RilMessageDecoder mMsgDecoder = null; 800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private boolean mStkAppInstalled = false; 810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Service constants. 830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static final int MSG_ID_SESSION_END = 1; 840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static final int MSG_ID_PROACTIVE_COMMAND = 2; 850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static final int MSG_ID_EVENT_NOTIFY = 3; 860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static final int MSG_ID_CALL_SETUP = 4; 870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static final int MSG_ID_REFRESH = 5; 880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static final int MSG_ID_RESPONSE = 6; 890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static final int MSG_ID_SIM_READY = 7; 900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static final int MSG_ID_RIL_MSG_DECODED = 10; 920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Events to signal SIM presence or absent in the device. 940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int MSG_ID_ICC_RECORDS_LOADED = 20; 950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int DEV_ID_KEYPAD = 0x01; 970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int DEV_ID_DISPLAY = 0x02; 980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int DEV_ID_EARPIECE = 0x03; 990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int DEV_ID_UICC = 0x81; 1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int DEV_ID_TERMINAL = 0x82; 1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int DEV_ID_NETWORK = 0x83; 1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static final String STK_DEFAULT = "Defualt Message"; 1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /* Intentionally private for singleton */ 106e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka private CatService(CommandsInterface ci, UiccCardApplication ca, IccRecords ir, 107e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka Context context, IccFileHandler fh, UiccCard ic) { 108e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (ci == null || ca == null || ir == null || context == null || fh == null 1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville || ic == null) { 1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville throw new NullPointerException( 1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "Service: Input parameters must not be null"); 1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCmdIf = ci; 1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mContext = context; 1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Get the RilMessagesDecoder for decoding the messages. 1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mMsgDecoder = RilMessageDecoder.getInstance(this, fh); 1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Register ril events handling. 1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCmdIf.setOnCatSessionEnd(this, MSG_ID_SESSION_END, null); 1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCmdIf.setOnCatProactiveCmd(this, MSG_ID_PROACTIVE_COMMAND, null); 1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCmdIf.setOnCatEvent(this, MSG_ID_EVENT_NOTIFY, null); 1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCmdIf.setOnCatCallSetUp(this, MSG_ID_CALL_SETUP, null); 1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //mCmdIf.setOnSimRefresh(this, MSG_ID_REFRESH, null); 1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mIccRecords = ir; 127e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mUiccApplication = ca; 1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Register for SIM ready event. 130e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mUiccApplication.registerForReady(this, MSG_ID_SIM_READY, null); 1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mIccRecords.registerForRecordsLoaded(this, MSG_ID_ICC_RECORDS_LOADED, null); 1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Check if STK application is availalbe 1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mStkAppInstalled = isStkAppInstalled(); 1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatLog.d(this, "Running CAT service. STK app installed:" + mStkAppInstalled); 1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void dispose() { 1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mIccRecords.unregisterForRecordsLoaded(this); 1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCmdIf.unSetOnCatSessionEnd(this); 1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCmdIf.unSetOnCatProactiveCmd(this); 1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCmdIf.unSetOnCatEvent(this); 1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCmdIf.unSetOnCatCallSetUp(this); 1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville this.removeCallbacksAndMessages(null); 1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected void finalize() { 1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatLog.d(this, "Service finalized"); 1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void handleRilMsg(RilMessage rilMsg) { 1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (rilMsg == null) { 1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // dispatch messages 1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CommandParams cmdParams = null; 1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (rilMsg.mId) { 1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case MSG_ID_EVENT_NOTIFY: 1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (rilMsg.mResCode == ResultCode.OK) { 1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cmdParams = (CommandParams) rilMsg.mData; 1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (cmdParams != null) { 1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville handleCommand(cmdParams, false); 1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case MSG_ID_PROACTIVE_COMMAND: 1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cmdParams = (CommandParams) rilMsg.mData; 1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (ClassCastException e) { 1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // for error handling : cast exception 1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatLog.d(this, "Fail to parse proactive command"); 1751e5f46c0477703b0eef40278cfa101d20b53091aJohn Wang // Don't send Terminal Resp if command detail is not available 1769fdeecb4aa06552efcc535f21718cae45cc604e2Wink Saville if (mCurrntCmd != null) { 1771e5f46c0477703b0eef40278cfa101d20b53091aJohn Wang sendTerminalResponse(mCurrntCmd.mCmdDet, ResultCode.CMD_DATA_NOT_UNDERSTOOD, 1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville false, 0x00, null); 1791e5f46c0477703b0eef40278cfa101d20b53091aJohn Wang } 1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (cmdParams != null) { 1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (rilMsg.mResCode == ResultCode.OK) { 1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville handleCommand(cmdParams, true); 1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // for proactive commands that couldn't be decoded 1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // successfully respond with the code generated by the 1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // message decoder. 1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sendTerminalResponse(cmdParams.cmdDet, rilMsg.mResCode, 1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville false, 0, null); 1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case MSG_ID_REFRESH: 1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cmdParams = (CommandParams) rilMsg.mData; 1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (cmdParams != null) { 1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville handleCommand(cmdParams, false); 1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case MSG_ID_SESSION_END: 2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville handleSessionEnd(); 2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case MSG_ID_CALL_SETUP: 2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // prior event notify command supplied all the information 2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // needed for set up call processing. 2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Handles RIL_UNSOL_STK_EVENT_NOTIFY or RIL_UNSOL_STK_PROACTIVE_COMMAND command 2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * from RIL. 2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Sends valid proactive command data to the application using intents. 2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE will be send back if the command is 2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * from RIL_UNSOL_STK_PROACTIVE_COMMAND. 2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void handleCommand(CommandParams cmdParams, boolean isProactiveCmd) { 2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatLog.d(this, cmdParams.getCommandType().name()); 2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CharSequence message; 2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatCmdMessage cmdMsg = new CatCmdMessage(cmdParams); 2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (cmdParams.getCommandType()) { 2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SET_UP_MENU: 2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (removeMenu(cmdMsg.getMenu())) { 2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mMenuCmd = null; 2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mMenuCmd = cmdMsg; 2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null); 2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case DISPLAY_TEXT: 2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // when application is not required to respond, send an immediate response. 2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (!cmdMsg.geTextMessage().responseNeeded) { 2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null); 2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case REFRESH: 2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // ME side only handles refresh commands which meant to remove IDLE 2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // MODE TEXT. 2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cmdParams.cmdDet.typeOfCommand = CommandType.SET_UP_IDLE_MODE_TEXT.value(); 2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SET_UP_IDLE_MODE_TEXT: 2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null); 2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case PROVIDE_LOCAL_INFORMATION: 2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ResponseData resp; 2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (cmdParams.cmdDet.commandQualifier) { 2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case CommandParamsFactory.DTTZ_SETTING: 2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville resp = new DTTZResponseData(null); 2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, resp); 2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case CommandParamsFactory.LANGUAGE_SETTING: 2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville resp = new LanguageResponseData(Locale.getDefault().getLanguage()); 2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, resp); 2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: 2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null); 2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // No need to start STK app here. 2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case LAUNCH_BROWSER: 2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((((LaunchBrowserParams) cmdParams).confirmMsg.text != null) 2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville && (((LaunchBrowserParams) cmdParams).confirmMsg.text.equals(STK_DEFAULT))) { 2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville message = mContext.getText(com.android.internal.R.string.launchBrowserDefault); 2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ((LaunchBrowserParams) cmdParams).confirmMsg.text = message.toString(); 2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SELECT_ITEM: 2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case GET_INPUT: 2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case GET_INKEY: 2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SEND_DTMF: 2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SEND_SMS: 2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SEND_SS: 2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SEND_USSD: 2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((((DisplayTextParams)cmdParams).textMsg.text != null) 2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville && (((DisplayTextParams)cmdParams).textMsg.text.equals(STK_DEFAULT))) { 2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville message = mContext.getText(com.android.internal.R.string.sending); 2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ((DisplayTextParams)cmdParams).textMsg.text = message.toString(); 2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case PLAY_TONE: 2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SET_UP_CALL: 2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((((CallSetupParams) cmdParams).confirmMsg.text != null) 2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville && (((CallSetupParams) cmdParams).confirmMsg.text.equals(STK_DEFAULT))) { 2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville message = mContext.getText(com.android.internal.R.string.SetupCallDefault); 2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ((CallSetupParams) cmdParams).confirmMsg.text = message.toString(); 2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case OPEN_CHANNEL: 2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case CLOSE_CHANNEL: 2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case RECEIVE_DATA: 2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SEND_DATA: 2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville BIPClientParams cmd = (BIPClientParams) cmdParams; 2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (cmd.bHasAlphaId && (cmd.textMsg.text == null)) { 2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatLog.d(this, "cmd " + cmdParams.getCommandType() + " with null alpha id"); 2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // If alpha length is zero, we just respond with OK. 2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (isProactiveCmd) { 3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null); 3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Respond with permanent failure to avoid retry if STK app is not present. 3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (!mStkAppInstalled) { 3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatLog.d(this, "No STK application found."); 3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (isProactiveCmd) { 3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sendTerminalResponse(cmdParams.cmdDet, 3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ResultCode.BEYOND_TERMINAL_CAPABILITY, 3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville false, 0, null); 3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /* 3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * CLOSE_CHANNEL, RECEIVE_DATA and SEND_DATA can be delivered by 3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * either PROACTIVE_COMMAND or EVENT_NOTIFY. 3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * If PROACTIVE_COMMAND is used for those commands, send terminal 3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * response here. 3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (isProactiveCmd && 3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ((cmdParams.getCommandType() == CommandType.CLOSE_CHANNEL) || 3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville (cmdParams.getCommandType() == CommandType.RECEIVE_DATA) || 3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville (cmdParams.getCommandType() == CommandType.SEND_DATA))) { 3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null); 3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: 3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatLog.d(this, "Unsupported command"); 3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCurrntCmd = cmdMsg; 3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Intent intent = new Intent(AppInterface.CAT_CMD_ACTION); 3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville intent.putExtra("STK CMD", cmdMsg); 3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mContext.sendBroadcast(intent); 3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Handles RIL_UNSOL_STK_SESSION_END unsolicited command from RIL. 3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void handleSessionEnd() { 3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatLog.d(this, "SESSION END"); 3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCurrntCmd = mMenuCmd; 3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Intent intent = new Intent(AppInterface.CAT_SESSION_END_ACTION); 3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mContext.sendBroadcast(intent); 3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void sendTerminalResponse(CommandDetails cmdDet, 3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ResultCode resultCode, boolean includeAdditionalInfo, 3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int additionalInfo, ResponseData resp) { 3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (cmdDet == null) { 3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ByteArrayOutputStream buf = new ByteArrayOutputStream(); 3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Input cmdInput = null; 3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mCurrntCmd != null) { 3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cmdInput = mCurrntCmd.geInput(); 3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // command details 3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int tag = ComprehensionTlvTag.COMMAND_DETAILS.value(); 3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (cmdDet.compRequired) { 3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville tag |= 0x80; 3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(tag); 3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(0x03); // length 3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(cmdDet.commandNumber); 3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(cmdDet.typeOfCommand); 3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(cmdDet.commandQualifier); 3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // device identities 3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // According to TS102.223/TS31.111 section 6.8 Structure of 3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // TERMINAL RESPONSE, "For all SIMPLE-TLV objects with Min=N, 3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // the ME should set the CR(comprehension required) flag to 3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // comprehension not required.(CR=0)" 3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Since DEVICE_IDENTITIES and DURATION TLVs have Min=N, 3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // the CR flag is not set. 3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville tag = ComprehensionTlvTag.DEVICE_IDENTITIES.value(); 3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(tag); 3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(0x02); // length 3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(DEV_ID_TERMINAL); // source device id 3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(DEV_ID_UICC); // destination device id 3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // result 3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville tag = 0x80 | ComprehensionTlvTag.RESULT.value(); 3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(tag); 3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int length = includeAdditionalInfo ? 2 : 1; 3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(length); 3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(resultCode.value()); 3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // additional info 3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (includeAdditionalInfo) { 3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(additionalInfo); 3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Fill optional data for each corresponding command 4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (resp != null) { 4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville resp.format(buf); 4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville encodeOptionalTags(cmdDet, resultCode, cmdInput, buf); 4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] rawData = buf.toByteArray(); 4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String hexString = IccUtils.bytesToHexString(rawData); 4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (false) { 4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatLog.d(this, "TERMINAL RESPONSE: " + hexString); 4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCmdIf.sendTerminalResponse(hexString, null); 4130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void encodeOptionalTags(CommandDetails cmdDet, 4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ResultCode resultCode, Input cmdInput, ByteArrayOutputStream buf) { 4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CommandType cmdType = AppInterface.CommandType.fromInt(cmdDet.typeOfCommand); 4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (cmdType != null) { 4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (cmdType) { 4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case GET_INKEY: 4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // ETSI TS 102 384,27.22.4.2.8.4.2. 4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // If it is a response for GET_INKEY command and the response timeout 4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // occured, then add DURATION TLV for variable timeout case. 4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((resultCode.value() == ResultCode.NO_RESPONSE_FROM_USER.value()) && 4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville (cmdInput != null) && (cmdInput.duration != null)) { 4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville getInKeyResponse(buf, cmdInput); 4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case PROVIDE_LOCAL_INFORMATION: 4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((cmdDet.commandQualifier == CommandParamsFactory.LANGUAGE_SETTING) && 4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville (resultCode.value() == ResultCode.OK.value())) { 4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville getPliResponse(buf); 4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: 4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatLog.d(this, "encodeOptionalTags() Unsupported Cmd details=" + cmdDet); 4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatLog.d(this, "encodeOptionalTags() bad Cmd details=" + cmdDet); 4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void getInKeyResponse(ByteArrayOutputStream buf, Input cmdInput) { 4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int tag = ComprehensionTlvTag.DURATION.value(); 4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(tag); 4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(0x02); // length 4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(cmdInput.duration.timeUnit.SECOND.value()); // Time (Unit,Seconds) 4500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(cmdInput.duration.timeInterval); // Time Duration 4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void getPliResponse(ByteArrayOutputStream buf) { 4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Locale Language Setting 4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String lang = SystemProperties.get("persist.sys.language"); 4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (lang != null) { 4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // tag 4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int tag = ComprehensionTlvTag.LANGUAGE.value(); 4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(tag); 4620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ResponseData.writeLength(buf, lang.length()); 4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(lang.getBytes(), 0, lang.length()); 4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void sendMenuSelection(int menuId, boolean helpRequired) { 4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ByteArrayOutputStream buf = new ByteArrayOutputStream(); 4700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // tag 4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int tag = BerTlv.BER_MENU_SELECTION_TAG; 4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(tag); 4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // length 4760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(0x00); // place holder 4770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // device identities 4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value(); 4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(tag); 4810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(0x02); // length 4820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(DEV_ID_KEYPAD); // source device id 4830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(DEV_ID_UICC); // destination device id 4840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // item identifier 4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville tag = 0x80 | ComprehensionTlvTag.ITEM_ID.value(); 4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(tag); 4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(0x01); // length 4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(menuId); // menu identifier chosen 4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // help request 4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (helpRequired) { 4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville tag = ComprehensionTlvTag.HELP_REQUEST.value(); 4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(tag); 4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(0x00); // length 4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] rawData = buf.toByteArray(); 4990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // write real length 5010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int len = rawData.length - 2; // minus (tag + length) 5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville rawData[1] = (byte) len; 5030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String hexString = IccUtils.bytesToHexString(rawData); 5050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCmdIf.sendEnvelope(hexString, null); 5070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void eventDownload(int event, int sourceId, int destinationId, 5100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] additionalInfo, boolean oneShot) { 5110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ByteArrayOutputStream buf = new ByteArrayOutputStream(); 5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // tag 5150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int tag = BerTlv.BER_EVENT_DOWNLOAD_TAG; 5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(tag); 5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // length 5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(0x00); // place holder, assume length < 128. 5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // event list 5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville tag = 0x80 | ComprehensionTlvTag.EVENT_LIST.value(); 5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(tag); 5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(0x01); // length 5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(event); // event value 5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // device identities 5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value(); 5290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(tag); 5300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(0x02); // length 5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(sourceId); // source device id 5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(destinationId); // destination device id 5330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // additional information 5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (additionalInfo != null) { 5360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (byte b : additionalInfo) { 5370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buf.write(b); 5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] rawData = buf.toByteArray(); 5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // write real length 5440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int len = rawData.length - 2; // minus (tag + length) 5450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville rawData[1] = (byte) len; 5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String hexString = IccUtils.bytesToHexString(rawData); 5480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCmdIf.sendEnvelope(hexString, null); 5500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 5530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Used for instantiating/updating the Service from the GsmPhone or CdmaPhone constructor. 5540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param ci CommandsInterface object 5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param ir IccRecords object 5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param context phone app context 5580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param fh Icc file handler 5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param ic Icc card 5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return The only Service object in the system 5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 562e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka public static CatService getInstance(CommandsInterface ci, 563e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka Context context, UiccCard ic) { 564e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka UiccCardApplication ca = null; 565e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka IccFileHandler fh = null; 566e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka IccRecords ir = null; 567e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (ic != null) { 568e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka /* Since Cat is not tied to any application, but rather is Uicc application 569e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka * in itself - just get first FileHandler and IccRecords object 570e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka */ 571e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka ca = ic.getApplicationIndex(0); 572e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (ca != null) { 573e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka fh = ca.getIccFileHandler(); 574e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka ir = ca.getIccRecords(); 575e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 576e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 5770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville synchronized (sInstanceLock) { 5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (sInstance == null) { 579e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (ci == null || ca == null || ir == null || context == null || fh == null 5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville || ic == null) { 5810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return null; 5820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville HandlerThread thread = new HandlerThread("Cat Telephony service"); 5840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville thread.start(); 585e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka sInstance = new CatService(ci, ca, ir, context, fh, ic); 5860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatLog.d(sInstance, "NEW sInstance"); 5870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if ((ir != null) && (mIccRecords != ir)) { 588e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mIccRecords != null) { 589e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mIccRecords.unregisterForRecordsLoaded(sInstance); 590e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 591e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 592e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (mUiccApplication != null) { 593e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mUiccApplication.unregisterForReady(sInstance); 594e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 595e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka CatLog.d(sInstance, 596e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka "Reinitialize the Service with SIMRecords and UiccCardApplication"); 5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mIccRecords = ir; 598e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mUiccApplication = ca; 5990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // re-Register for SIM ready event. 6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mIccRecords.registerForRecordsLoaded(sInstance, MSG_ID_ICC_RECORDS_LOADED, null); 602e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka mUiccApplication.registerForReady(sInstance, MSG_ID_SIM_READY, null); 6030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatLog.d(sInstance, "sr changed reinitialize and return current sInstance"); 6040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 6050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatLog.d(sInstance, "Return current sInstance"); 6060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return sInstance; 6080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 6120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Used by application to get an AppInterface object. 6130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 6140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return The only Service object in the system 6150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 6160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static AppInterface getInstance() { 617e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka return getInstance(null, null, null); 6180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 6210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void handleMessage(Message msg) { 6220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (msg.what) { 6240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case MSG_ID_SESSION_END: 6250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case MSG_ID_PROACTIVE_COMMAND: 6260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case MSG_ID_EVENT_NOTIFY: 6270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case MSG_ID_REFRESH: 6280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatLog.d(this, "ril message arrived"); 6290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String data = null; 6300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (msg.obj != null) { 6310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville AsyncResult ar = (AsyncResult) msg.obj; 6320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (ar != null && ar.result != null) { 6330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 6340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville data = (String) ar.result; 6350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (ClassCastException e) { 6360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 6370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, data)); 6410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case MSG_ID_CALL_SETUP: 6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, null)); 6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case MSG_ID_ICC_RECORDS_LOADED: 6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case MSG_ID_RIL_MSG_DECODED: 6480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville handleRilMsg((RilMessage) msg.obj); 6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 6500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case MSG_ID_RESPONSE: 6510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville handleCmdResponse((CatResponseMessage) msg.obj); 6520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 6530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case MSG_ID_SIM_READY: 6540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatLog.d(this, "SIM ready. Reporting STK service running now..."); 6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCmdIf.reportStkServiceIsRunning(null); 6560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 6570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: 6580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville throw new AssertionError("Unrecognized CAT command: " + msg.what); 6590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public synchronized void onCmdResponse(CatResponseMessage resMsg) { 6630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (resMsg == null) { 6640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // queue a response message. 6670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Message msg = this.obtainMessage(MSG_ID_RESPONSE, resMsg); 6680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville msg.sendToTarget(); 6690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private boolean validateResponse(CatResponseMessage resMsg) { 6720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mCurrntCmd != null) { 6730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return (resMsg.cmdDet.compareTo(mCurrntCmd.mCmdDet)); 6740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 6760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private boolean removeMenu(Menu menu) { 6790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 6800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (menu.items.size() == 1 && menu.items.get(0) == null) { 6810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return true; 6820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (NullPointerException e) { 6840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatLog.d(this, "Unable to get Menu's items size"); 6850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return true; 6860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 6880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void handleCmdResponse(CatResponseMessage resMsg) { 6910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Make sure the response details match the last valid command. An invalid 6920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // response is a one that doesn't have a corresponding proactive command 6930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // and sending it can "confuse" the baseband/ril. 6940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // One reason for out of order responses can be UI glitches. For example, 6950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // if the application launch an activity, and that activity is stored 6960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // by the framework inside the history stack. That activity will be 6970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // available for relaunch using the latest application dialog 6980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // (long press on the home button). Relaunching that activity can send 6990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // the same command's result again to the CatService and can cause it to 7000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // get out of sync with the SIM. 7010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (!validateResponse(resMsg)) { 7020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 7030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ResponseData resp = null; 7050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean helpRequired = false; 7060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CommandDetails cmdDet = resMsg.getCmdDetails(); 7070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (resMsg.resCode) { 7090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case HELP_INFO_REQUIRED: 7100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville helpRequired = true; 7110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // fall through 7120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case OK: 7130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case PRFRMD_WITH_PARTIAL_COMPREHENSION: 7140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case PRFRMD_WITH_MISSING_INFO: 7150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case PRFRMD_WITH_ADDITIONAL_EFS_READ: 7160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case PRFRMD_ICON_NOT_DISPLAYED: 7170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case PRFRMD_MODIFIED_BY_NAA: 7180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case PRFRMD_LIMITED_SERVICE: 7190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case PRFRMD_WITH_MODIFICATION: 7200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case PRFRMD_NAA_NOT_ACTIVE: 7210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case PRFRMD_TONE_NOT_PLAYED: 7220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (AppInterface.CommandType.fromInt(cmdDet.typeOfCommand)) { 7230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SET_UP_MENU: 7240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville helpRequired = resMsg.resCode == ResultCode.HELP_INFO_REQUIRED; 7250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sendMenuSelection(resMsg.usersMenuSelection, helpRequired); 7260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 7270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SELECT_ITEM: 7280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville resp = new SelectItemResponseData(resMsg.usersMenuSelection); 7290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 7300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case GET_INPUT: 7310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case GET_INKEY: 7320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Input input = mCurrntCmd.geInput(); 7330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (!input.yesNo) { 7340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // when help is requested there is no need to send the text 7350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // string object. 7360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (!helpRequired) { 7370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville resp = new GetInkeyInputResponseData(resMsg.usersInput, 7380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville input.ucs2, input.packed); 7390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 7410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville resp = new GetInkeyInputResponseData( 7420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville resMsg.usersYesNoSelection); 7430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 7450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case DISPLAY_TEXT: 7460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case LAUNCH_BROWSER: 7470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 7480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SET_UP_CALL: 7490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCmdIf.handleCallSetupRequestFromSim(resMsg.usersConfirm, null); 7500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // No need to send terminal response for SET UP CALL. The user's 7510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // confirmation result is send back using a dedicated ril message 7520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // invoked by the CommandInterface call above. 7530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCurrntCmd = null; 7540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 7550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 7570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case NO_RESPONSE_FROM_USER: 7580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case UICC_SESSION_TERM_BY_USER: 7590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case BACKWARD_MOVE_BY_USER: 7600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case USER_NOT_ACCEPT: 7610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville resp = null; 7620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 7630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: 7640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 7650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sendTerminalResponse(cmdDet, resMsg.resCode, false, 0, resp); 7670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCurrntCmd = null; 7680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private boolean isStkAppInstalled() { 7710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Intent intent = new Intent(AppInterface.CAT_CMD_ACTION); 7720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville PackageManager pm = mContext.getPackageManager(); 7730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville List<ResolveInfo> broadcastReceivers = 7740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pm.queryBroadcastReceivers(intent, PackageManager.GET_META_DATA); 7750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int numReceiver = broadcastReceivers == null ? 0 : broadcastReceivers.size(); 7760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return (numReceiver > 0); 7780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 780