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 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      */
     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      */
     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      */
     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 
    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 
    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 
    122     private RilMessageDecoder() {
    123         super("RilMessageDecoder");
    124     }
    125 
    126     private class StateStart extends State {
    127         @Override
    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
    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 
    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 
    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