[go: nahoru, domu]

1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.telephony.cat;
18
19import android.os.Handler;
20import android.os.Message;
21import android.telephony.SubscriptionManager;
22import android.telephony.TelephonyManager;
23
24import com.android.internal.telephony.PhoneConstants;
25import com.android.internal.telephony.uicc.IccFileHandler;
26import com.android.internal.telephony.uicc.IccUtils;
27import com.android.internal.util.State;
28import com.android.internal.util.StateMachine;
29
30/**
31 * Class used for queuing raw ril messages, decoding them into CommanParams
32 * objects and sending the result back to the CAT Service.
33 */
34class RilMessageDecoder extends StateMachine {
35
36    // constants
37    private static final int CMD_START = 1;
38    private static final int CMD_PARAMS_READY = 2;
39
40    // members
41    private CommandParamsFactory mCmdParamsFactory = null;
42    private RilMessage mCurrentRilMessage = null;
43    private Handler mCaller = null;
44    private static int mSimCount = 0;
45    private static RilMessageDecoder[] mInstance = null;
46
47    // States
48    private StateStart mStateStart = new StateStart();
49    private StateCmdParamsReady mStateCmdParamsReady = new StateCmdParamsReady();
50
51    /**
52     * Get the singleton instance, constructing if necessary.
53     *
54     * @param caller
55     * @param fh
56     * @return RilMesssageDecoder
57     */
58    public static synchronized RilMessageDecoder getInstance(Handler caller, IccFileHandler fh,
59            int slotId) {
60        if (null == mInstance) {
61            mSimCount = TelephonyManager.getDefault().getSimCount();
62            mInstance = new RilMessageDecoder[mSimCount];
63            for (int i = 0; i < mSimCount; i++) {
64                mInstance[i] = null;
65            }
66        }
67
68        if (slotId != SubscriptionManager.INVALID_SIM_SLOT_INDEX && slotId < mSimCount) {
69            if (null == mInstance[slotId]) {
70                mInstance[slotId] = new RilMessageDecoder(caller, fh);
71            }
72        } else {
73            CatLog.d("RilMessageDecoder", "invaild slot id: " + slotId);
74            return null;
75        }
76
77        return mInstance[slotId];
78    }
79
80    /**
81     * Start decoding the message parameters,
82     * when complete MSG_ID_RIL_MSG_DECODED will be returned to caller.
83     *
84     * @param rilMsg
85     */
86    public void sendStartDecodingMessageParams(RilMessage rilMsg) {
87        Message msg = obtainMessage(CMD_START);
88        msg.obj = rilMsg;
89        sendMessage(msg);
90    }
91
92    /**
93     * The command parameters have been decoded.
94     *
95     * @param resCode
96     * @param cmdParams
97     */
98    public void sendMsgParamsDecoded(ResultCode resCode, CommandParams cmdParams) {
99        Message msg = obtainMessage(RilMessageDecoder.CMD_PARAMS_READY);
100        msg.arg1 = resCode.value();
101        msg.obj = cmdParams;
102        sendMessage(msg);
103    }
104
105    private void sendCmdForExecution(RilMessage rilMsg) {
106        Message msg = mCaller.obtainMessage(CatService.MSG_ID_RIL_MSG_DECODED,
107                new RilMessage(rilMsg));
108        msg.sendToTarget();
109    }
110
111    private RilMessageDecoder(Handler caller, IccFileHandler fh) {
112        super("RilMessageDecoder");
113
114        addState(mStateStart);
115        addState(mStateCmdParamsReady);
116        setInitialState(mStateStart);
117
118        mCaller = caller;
119        mCmdParamsFactory = CommandParamsFactory.getInstance(this, fh);
120    }
121
122    private RilMessageDecoder() {
123        super("RilMessageDecoder");
124    }
125
126    private class StateStart extends State {
127        @Override
128        public boolean processMessage(Message msg) {
129            if (msg.what == CMD_START) {
130                if (decodeMessageParams((RilMessage)msg.obj)) {
131                    transitionTo(mStateCmdParamsReady);
132                }
133            } else {
134                CatLog.d(this, "StateStart unexpected expecting START=" +
135                         CMD_START + " got " + msg.what);
136            }
137            return true;
138        }
139    }
140
141    private class StateCmdParamsReady extends State {
142        @Override
143        public boolean processMessage(Message msg) {
144            if (msg.what == CMD_PARAMS_READY) {
145                mCurrentRilMessage.mResCode = ResultCode.fromInt(msg.arg1);
146                mCurrentRilMessage.mData = msg.obj;
147                sendCmdForExecution(mCurrentRilMessage);
148                transitionTo(mStateStart);
149            } else {
150                CatLog.d(this, "StateCmdParamsReady expecting CMD_PARAMS_READY="
151                         + CMD_PARAMS_READY + " got " + msg.what);
152                deferMessage(msg);
153            }
154            return true;
155        }
156    }
157
158    private boolean decodeMessageParams(RilMessage rilMsg) {
159        boolean decodingStarted;
160
161        mCurrentRilMessage = rilMsg;
162        switch(rilMsg.mId) {
163        case CatService.MSG_ID_SESSION_END:
164        case CatService.MSG_ID_CALL_SETUP:
165            mCurrentRilMessage.mResCode = ResultCode.OK;
166            sendCmdForExecution(mCurrentRilMessage);
167            decodingStarted = false;
168            break;
169        case CatService.MSG_ID_PROACTIVE_COMMAND:
170        case CatService.MSG_ID_EVENT_NOTIFY:
171        case CatService.MSG_ID_REFRESH:
172            byte[] rawData = null;
173            try {
174                rawData = IccUtils.hexStringToBytes((String) rilMsg.mData);
175            } catch (Exception e) {
176                // zombie messages are dropped
177                CatLog.d(this, "decodeMessageParams dropping zombie messages");
178                decodingStarted = false;
179                break;
180            }
181            try {
182                // Start asynch parsing of the command parameters.
183                mCmdParamsFactory.make(BerTlv.decode(rawData));
184                decodingStarted = true;
185            } catch (ResultException e) {
186                // send to Service for proper RIL communication.
187                CatLog.d(this, "decodeMessageParams: caught ResultException e=" + e);
188                mCurrentRilMessage.mResCode = e.result();
189                sendCmdForExecution(mCurrentRilMessage);
190                decodingStarted = false;
191            }
192            break;
193        default:
194            decodingStarted = false;
195            break;
196        }
197        return decodingStarted;
198    }
199
200    public void dispose() {
201        quitNow();
202        mStateStart = null;
203        mStateCmdParamsReady = null;
204        mCmdParamsFactory.dispose();
205        mCmdParamsFactory = null;
206        mCurrentRilMessage = null;
207        mCaller = null;
208        mInstance = null;
209    }
210}
211