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 com.android.internal.telephony.IccFileHandler;
200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.IccUtils;
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Handler;
230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.util.State;
240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.util.StateMachine;
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Class used for queuing raw ril messages, decoding them into CommanParams
290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * objects and sending the result back to the CAT Service.
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleclass RilMessageDecoder extends StateMachine {
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // constants
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int CMD_START = 1;
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final int CMD_PARAMS_READY = 2;
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // members
380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static RilMessageDecoder sInstance = null;
390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private CommandParamsFactory mCmdParamsFactory = null;
400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private RilMessage mCurrentRilMessage = null;
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private Handler mCaller = null;
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // States
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private StateStart mStateStart = new StateStart();
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private StateCmdParamsReady mStateCmdParamsReady = new StateCmdParamsReady();
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Get the singleton instance, constructing if necessary.
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param caller
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param fh
520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return RilMesssageDecoder
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public static synchronized RilMessageDecoder getInstance(Handler caller, IccFileHandler fh) {
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (sInstance == null) {
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            sInstance = new RilMessageDecoder(caller, fh);
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            sInstance.start();
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return sInstance;
600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Start decoding the message parameters,
640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * when complete MSG_ID_RIL_MSG_DECODED will be returned to caller.
650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param rilMsg
670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void sendStartDecodingMessageParams(RilMessage rilMsg) {
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Message msg = obtainMessage(CMD_START);
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        msg.obj = rilMsg;
710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        sendMessage(msg);
720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * The command parameters have been decoded.
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param resCode
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param cmdParams
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void sendMsgParamsDecoded(ResultCode resCode, CommandParams cmdParams) {
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Message msg = obtainMessage(RilMessageDecoder.CMD_PARAMS_READY);
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        msg.arg1 = resCode.value();
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        msg.obj = cmdParams;
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        sendMessage(msg);
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void sendCmdForExecution(RilMessage rilMsg) {
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Message msg = mCaller.obtainMessage(CatService.MSG_ID_RIL_MSG_DECODED,
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                new RilMessage(rilMsg));
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        msg.sendToTarget();
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private RilMessageDecoder(Handler caller, IccFileHandler fh) {
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        super("RilMessageDecoder");
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        addState(mStateStart);
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        addState(mStateCmdParamsReady);
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        setInitialState(mStateStart);
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCaller = caller;
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCmdParamsFactory = CommandParamsFactory.getInstance(this, fh);
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private class StateStart extends State {
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        @Override
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        public boolean processMessage(Message msg) {
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (msg.what == CMD_START) {
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (decodeMessageParams((RilMessage)msg.obj)) {
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    transitionTo(mStateCmdParamsReady);
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                CatLog.d(this, "StateStart unexpected expecting START=" +
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                         CMD_START + " got " + msg.what);
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private class StateCmdParamsReady extends State {
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        @Override
1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        public boolean processMessage(Message msg) {
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (msg.what == CMD_PARAMS_READY) {
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mCurrentRilMessage.mResCode = ResultCode.fromInt(msg.arg1);
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mCurrentRilMessage.mData = msg.obj;
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                sendCmdForExecution(mCurrentRilMessage);
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                transitionTo(mStateStart);
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                CatLog.d(this, "StateCmdParamsReady expecting CMD_PARAMS_READY="
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                         + CMD_PARAMS_READY + " got " + msg.what);
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                deferMessage(msg);
1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return true;
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private boolean decodeMessageParams(RilMessage rilMsg) {
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        boolean decodingStarted;
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        mCurrentRilMessage = rilMsg;
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        switch(rilMsg.mId) {
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CatService.MSG_ID_SESSION_END:
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CatService.MSG_ID_CALL_SETUP:
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            mCurrentRilMessage.mResCode = ResultCode.OK;
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            sendCmdForExecution(mCurrentRilMessage);
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            decodingStarted = false;
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CatService.MSG_ID_PROACTIVE_COMMAND:
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CatService.MSG_ID_EVENT_NOTIFY:
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        case CatService.MSG_ID_REFRESH:
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            byte[] rawData = null;
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            try {
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                rawData = IccUtils.hexStringToBytes((String) rilMsg.mData);
1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } catch (Exception e) {
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // zombie messages are dropped
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                CatLog.d(this, "decodeMessageParams dropping zombie messages");
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                decodingStarted = false;
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                break;
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            try {
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Start asynch parsing of the command parameters.
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mCmdParamsFactory.make(BerTlv.decode(rawData));
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                decodingStarted = true;
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } catch (ResultException e) {
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // send to Service for proper RIL communication.
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                CatLog.d(this, "decodeMessageParams: caught ResultException e=" + e);
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mCurrentRilMessage.mResCode = e.result();
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                sendCmdForExecution(mCurrentRilMessage);
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                decodingStarted = false;
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        default:
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            decodingStarted = false;
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            break;
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return decodingStarted;
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
178