CatService详解
相关类路径frameworks/opt/telephony/src/java/com/android/internal/telephony/cat/
下面有如下多个类
AppInterface.java BerTlv.java CallControlResult.java CatCmdMessage.java CatException.java CatLanguageDecoder.java CatLog.java CatResponseMessage.java CatService.java ChannelData.java CommandDetails.java //1、解析SIM卡上报的STK数据;2、将解析后的数据发送给RilMessageDecoder CommandParamsFactory.java CommandParams.java ComprehensionTlv.java //COMPREHENSION-TLV对象的枚举类型 ComprehensionTlvTag.java DtmfMessage.java Duration.java FontSize.java IATUtils.java IconLoader.java IconLoaderProxy.java ImageDescriptor.java Input.java Item.java LanguageMessage.java LaunchBrowserMode.java Menu.java OpenChannelData.java package.html PresentationType.java ReceiveChannelData.java ResponseData.java ResultCode.java ResultException.java RilMessageDecoder.java SendChannelData.java StkServiceProxy.java TextAlignment.java TextAttribute.java TextColor.java TextMessage.java Tone.java ToneSettings.java ValueParser.java
什么是TLV
TLV一种可变格式,TLV的意思就是:Type类型, Lenght长度,Value值。
在CAT相关源码中的体现
ComprehensionTlvTag.java
这是TLV中的T,即TAG
//枚举,用于表示COMPREHENSION-TLV对象的标记值。 如果要获取实际值,请调用value()方法 public enum ComprehensionTlvTag { COMMAND_DETAILS(0x01), //命令详情 DEVICE_IDENTITIES(0x02), //设备ID标识 RESULT(0x03), //结果 DURATION(0x04), //时长 ALPHA_ID(0x05), ADDRESS(0x06), //地址 USSD_STRING(0x0a), SMS_TPDU(0x0b), TEXT_STRING(0x0d), TONE(0x0e), ITEM(0x0f), ITEM_ID(0x10), RESPONSE_LENGTH(0x11), FILE_LIST(0x12), HELP_REQUEST(0x15), DEFAULT_TEXT(0x17), NEXT_ACTION_INDICATOR(0x18), EVENT_LIST(0x19), ICON_ID(0x1e), ITEM_ICON_ID_LIST(0x1f), DATE_TIME_TIMEZONE(0x26), IMMEDIATE_RESPONSE(0x2b), //Deal With DTMF Message Start DTMF(0x2c), //Deal With DTMF Message End LANGUAGE(0x2d), URL(0x31), BROWSER_TERMINATION_CAUSE(0x34), BEARER_DESCRIPTION(0x35), CHANNEL_DATA(0x36), CHANNEL_DATA_LENGTH(0x37), CHANNEL_STATUS(0x38), BUFFER_SIZE(0x39), TRANSPORT_LEVEL(0x3c), OTHER_ADDRESS(0x3e), NETWORK_ACCESS_NAME(0x47), TEXT_ATTRIBUTE(0x50); private int mValue; ComprehensionTlvTag(int value) { mValue = value; } //返回此COMPREHENSION-TLV对象的实际值 public int value() { return mValue; } //value转为枚举类型 public static ComprehensionTlvTag fromInt(int value) { for (ComprehensionTlvTag e : ComprehensionTlvTag.values()) { if (e.mValue == value) { return e; } } return null; } }
ComprehensionTlv.java
表示COMPREHENSION-TLV对象的类,里面包含了T,L,V
class ComprehensionTlv { private static final String LOG_TAG = "ComprehensionTlv"; private int mTag; //TLV中的T private boolean mCr; private int mLength; //TLV中的L private int mValueIndex; private byte[] mRawValue; //存储数据的字节数组,TLV中的V /** * 私有构造函数,请使用decodeMany或decode方法来获取对象实例 */ protected ComprehensionTlv(int tag, boolean cr, int length, byte[] data, int valueIndex) { mTag = tag; mCr = cr; mLength = length; mValueIndex = valueIndex; mRawValue = data; } /** * 解析字节数组中的COMPREHENSION-TLV对象列表. */ public static List<ComprehensionTlv> decodeMany(byte[] data, int startIndex) throws ResultException { ArrayList<ComprehensionTlv> items = new ArrayList<ComprehensionTlv>(); int endIndex = data.length; while (startIndex < endIndex) { ComprehensionTlv ctlv = ComprehensionTlv.decode(data, startIndex); if (ctlv != null) { items.add(ctlv); startIndex = ctlv.mValueIndex + ctlv.mLength; } else { CatLog.d(LOG_TAG, "decodeMany: ctlv is null, stop decoding"); items.clear(); break; } } return items; } /** * 从字节数组解析COMPREHENSION-TLV对象。 */ public static ComprehensionTlv decode(byte[] data, int startIndex) throws ResultException { int curIndex = startIndex; int endIndex = data.length; try { /* tag */ int tag; boolean cr; // Comprehension required flag int temp = data[curIndex++] & 0xff; switch (temp) { case 0: tag = 0; cr = false; break; case 0xff: ... ... return new ComprehensionTlv(tag, cr, length, data, curIndex); }
CommandParamsFactory.java
/** * 从tlv列表中找到指定TAG的TLV对象 */ private ComprehensionTlv searchForTag(ComprehensionTlvTag tag, List<ComprehensionTlv> ctlvs) { Iterator<ComprehensionTlv> iter = ctlvs.iterator(); return searchForNextTag(tag, iter); }
/** *SIM卡中proactive commands 的详细对象类 */ public class CommandDetails extends ValueObject implements Parcelable { public boolean compRequired; public int commandNumber; public int typeOfCommand; public int commandQualifier; @Override public ComprehensionTlvTag getTag() { return ComprehensionTlvTag.COMMAND_DETAILS; } ... ... }
AppInterface
/** * STK APP与CAT Telephony通信的接口 */ public interface AppInterface { /* *用于表示proactive commands的命令类型枚举。这些是Telephony支持的唯一命令 */ public static enum CommandType { DISPLAY_TEXT(0x21), GET_INKEY(0x22), GET_INPUT(0x23), LAUNCH_BROWSER(0x15), PLAY_TONE(0x20), REFRESH(0x01), SELECT_ITEM(0x24), SEND_SS(0x11), SEND_USSD(0x12), SEND_SMS(0x13), SEND_DTMF(0x14), SET_UP_EVENT_LIST(0x05), SET_UP_IDLE_MODE_TEXT(0x28), SET_UP_MENU(0x25), SET_UP_CALL(0x10), PROVIDE_LOCAL_INFORMATION(0x26), /* SPRD: add for USAT 27.22.4.25 LANGUAGE NOTIFICATION @{ */ LANGUAGE_NOTIFACTION(0x35), /* @}*/ OPEN_CHANNEL(0x40), CLOSE_CHANNEL(0x41), RECEIVE_DATA(0x42), SEND_DATA(0x43), GET_CHANNEL_STATUS(0x44); private int mValue; CommandType(int value) { mValue = value; } public int value() { return mValue; } public static CommandType fromInt(int value) { for (CommandType e : CommandType.values()) { if (e.mValue == value) { return e; } } return null; } } }
RilMessageDecoder.java
用于解析RilMessage的类
//用于对原始 ril 消息进行排队的类,将它们解码为 CommanParams 对象并将结果发送回 CAT 服务。 class RilMessageDecoder extends StateMachine { private class StateStart extends State { @Override public boolean processMessage(Message msg) { if (msg.what == CMD_START) { if (decodeMessageParams((RilMessage)msg.obj)) { transitionTo(mStateCmdParamsReady); } } else { CatLog.d(this, "StateStart unexpected expecting START=" + CMD_START + " got " + msg.what); } return true; } } /** 在decodeMessageParams()中先通过hexStringToBytes()方法将得到的Modem数据 转换为byte类型的数组数据rawData,然后将此数据交给CommandParamsFactory类 的make()方法去解析,经过make的解析就可以得到每项STK菜单的图标、菜单文本以 及需要的控件等信息 */ private boolean decodeMessageParams(RilMessage rilMsg) { boolean decodingStarted; mCurrentRilMessage = rilMsg; switch(rilMsg.mId) { ... case CatService.MSG_ID_PROACTIVE_COMMAND: case CatService.MSG_ID_EVENT_NOTIFY: case CatService.MSG_ID_REFRESH: byte[] rawData = null; try { //转为字节数组 rawData = IccUtils.hexStringToBytes((String) rilMsg.mData); CatLog.d(this, "[stk]rawData length"+rawData.length); if (rawData.length == 0) { CatLog.d(this, "[stk]rawData is empty"); decodingStarted = false; break; } } catch (Exception e) { // zombie messages are dropped CatLog.d(this, "[stk] decodemessage Exception e:" + e); decodingStarted = false; break; } try { //开始异步解析命令参数 mCmdParamsFactory.make(BerTlv.decode(rawData)); decodingStarted = true; } catch (ResultException e) { // send to Service for proper RIL communication. CatLog.d(this, "[stk]mCmdParamsFactory.make Exception = " + e); mCurrentRilMessage.mId = CatService.MSG_ID_SESSION_END; mCurrentRilMessage.mResCode = e.result(); sendCmdForExecution(mCurrentRilMessage); decodingStarted = false; } break; default: decodingStarted = false; break; } return decodingStarted; }
packages\apps\stk\src\com\android\stk\StkCmdReceiver.java
广播接收类,主要接收来自framework层的CatService发送的针对RIL层上报上来的处理结果的响应信息
1、目前Stk 只使用packages/apps/Stk/src/com/android/stk/下面的代码处理Stk 相关的逻辑
不需要关注Stk1,Stk2;
2、modem 上报Get input command,通过RIL_UNSOL_STK_PROACTIVE_COMMAND上报给上层