SIM Toolkit开发

SIM Toolkit驱动开发

目的:最近刚刚接触RILRILWindows Mobile的驱动中还是比较复杂的,由于微软有关PhoneFeature全部在RIL中实现,就可以想象其复杂的程度了。网上去找关于如何做RIL的资料是非常的少,而且RIL这种东西又不是很难,难的东西模块已经帮我做好了,我们做的只需要把与上层的接口了解清楚,就行了。既然没有技术难度,何必每个做RIL的人,都需要从头开始熟悉呢,站着巨人的肩膀上就可以了,当然我不是巨人。我愿意当个挖井人,一人挖井,全村受益。

 

SIM ToolKit架构:要弄清楚SIM Toolkit, 就是了解其与上层的接口。如何把上层的函数请求包装成AT命令,往串口发送。串口来的数据,解析成上层所要的数据结构。上层通过RIL Toolkit 函数进行函数调用,实现请求。SIM Toolkit接口函数如下:

l         RIL_GetSimToolkitProfile//获取STK的简要信息

l         RIL_SetSimToolkitProfile//设置STK的简要信息

l         RIL_SendSimToolkitCmdResponse//发送一个STK命令的响应

l         RIL_SendSimToolkitEnvelopeCmd//发送一个envelope命令

l         RIL_TerminateSimToolkitSession//终止STK会议

其中主要的最重要的一个函数是RIL_SendSimToolkitCmdResponse,其他几个在Simtkit中不会调用到。当底层有命令上来,需要上层做反应时,通过RIL_SendSimToolkitCmdResponse给予反馈。

代码分析:以模拟器的RILGSM分析, SIM Toolkit应用的架构如下图

 SIM Toolkit开发_第1张图片

 

RILGSM: GSM RIL驱动

SIMTkit: STK的功能函数及UI显示。

Tkitapp: 管理STKSTK的图标及程序的名字。

其中tkitappsimtkit这两部分我们都不需要修改任何代码,只要修改rilgsm.dll代码,根据当前的模块跟上层完成接口就可以了。

 

其调用顺序如下:

 

 SIM Toolkit开发_第2张图片

解析SIM Toolkit的函数是ParseSIMToolkitCmdOrRsp,该函数在Response.cpp中。当收到串口STK通知时,我们调用这个函数去解析。在GSM中是“*STKN:”。ParseSIMToolkitCmdOrRsp函数的流程如下

 SIM Toolkit开发_第3张图片

 

 

ParseSIMToolkitCmdOrRsp 流程图

上图的流程中,调用ParseCommand来进行解析。ParseCommand流程图如下:

 SIM Toolkit开发_第4张图片

 

ParseCommand流程图

ParseTextFormatCommand函数中是我们正在要去执行解析的函数,一般情况下,命令传过来的时候。如“*STKN:44524542100,在“*STKN:”后面会带有一个数值,这个数值就是标志通知是什么类型的通知,看下ParseTextFormatCommand函数中的代码,先用ParseHexDWord去解析NotifyCode

// First thing should be the Command ID.

    if (!ParseHexDWord((LPCSTR)m_lpbParse, SIMTKIT_TEXTPARSE_PARSE_LEADINGZERO, dwNotifyCode, (LPCSTR&)m_lpbParse))

    {

        *pdwRetVal = SIM_RESPONSE_ERR_COMMANDNUMBER;

        hr = E_FAIL;

        goto Exit;

}

解析出NotifyCode之后,再进入相应的解析子函数。

switch(dwNotifyCode)

    {

        case SIM_NOTIFY_SETUPMENU:

        case SIM_NOTIFY_SELECTITEM:

            hr = ParseSetupMenu(dwNotifyCode, pbFifthByte);

            break;

        case SIM_NOTIFY_PLAYTONE:

            hr = ParsePlayTone();

            break;

        case SIM_NOTIFY_DISPLAYTEXT:

            hr = ParseDisplayText(pbFifthByte);

            break;

        case SIM_NOTIFY_GETINKEY:

            hr = ParseGetInKey(pbFifthByte);

            break;

        case SIM_NOTIFY_GETINPUT:

            hr = ParseGetInput(pbFifthByte);

            break;

        case SIM_NOTIFY_SETUPIDLEMODETEXT:

            hr = ParseSetupIdleModeText();

            break;

        case SIM_NOTIFY_SENDSMS:

        case SIM_NOTIFY_SENDSS:

        case SIM_NOTIFY_SENDUSSD:

        case SIM_NOTIFY_SETUPCALL:

        case SIM_NOTIFY_SENDDTMF:

        case SIM_NOTIFY_OPENCHANNEL:

        case SIM_NOTIFY_CLOSECHANNEL:

        case SIM_NOTIFY_RUNATCOMMAND:

            hr = ParseUnsolicitedData();

            break;

        case SIM_NOTIFY_REFRESH:

            hr = ParseRefresh(pbFifthByte);

            break;         

        case SIM_NOTIFY_EVENTLIST:

            hr = ParseEventList();

            break;         

        case SIM_NOTIFY_LAUNCHBROWSER:

            hr = ParseLaunchBrowser(pbFifthByte);

            break;         

        case SIM_NOTIFY_RECEIVEDATA:

            hr = ParseReceiveData();

            break;         

        case SIM_NOTIFY_SENDDATA:

            hr = ParseSendData();

            break;         

        case SIM_NOTIFY_LANGUAGENOTIFICATION:

            hr = ParseLanguageNotification();

            break;         

        case SIM_NOTIFY_CALLSETUP:

        case SIM_NOTIFY_MORETIME:

        case SIM_NOTIFY_POLLINTERVAL:

        case SIM_NOTIFY_POLLINGOFF:

        case SIM_NOTIFY_LOCALINFO:

        default:

            // We don't understand this command

            DEBUGMSG(ZONE_ERROR, (TEXT("RilDrv : SIMTKit: Don't understand command %x/r/n"), dwNotifyCode));

            *pdwRetVal = SIM_RESPONSE_ERR_COMMANDTYPE;

            hr = E_FAIL;

            goto Exit;

}

 

每个解析函数主要的工作就是把字符串解析并赋值给CRilSimToolkitCommand的成员变量。CRilSimToolkitCommand有很多成员变量,我们该如何进行赋值呢。我们看到在ParseCommand的流程图中,在完成解析后,有一系列的BUILD打头的函数。这些函数,就是把数据打包成SIMTKIT要的数据,如SIMTEXTSIMSMSSIMCALL等等。下面举几个例子说明下

BuildSIMTEXT

BuildSIMTEXT中,就是把ParseDisplayText解析出来的数据,组装成SIMTEXT的结构,下面的伪代码可以看出。

SIMTEXT *pst = NULL;

pst->dwMinResponse = m_dwMinResponse;

pst->dwMaxResponse = m_dwMaxResponse;

 

pst->dwFlags = || bFifthByte;

 

pst + pst->dwTextOffset = m_pwszText;

pst->dwTextSize = m_dwTextLen;

 

pst + pst->dwDefaultTextOffset = m_pwszDefaultText;

pst->dwDefaultTextSize = m_dwDefaultTextLen;

 

pst->dwIconIdentifier = m_dwIconIdentifier;

pst->dwIconQualifier = m_dwIconQualifier;

我们从解析函数中看到pbFifthByte这个变量,传入了很多函数,他根据的NotifyCode,他的意义都不一样,这都需要看其对应的BUILD函数对于pbFifthByte是怎么用的。对于其他解析函数都一样,你都需要认认真真的把相应的BUILD函数看了之后,那个变量是对应AT命令通知的哪个字段。完成这件事之后,解析就非常简单了,就是一个解析,赋值的过程了。

 

完成了命令解析,也组装好数据结构,就往SIMtkit.dll通知了,在得到通知后,simtkit中会根据通知的类型,调用相应的功能,并显示相应的UI。并会通过RIL_SendSimToolkitCmdResponse对通知进行反馈。在RILDrv_SendSimToolkitCmdResponse中调用CRilSimToolkitResponse::CreateResponse,创建AT命令。这个过程就比较简单了,就不做说明了。

 

 

你可能感兴趣的:(SIM Toolkit开发)