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