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