• 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.os.Handler;
20 import android.os.Message;
21 import android.telephony.SubscriptionManager;
22 import android.telephony.TelephonyManager;
23 
24 import com.android.internal.telephony.PhoneConstants;
25 import com.android.internal.telephony.uicc.IccFileHandler;
26 import com.android.internal.telephony.uicc.IccUtils;
27 import com.android.internal.util.State;
28 import 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  */
34 class 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      */
getInstance(Handler caller, IccFileHandler fh, int slotId)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      */
sendStartDecodingMessageParams(RilMessage rilMsg)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      */
sendMsgParamsDecoded(ResultCode resCode, CommandParams cmdParams)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 
sendCmdForExecution(RilMessage rilMsg)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 
RilMessageDecoder(Handler caller, IccFileHandler fh)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 
RilMessageDecoder()122     private RilMessageDecoder() {
123         super("RilMessageDecoder");
124     }
125 
126     private class StateStart extends State {
127         @Override
processMessage(Message msg)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
processMessage(Message msg)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 
decodeMessageParams(RilMessage rilMsg)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 
dispose()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