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