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