MSDN关于RIL的翻译

无线接口层(Radio Interface Layer: RIL) RIL提供移动通讯核心(cellcore)和无线硬件设备(modem)之间通讯的控制接口,由此可以适应不同无线网络,集成不同Modem设备。

RIL由两部分组成:RIL proxyRIL driverRILproxy是一个基于CE的动态链接库(DLL)
--- ril.dll,微软已经提供,它的作用是让多个应用可以访问单个ril driver RIL driver即流驱动需要自己实现,比如实现了rilgsm.dll驱动一个gsmmodemRILdriver向系统提供无线服务,包括语音、数据和SMSRILdriver同时也通知无线状态的改变,例如服务区(coverage)、信息强度和来电等。 RIL如同音频模型,rilproxy好比waveapi ril driver好比wave流驱动。

Ril proxylogging是一个可选功能。是一个动态库rillog.dll boot时候由ril.dll加载。

 

RIL OS设计 提供关于RIL驱动和RIL实现所需的OS定制信息。 支持无线所需要的组件下表列出支持无线所需要的组件和示例驱动的位置。

 

Enfora ExternalRadio Module

/platform/DEVICEEMULATOR/src/drivers/rilpdd/enfora/platform/CEPC/src/drivers/rilpdd/enfora

 

TTPCom RadioModule

/platform/DEVICEEMULATOR/src/drivers/rilpdd/ttpcom/platform/CEPC/src/drivers/rilpdd/ttpcom

 

创建内核运行时映像时,通过关联IMG环境变量来指定需要的RIL驱动。同时必须明确的不设置其它RILIMG环境变量。 下表列出支持RIL模块的IMG环境变量

Radio Module RIL Driver IMG Setting(s)

Enfora External Radio Module IMGENFORA=1

TTPCom Radio Module IMGTTPCOM=1

下面的示例说明了如何使能Enfora驱动。如果使用Rnfora驱动,必须使能710MUX驱动。 BaseOSEnv.bat 文件中增加以下行:

set IMGFAKERIL=

set IMGTTPCOM=

set IMGENFORA=1

 


------ 开发RIL驱动 你可以开发自定义的RIL驱动,来驱动你的无线模块。提供示例驱动以帮助你来设置和开发新的RIL驱动。 CE6.0提供下面的MDD层示例: Sample Driver Driver LocationFor Enfora radio stacks /public/Cellcore/ril/driver/mdd 此示例RIL驱动也可以在TTPCOM无线堆栈上工作,然而它仅仅在已经停产且使用过时固件的TTPCOM模块上进行了测试 ,没有在运行CE6.0的设备模拟器上测试过。 CE6.0也可以针对一部分无线模块用PDD层,详细的信息,请考虑Supported Radio Modules 下面的列表说明一些与成功的设备驱动开发相关的主题。

1.如果开发设备驱动,请考虑Developing a DeviceDirver

2.CETK包含一系列的设备驱动测试工具,关于CETK,请考虑Windows Embedded CE Test Kit

 

------ RILMiniport Driver (微端口/小端口 : miniport 不直接调用操作系统函数,它们对于操作系统的接口是NDIS) RIL微端口驱动组件是一个NDIS中间驱动,它创建在TCP/IP堆栈和RIL之间传递IP配置信息的接口。 下图说明在无线硬件和TCP/IP堆栈之间包传递的路径。 TCP/IP ConnectionManager | | | NDISUIO |_ _ _| | RIL Miniport Driver | RIL Driver | RadioHardware RIL微端口驱动暴露的是802.3NIDIS接口,此接口被暴露给TCP/IP和其它协议驱动。微端口驱动同时也暴露一系列 WWAN(wirelessWide Area Network)配置和OIDS(notification NDIS object identifiers) 微端口驱动使用RIL APIs发送和接收包,配置802.3接口和得到关于802.3接口的状态。 上图也显示了从Connection ManagerRIL微端口驱动的路径。此路径使用NDISUIO(NDISUser-Mode I/O)打包驱动 接口。Connection Manager使用RIL微端口驱动来帮助建立以下任务: 1.建立GPRS连接 2.断开GPRS连接 3.监视GPRS连接状态

 

------ RIL驱动增加同步(Simultaneous)数据连接的支持 示例的RIL驱动支持同步的基于PPPGPRS连接,详细的信息请考虑 Configuring SimultaneousData Connections 中注册表设置项。 如果你想在一个自定义的RIL驱动中使用同步的数据连接,必须在驱动中实现相关的函数。 每个基于PPP的连接都是和COM端口句柄相关的,此COM端口必须在驱动中执行。 RIL代理使用下面的IOCTL调用RIL驱动,得到COM端口描述。IOCTL_RIL_GETSERIALPORTHANDLEFROMCONTEXTID RIL驱动必须实现一个同步RIL驱动,它的原型如下:HRESULT RILDrv_GetSerialPortHandleFromContextID(DWORD dwContextID, TCHAR*tszDataPortName, DWORD dwSize, DWORD *pdwSizeOut) RIL驱动实现的示例位于RIL Sample Driver代码中。RILDrv_GetSerialPortHandleFromContextID()函数定义在 Data.cpp中,在Rilmain.cpp中调用。 RIL代理初始化端口句柄(使用CreateFile()函数),并返回此句柄用于特定上下文ID(GPRS连接)基于PPP的连接。

 

------ 增加Push-To-Talk支持 Push-To-Talk(PTT)是一个半双工通讯方法。用户体验与使用无线电对讲机(walkie-talkie)的体验是一样的。在PTT 通话中,一通讯方在讲话时按下按钮,在听时松开按钮。 通常,为设备增加PTTOEM必须做以下工作: 1.实现 RILCALLTYPECALLBACK() 函数,它标识PTT通讯。 2.正确设置PTT注册表项,考虑RILRegistry Setting PTTExample.exe应用是一个测试程序,演示PPT通话处理。提供此程序的源代码供考虑。

 

------ RIL代理日志(Log) RIL代理日志是一个可选的DLLrillog.dll。它用来减少RIL代理组件ril.dll的运行痕迹,并且提高RIL代理内存的 使用。 可以通过在编译映像文件时设置环境变量SYSGEN_RILPROXY_LOG1 来增加RIL代理的日志。RIL代理日志也可以在映 像文件生成后手工运行:sysgen -p cellcore rillog 来增加。如果设备与Platform Builder连接,就不必增加 rillog.dll到映像文件中。

注册表项:HKEY_LOCAL_MACHINE/Software/Microsoft/RIL 用于控制RIL代理日志的输出。下表列出命名的值:

Value :
type
Description

RILProxyLogDetail: REG_DWORD 设置RIL代理日志的详细级别,设为1使能详细的日志输出。默认值为1

RILProxyLogNormal: REG_DWORD 设置RIL代理日志输出级别,设为1使能正常日志输出。默认值为1 注:代理日志输出时,RILProxyLogDetail RILProxyLogNormal 必须有一个为1

 

------ RIL应用开发应用开发者可以使用RIL函数做出不同特点的手机。RIL功能暴露的函数性的需求,实现了基于无线的手机通讯和数 据连接。本部分包括开发者对实现通讯和数据连接情景感兴趣的概念性信息。 RIL体系 RIL被分成两独立的部分:RIL驱动和RIL代理。RIL驱动处理无线命令和事件。RIL代理执行多用户访问RIL驱动的仲 裁。 RIL驱动体系基于嵌入式WindowsCE标准的MDD/PDD驱动模型。分为两个主要的部分,MDDPDD层。下图说明了RIL 系: RIL Client(celltsp.dll) | RIL Proxy(ril.dll) | RILDirver(rilgsm.dll) RILMDD.lib RILPDD_AT_COMMON.lib RILPDD_AT_OMAP730.lib |Radio MUX(csmi.dll) | Radio Stack(TI TCS 3.x) MDD(Model Device Driver)层独立于无线堆栈,它包含RIL代理接口代码和与RIL驱动无关特性实现的代码。 PDD(Platform DependentDriver)层是与无线堆栈相关的。它包含为了无线堆栈而实现的RIL APIs接口代码,这是 OEM厂商必须实现的层。为了促进PDD层更容易的实现任务,PDD层自身分成无线类型通用的代码和特定无线类型特有 的代码两部分。例如上图所示的PDD层被分成通用的AT代码和无线特定的AT代码。 虽然RIL驱动被分成2个主要的部分,但输出的文件仍然是一个单独的DLL 更多信息,请考虑RIL驱动和RIL代理。

 

------ TIL呼叫概述 蜂窝电话服务提供者(TSP)可以使用RIL拨出或接通语音通话,就像是远程访问服务(RAS)一样。下面的部分提供一些 典型的呼叫情况的示例。 RIL呼出语音呼叫过程 为了拨打语音呼叫,蜂窝TSPRIL驱动完成以下步骤:

1. 应用调用电话API(TAPI): lineMakeCall()lineDial()函数初始化呼叫。

2. TSP在拨号状态中创建一个TAPI呼叫。

3. TSP调用RIL_SetAudioDevices()函数来设置 RIL_AUDIO_HANDSET 常量为呼入和呼出同时的设备。如果此函数执 行成功,返回RIL_RESULT_OK

4. 连接管理器通过TAPI RIL_GetAudioMuting()函数来得到静音状态。

5. TSP调用RIL_Call(),使用IOCTL_RIL_DIAL IOCTL。在IOCTL_RIL_DIAL RIL_IOControl会被调用。

6. RIL驱动向无线发送一个拨号命令,无线知道拨号已经初始化。

7. RIL驱动返回对拨号命令的响应RIL_RESULT_OK

8. RIL驱动生成RIL_NOTIFY_CONNECT RIL_CALLTYPE_VOICE 变量。

9. TSP等待呼叫进入RIL_CALLSTAT_ACTIVE 模式时,循环调用RIL_GetCallList()函数。如果此函数调用成功完成,它返回RIL_RESULT_OK和带有以下值的结构体RILCALLINFO Member Value DwID 1 DwDirectionRIL_CALLDIR_OUTGOING DwStatus RIL_CALLSTAT_DIALING or RIL_CALLSTAT_ACTIVEDwType RIL_CALLTYPE_VOICE DwMultiparty RIL_CALL_SINGLEPARTY RaAddress"14255551212" 如果数据连接是活动的,同时用户请求呼出语音呼叫,如果此数据连接不是可挂起/恢复的话连接管理器将请求中断 数据连接,并且在呼出语音呼叫前等待无线关于数据连接的返回。呼出语音呼叫在无线没有断开数据连接时,是不 会呼叫的。如果数据连接是可挂起/恢复的,连接管理器不要求低层做任何事,使数据连接进入挂起状态。

 

--- RIL呼入语音呼叫接收过程 为了接呼入的语音呼叫,蜂窝TSPRIL驱动完成以下步骤:

1. 无线检测呼入呼叫

2. RIL产生RIL_NOTIFY_RING 消息和带有以下值的结构体RILRINGINFO Member ValuedwCallType RIL_CALLTYPE_VOICE dwAddressId 0

3. RIL产生RIL_NOTIFY_CALLERID 消息和带有以下值的结构体 RILREMOTEPARTYINFOMember Value raAddress "4255551212" dwValidityRIL_REMOTEPARTYINFO_VALID

4. TAPI调用RIL_GetLineStatus()函数得到呼叫状态,返回值RIL_RESULT_OK 和指向RIL_LINESTAT_RINGING 常量的 lpData 参数。此步骤可以发生多次。

5. 连接管理器请求TAPI RIL_GetAudioMuting()函数得到静音状态,返回值是RIL_RESULT_OK(FALSE: 非静音)。此步骤可以发生多次。

6. TAPI调用RIL_GetCallList()函数得到有效的呼叫列表。此步骤可以发生多次。返回值是RIL_RESULT_OK 指向带有以下值的结构体 RILCALLINFO lpData Member Value dwID 1dwDirection RIL_CALLDIR_INCOMING dwStatus RIL_CALLSTAT_INCOMING dwTypeRIL_CALLTYPE_VOICE dwMultiparty RIL_CALL_SINGLEPARTY raAddress"14255551212"

7. 当用户应答时,TAPI调用RIL_Answer()函数。

8. 无线应答此呼叫。

9. RIL驱动返回RIL_RESULT_OK 值为空的lpData 做为应答指令。

10. RIL驱动产生RIL_NOTIFY_CONNECT RIL_CALLTYPE_VOICE 常量。

11. TSP调用 RIL_SetAudioDevices()函数设置RIL_AUDIO_HANDSET 使用设备具有输入/输出音频。返回值是 RIL_RESULT_OK

12. TAPI调用RIL_GetLineStatus()函数来确保呼叫已经被应答。返回值是RIL_RESULT_OK 和指向 RIL_LINESTAT_CALLINPROGRESS 常量的指针lpData 当数据连接活动时,连接管理器通过TAPI接收到来电通知,在接受收电前连接管理器请求断开数据连接并且等待无线返回断开的响应。如果数据连接没有断开,则来电不能到达。如果数据连接具有挂起/恢复能力,无线将便数据连 接进入挂起状态。 通常情况下如果语音呼叫已经初始化,同时一个低优先级的连接是不能建立的。但是在特定的条件下也可能发生,如在来电到达连接管理器的通知前,数据连接被请求。这种情况下,当两种连接不能同时建立,数据连接被拒绝, 合理的语音呼叫被支持。另一种可接受的动作是拒绝语音呼叫和数据连接,但是这可能引起用户不好的感觉。 一些程序可能直接请求无线连接,而不通过连接管理器。如果请求的连接使用无线资源,连接管理器将检测到此连 接,并且保持一个内部伪装的连接对象,它具有比数据连接更高的、但低于连接管理器中语音连接的优先级。从而 ,如果请求一个语音呼叫,此伪装的连接将会被连接连接器断开,一量此伪装的连接被检测到断开,语音呼叫将被 建立。

 

--- RIL语音呼叫断开过程 挂掉RIL语音呼叫或远程断开连接,蜂窝TSPRIL驱动将完成以下步骤:

1. 无线检测到远程断开,然后产生lpData带有值为RIL_DISCINIT_REMOTE RIL_NOTIFY_DISCONNECT 常量。

2. TAPI调用 RIL_GetCallList()函数决定改变哪个呼叫的状态。返回值为RIL_RESULT_OK,且lpData 的值为空。

3. TSP调用 RIL_SetAudioDevices()函数设置RIL_AUDIO_NONE ,使设备具有音频输入和输出功能。返回值为 RIL_RESULT_OK

4. 连接管理器通过调用 RIL_GetAudioMuting()函数得到静音的状态,返回值是RIL_RESULT_OK(TRUE:静音)

 


--- 使用RIL发起RAS呼叫(RAS:RemoteAccess System,远程访问服务) 在建立RAS呼叫时使用RIL,蜂窝TSPRIL驱动须完成以下步骤:

1. TAPI调用 RIL_SetBearerServiceOptions()函数,带结构体RILBEARERSVCINFO,根据结构体RASDEVINFO 设置承 载业务。以下列出典型的RILBEARERSVCINFO的值: RIL_SPEED_9600_V32 RIL_BSVCNAME_DATACIRCUIT_ASYNC_UDI_MODEMRIL_BSVCCE_NONTRANSPARENT 返回值是RIL_RESULT_OK

2. TAPI调用 RIL_Dial()函数,参数设置为:"T14255551212",RIL_CALLTYPE_DATA, RIL_DIALOPT_NONE

3. RIL驱动产生RIL_NOTIFY_DATASVCNEGOTIATED 通知,它的lpData 指结构体 RILSERVICEINFO,设置为异步、不透 明。这样,系统忽略此通知。

4. RIL驱动产生RIL_NOTIFY_CONNECT 通知,它的lpData 指向成员dwCallType 被设置为RIL_CALLTYPE_DATA dwBaudRate 被设置为9600 (或连接的实际速率)的结构体RILCONNECTINFO

5. 对于拨号命令,驱动返回RIL_RESULT_OK lpData 的值为 NULL

6. RAS打开数据端口,开始点对点(PPP)协商。

7. TAPI调用 RIL_GetCallList()函数确认呼叫是活动的。本步可多次发生。返回值是RIL_RESULT_OK,它有lpData 指向于带有下列值的结构体RILCALLINFO Member ValuedwID 1 dwDirection RIL_CALLDIR_OUTGOING dwStatus RIL_CALLSTAT_ACTIVE dwTypeRIL_CALLTYPE_DATA dwMultiparty RIL_CALL_SINGLEPARTY raAddress"14255551212" ------ (未完,待续......) RIL注册表部分 RIL驱动安全性 RIL参考

所有的AT指令都是异步的,CommandThread负责串行的下命令,
ResponseThread负责统一处理读上来的串口数据,包括回应和事件。

->rilmain.cpp的RIL_IOControl()
->msg.cpp的RIL_DeleteMsg()
  构造CNotificationData(pnd),设置Blob(Code,Index)
->atcmd.cpp的QueueCmd(,szCmd,,,,pnd,)
->atcmd.cpp的QueueCmdWithTimeout()
  构造CCommand(pCmd),传入szCmd和pnd
  把pCmd放入CRilInstanceHandle的m_pCmdList中
  把pCmd放入g_pCmdQ队列中,唤醒CommandThread

->atcmd.cpp的CRilHandle::CommandThread()
->comhand.cpp的CComHandle::SendRILCmdHandleRsp()
  ->rilhand.h的CRilHandle::StartWaitingForRsp()
    设置m_fWaitingForRsp=1 和 m_pCurrCommand=pCmd
  ->comhand.cpp的CComHandle::WriteCmdsToComPort()
    写串口
  读取g_pRspQ队列的回应信息(pRsp),由ResponseThread写入
  ->rilhand.h的CRilHandle::StopWaitingForRsp()
    设置m_fWaitingForRsp=0
  ->rilhand.cpp的CRilHandle::HandleRsp(rpCmd,pRsp)
    ->response.cpp的CResponse::ParseOKData()
      假如当初注册了ParseFunc()则释放原来的Blob,回调具体的处理函数
    取出最初的pnd
      ->rilhand.cpp的CRilHandle::BroadcastNotification(pnd)
    取出Blob
      ->command.cpp的CCommand::SendResponse(Code,Blob)
        假如当初没有设置CMDOPT_IGNORERSP的命令选项
          ->CRilInstanceHandle::Notify(Code,ID,Blob)
          ->把pCmd从CRilInstanceHandle的m_pCmdList中移除

->atcmd.cpp的CRilHandle::ResponseThread()
->atcmd.cpp的CRilHandle::HandleRxData()
  ->AppendReadBytes()把串口数据放入缓冲区
  ->GiveUpReadBytes()获得全部的新老串口数据
  构造CResponse
  ->response.cpp的CResponse::AppendString()
    ->response.cpp的CResponse::Parse()
      ->事件->response.cpp的CResponse::ParseNotification()
      ->结果->response.cpp的CResponse::ParseOKOrError()
    回应不完整则szRemainder和cbRemainder=0,否则等于下一个回应和长度
  假如pRsp->FUnsolicited==0,也就是Unsolicited Result Code(非请求结果码)
    假如FWaitingForRsp==1,调用atcmd.cpp的QueueRsp()唤醒CommandThread
  假如是URC,pRsp->GetBlob()然后BroadcastRealBlobNotification()
  剩下的串口数据调用AppendReadBytes(),重新开始一轮处理

最简单的AT指令,也就是只返回"OK",上面的处理过程很简单。

CRilHandle有内部缓冲区用来存放新老串口数据(例如上次没读完整),,
所以一进HandleRxData()就先AppendReadBytes()然后GiveUpReadBytes()

每个pRsp也有内部缓冲区,存放完整的回应数据。

对于有具体返回值的AT指令,例如AT+CSQ,
在misc.cpp的RILDrv_GetSignalQuality()调用QueueCmd()时,
注册ParseGetSignalQuality()作为而外的处理函数,
在CommandThread的HandleRsp()的ParseOKData()中被调用。
ParseGetSignalQuality()会分析回应数据,来构造新的Blob,
然后通过Blob通知调用者结果。

RIL应用程序一开始调用RIL_Initialize()会注册2个回调函数
pfnResult和pfnNotify,前者接收命令结果,后者接收事件(例如RING)。

有的AT指令会构造pnd传给QueueCmd,例如RILDrv_DeleteMsg(),
有的没有pnd,例如RILDrv_GetSignalQuality()。
前者在CommandThread的HandleRsp()结尾BroadcastNotification(pnd)。

"ATD"(呼出)有点麻烦,对方接起后才返回"OK",在此之前可能主叫方挂断,
也就是"ATD"在有回应之前下"ATH"指令。

因此comhand.cpp的CComHandle::SendRILCmdHandleRsp中对"ATD"和"ATA"有特殊处理,
启动专门的线程HangupThreadProc处理"ATH"。
->HangupThreadProc()
  情况1:"ATD"/"ATA"指令还没下给串口
    从g_pCmdQ中移走pCmd
    pCmd->SendResponse(RIL_RESULT_NOCARRIER,NULL,0);
  情况2:已经下给了串口
    假如g_pCmdQ的下个命令是"ATH",因为g_pCmdQ是CPriorityQueue,"ATH"会排在最前
      m_fCancelledDial=1
      写"AT"到串口

对于上述情况2
comhand.cpp的CComHandle::SendRILCmdHandleRsp()
在获得pRsp("AT"的返回值"OK")后,判断m_fCancelledDial==1
调用pRsp->SetCallAborted()把"OK"的RESULT换成"NOCARRIER",此后按原流程处理。
"ATH"的指令未被丢弃,随后会再次发出,来防止对方"ATA"发生在"ATD"被取消的同时。

假如有模块的"ATD"直接返回"OK",那就不需要线程HangupThreadProc,
把RILDrv_Dial()的pnd去掉,不然收到"OK"就会BroadcastNotification(RIL_NOTIFY_CONNECT)。
另外response.cpp的CResponse::ParseNotification()可能也得加点东西。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值