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