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 196bc4098827f3070a44b5e51508b455d7c7be9c07Wink Savilleimport android.os.Handler; 206bc4098827f3070a44b5e51508b455d7c7be9c07Wink Savilleimport android.os.Message; 216bc4098827f3070a44b5e51508b455d7c7be9c07Wink Savilleimport android.telephony.SubscriptionManager; 226bc4098827f3070a44b5e51508b455d7c7be9c07Wink Savilleimport android.telephony.TelephonyManager; 236bc4098827f3070a44b5e51508b455d7c7be9c07Wink Saville 246bc4098827f3070a44b5e51508b455d7c7be9c07Wink Savilleimport com.android.internal.telephony.PhoneConstants; 25d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccFileHandler; 26d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccUtils; 270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.util.State; 280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.util.StateMachine; 290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/** 310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Class used for queuing raw ril messages, decoding them into CommanParams 320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * objects and sending the result back to the CAT Service. 330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 340825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleclass RilMessageDecoder extends StateMachine { 350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // constants 370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int CMD_START = 1; 380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int CMD_PARAMS_READY = 2; 390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // members 410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private CommandParamsFactory mCmdParamsFactory = null; 420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private RilMessage mCurrentRilMessage = null; 430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private Handler mCaller = null; 44a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private static int mSimCount = 0; 45a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private static RilMessageDecoder[] mInstance = null; 460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // States 480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private StateStart mStateStart = new StateStart(); 490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private StateCmdParamsReady mStateCmdParamsReady = new StateCmdParamsReady(); 500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Get the singleton instance, constructing if necessary. 530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param caller 550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param fh 560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return RilMesssageDecoder 570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 58a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public static synchronized RilMessageDecoder getInstance(Handler caller, IccFileHandler fh, 59a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville int slotId) { 60a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (null == mInstance) { 61a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mSimCount = TelephonyManager.getDefault().getSimCount(); 62a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mInstance = new RilMessageDecoder[mSimCount]; 63a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville for (int i = 0; i < mSimCount; i++) { 64a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mInstance[i] = null; 65a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 66a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 67a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 684b09dff383ae7dfca595aeeea886a594a1947340Wink Saville if (slotId != SubscriptionManager.INVALID_SIM_SLOT_INDEX && slotId < mSimCount) { 69a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (null == mInstance[slotId]) { 70a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mInstance[slotId] = new RilMessageDecoder(caller, fh); 71a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 72a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else { 73a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville CatLog.d("RilMessageDecoder", "invaild slot id: " + slotId); 74a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return null; 750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 76a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 77a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return mInstance[slotId]; 780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Start decoding the message parameters, 820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * when complete MSG_ID_RIL_MSG_DECODED will be returned to caller. 830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param rilMsg 850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void sendStartDecodingMessageParams(RilMessage rilMsg) { 870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Message msg = obtainMessage(CMD_START); 880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville msg.obj = rilMsg; 890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sendMessage(msg); 900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * The command parameters have been decoded. 940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param resCode 960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param cmdParams 970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void sendMsgParamsDecoded(ResultCode resCode, CommandParams cmdParams) { 990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Message msg = obtainMessage(RilMessageDecoder.CMD_PARAMS_READY); 1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville msg.arg1 = resCode.value(); 1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville msg.obj = cmdParams; 1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sendMessage(msg); 1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void sendCmdForExecution(RilMessage rilMsg) { 1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Message msg = mCaller.obtainMessage(CatService.MSG_ID_RIL_MSG_DECODED, 1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville new RilMessage(rilMsg)); 1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville msg.sendToTarget(); 1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private RilMessageDecoder(Handler caller, IccFileHandler fh) { 1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville super("RilMessageDecoder"); 1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addState(mStateStart); 1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addState(mStateCmdParamsReady); 1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville setInitialState(mStateStart); 1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCaller = caller; 1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCmdParamsFactory = CommandParamsFactory.getInstance(this, fh); 1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 122a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private RilMessageDecoder() { 123a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville super("RilMessageDecoder"); 124a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 125a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private class StateStart extends State { 1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean processMessage(Message msg) { 1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (msg.what == CMD_START) { 1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (decodeMessageParams((RilMessage)msg.obj)) { 1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville transitionTo(mStateCmdParamsReady); 1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatLog.d(this, "StateStart unexpected expecting START=" + 1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CMD_START + " got " + msg.what); 1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return true; 1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private class StateCmdParamsReady extends State { 1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean processMessage(Message msg) { 1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (msg.what == CMD_PARAMS_READY) { 1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCurrentRilMessage.mResCode = ResultCode.fromInt(msg.arg1); 1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCurrentRilMessage.mData = msg.obj; 1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sendCmdForExecution(mCurrentRilMessage); 1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville transitionTo(mStateStart); 1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatLog.d(this, "StateCmdParamsReady expecting CMD_PARAMS_READY=" 1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + CMD_PARAMS_READY + " got " + msg.what); 1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville deferMessage(msg); 1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return true; 1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private boolean decodeMessageParams(RilMessage rilMsg) { 1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean decodingStarted; 1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCurrentRilMessage = rilMsg; 1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch(rilMsg.mId) { 1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case CatService.MSG_ID_SESSION_END: 1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case CatService.MSG_ID_CALL_SETUP: 1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCurrentRilMessage.mResCode = ResultCode.OK; 1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sendCmdForExecution(mCurrentRilMessage); 1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville decodingStarted = false; 1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case CatService.MSG_ID_PROACTIVE_COMMAND: 1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case CatService.MSG_ID_EVENT_NOTIFY: 1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case CatService.MSG_ID_REFRESH: 1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] rawData = null; 1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville rawData = IccUtils.hexStringToBytes((String) rilMsg.mData); 1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (Exception e) { 1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // zombie messages are dropped 1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatLog.d(this, "decodeMessageParams dropping zombie messages"); 1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville decodingStarted = false; 1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Start asynch parsing of the command parameters. 1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCmdParamsFactory.make(BerTlv.decode(rawData)); 1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville decodingStarted = true; 1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (ResultException e) { 1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // send to Service for proper RIL communication. 1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CatLog.d(this, "decodeMessageParams: caught ResultException e=" + e); 1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCurrentRilMessage.mResCode = e.result(); 1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sendCmdForExecution(mCurrentRilMessage); 1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville decodingStarted = false; 1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: 1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville decodingStarted = false; 1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return decodingStarted; 1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 199eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta 200eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta public void dispose() { 201eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta mStateStart = null; 202eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta mStateCmdParamsReady = null; 203eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta mCmdParamsFactory.dispose(); 204eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta mCmdParamsFactory = null; 205eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta mCurrentRilMessage = null; 206eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta mCaller = null; 207eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta mInstance = null; 208eca4a2ab310bf8d96cf98b5e880e2f8eef7ffeb6Sandeep Gutta } 2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 210