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