| /* |
| * Copyright (C) 2007 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.internal.telephony.cat; |
| |
| import com.android.internal.telephony.IccFileHandler; |
| import com.android.internal.telephony.IccUtils; |
| |
| import android.os.Handler; |
| import com.android.internal.util.State; |
| import com.android.internal.util.StateMachine; |
| import android.os.Message; |
| |
| /** |
| * Class used for queuing raw ril messages, decoding them into CommanParams |
| * objects and sending the result back to the CAT Service. |
| */ |
| class RilMessageDecoder extends StateMachine { |
| |
| // 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(CatService.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 State { |
| @Override |
| public boolean processMessage(Message msg) { |
| if (msg.what == CMD_START) { |
| if (decodeMessageParams((RilMessage)msg.obj)) { |
| transitionTo(mStateCmdParamsReady); |
| } |
| } else { |
| CatLog.d(this, "StateStart unexpected expecting START=" + |
| CMD_START + " got " + msg.what); |
| } |
| return true; |
| } |
| } |
| |
| private class StateCmdParamsReady extends State { |
| @Override |
| public 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 { |
| CatLog.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 CatService.MSG_ID_SESSION_END: |
| case CatService.MSG_ID_CALL_SETUP: |
| mCurrentRilMessage.mResCode = ResultCode.OK; |
| sendCmdForExecution(mCurrentRilMessage); |
| decodingStarted = false; |
| break; |
| case CatService.MSG_ID_PROACTIVE_COMMAND: |
| case CatService.MSG_ID_EVENT_NOTIFY: |
| case CatService.MSG_ID_REFRESH: |
| byte[] rawData = null; |
| try { |
| rawData = IccUtils.hexStringToBytes((String) rilMsg.mData); |
| } catch (Exception e) { |
| // zombie messages are dropped |
| CatLog.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. |
| CatLog.d(this, "decodeMessageParams: caught ResultException e=" + e); |
| mCurrentRilMessage.mResCode = e.result(); |
| sendCmdForExecution(mCurrentRilMessage); |
| decodingStarted = false; |
| } |
| break; |
| default: |
| decodingStarted = false; |
| break; |
| } |
| return decodingStarted; |
| } |
| } |