偷得浮生半桶水(半日闲), 好记性不如抄下来(烂笔头). 信息爆炸的时代, 学习是一项持续的工作.
全部博文(1750)
分类: LINUX
2009-05-05 16:29:00
1 ts27.010协议介绍
在常用的gsm/gprs通信模块中(如siemens的mc35mc35、wavecom的q2400q2400等),只能通过一个普通9针的异 步串口与终端设备te(terminal equipment)进行通信。te和ms?mobile station 需要通过这个串口交换各种类型的数据,例如:语音、传真、数据、sms、cbs、电话号码本的维护、电池状态、gprs、ussd等。如 何在一个串口上同时支持这么多的业务?例如,在数据通信过程中,怎样发送或接收sms?为了解决这些问题,3gpp提出了一个协议--ts27.010协 议(terminal equipment to mobile station multiplexer protocol)。有了multiplexer,即使在数据连接过程中,也可以发送sms。其它业务组合也可以同时进行。例如,数字语音和sms同时发 送。multiplexer的存在使得一个完整的系统能够根据需要进行划分。
3gpp 的multiplexer设计非常灵活,并且独立于ms/te平台,已有的应用程序不需要改动即可工作。在设计multiplexer时,特别考虑到采用 电池供电的设备的需求,所以包含了省电模式控制等很重要的功能,并且multiplexer本身在运行时也尽量使用最小的功耗和内存。
multiplexer基于iso的hdlc标准设计,工作于有多种选项的单模式下。但是basic option并不遵从hdlc。在基本选项模式下,multiplexer没有透明机制,也没有错误恢复功能。但是在高级选项(advanced option)模式下,使用hdlc的透明机制,且multiplexer有一个方便的再同步机制,能够在dc1/dc3(xon/xoff)流控打开的 链路上工作,且包含了错误恢复功能。
3gpp的multiplexer依赖于一个控制信道。在这个控制信道上,te和ms交换控制信息,例如参数协商、节电控制信息、流控信息等。 multiplexer是一个可选项,如果支持这个功能,就应使用at+cmux命令激活它。 multiplexer为te和ms在一个起始/停止模式的、具有分帧功能的串行链路上传输数据流提供了一套机制。图1给出了不同的协议层及其功能示意。 multiplexer层负责将数据按字节流的方式传输,不再进行进一步的组帧;如果数据需要按一定结构传输,就需要增加一个会聚层来完成这些功能。
multiplexer为te上的进程和ms上相对应的进程提供了一条虚连接,这样te和ms上的进程就可以通过这条虚连接通信。例如,te上的 sms应用程序可以通过一条multiplexer通道与ms上的sms处理程序连接起来。 ts27.010规范使用8bit字符的start-stop传输模式,两个mulitplexer实体间的通信使用了规定的帧格式。te和ms之间的每 个信道称为一条数据链路连接dlc(data link connection),这些dlc被依次独立地建立起来。每个dlc都可以有自己的流控机制。
multiplexer有三种工作模式:basic、advanced without error recovery和advanced with error recovery。这三种模式特点如下:
·basic:长度标识代替hdlc的透明机制;使用与hdlc不同的标志字;不能用于具有xon/xoff流控的链路;从同步丢失状态中恢复需要更长的时间。
·advanced without error recovery:遵从iso/iec13239的异步hdlc过程;可以用于具备xon/xoff流控的链路上;可以更快地从失同步状态恢复。
·advanced with error recovery:使用了hdlc的错误恢复过程。
2 wavecom gsm/gprs模块multiplexing协议介绍 笔者选用了wavecom的q2403a,这是一款e-gsm/gprs 900/1800的双频模块。这个模块支持大部分常用的at命令,但不支持标准的ts27.010协议。为了能够数据/命令复用,wavecom定义了自 己的multiplex协议。
wavecom的复用协议允许一条串行链路上同时进行两个会话(即虚连接):一个at命令的会话和一个数据通信的会话。at+wmux=1将激活模块的复用模式。在这种模式下,at命令和数据都被封装成数据包。通过包头,可以区分是数据包还是at命令包。
2.1 at命令包格式
at命令包帧格式如图2所示。第一个字节?0xaa 用于标识这是一个命令包,第二个字节是at命令长度的低八位。第三个字节由两部分组成:低3位
是at命令长度的高3位;高3位用于标识一个at命令。at命令的最大长度可以为2047字节。校验和(checksum)是包中所有字节(包括头和at
命令)之和对256取模。
2.2 数据包格式
数据包各个字段(除packet type外)意义与at命令包相同,其帧格式如图3所示。数据包有以下几种类型:
·type=0--data 包:这个包是发送到无线链路上或者从无线链路上接收到的数据
·type=1--status包:这个包给出了sa、sb、x和中断条件编码的信息。
状态包的长度总为1字节。任何一个状态(除了break)改变时,所有的状态位都要发送出去。缺省情况下,所有的状态位都是关闭的(因此dtr、rts都是关闭的),所以在打开复用开关准备传送数据之前,一定要发送一个状态包。
·type=2--ready包:这个包表示发送ready包的一方可以接收数据了。包中没有数据,所以长度字段为0。
·type=3--busy 包:这个包表示发送ready包的一方忙,无法接收数据。包中没有数据。
3 linux下串口通信系统的组成
要在linux系统上实现ts27.010协议,就必须了解linux下串口驱动软件模块的结构。
图4不但给出了linux kernel中串口通信模块的组成结构,还形象地表示出了数据是如何在用户和硬件接口之间流动的(笔者使用linux
2.4.19的内核)。从图4可以看到串口通信模块可在逻辑上分为三层:tty层、line
discipline层和底层驱动层。tty层是用户空间和内核空间的桥梁,用户程序和内核需要通过tty层交换数据;low-level
driver则负责硬件的交互,它对硬件进行控制和读写操作;line
discipline层是整个串行通信模块中最灵活、设计最巧妙的一层,它要为一个串行口的使用定下数据交互的"规程",在linux内核中已经存在了许
多line discipline,例如ppp、slip、tty等。缺省使用tty line discipline。可以根据需要将line
discipline替换成linux已经定义的line discipline结构,甚至替换为自己的line discipline结构。
在图4中,向硬件接口写数据的过程是显而易见的。但是,用户程序从硬件读取数据的过程却要复杂一些,这是因为硬件与用户空间之间没有直接的联系。解决的办
法就是使用缓冲技术,硬件接收数据存储于kernel
buffer中,等待用户程序请求这些数据;如果用户程序请求数据时,这个buffer是空的,那么用户程序就会被挂起,直到buffer中有数据时,它
才被唤醒。实际上,tty相关的缓冲是由两级构成的:一个"常规"buffer(数据等待着line
discpline取走,缺省情况下传到用户空间)和一个"flip"buffer(硬件驱动函数将底层进来的数据尽可能快地存入这个缓冲,而不必考虑并
发存取问题,因为这个buffer是每个硬件驱动专有的)。flip
buffer由两个物理的缓冲实现,并被交替地写入,这样中断处理函数就会总有一个缓冲可用。
linux下串口软件的这种分层结构虽然增加了复杂性,但是它带来的好处是多方面的。第一,串口模块更加灵活,在为新的串口硬件编写驱动程序时,只
需修改和增加最底层的软件即可;第二,上层应用程序可以根据需要改变line
discipline的处理软件,在使用ppp、slip等协议进行拨号连接时,都需要将原有的line
discipline替换为ppp或者slip协议本身的line
discipline?第三,可以根据需要,在层与层之间加入一层自己的处理软件。事实上,笔者在实现multiplex协议时正是这样做的。
4 multiplexing协议的实现
4.1 协议实现时的考虑
在实现ts27.010协议时,基于以下考虑:第一,使用串口的上层应用程序不需要改动。这一点很重要,因为系统中有许多用户程序使用串口进行通
信。如果需要对它们进行改动,那么由此付出的代价显然是不值得的。在这一点上,尤其需要特别考虑ppp软件,因为在linux下通过gprs上网必须使用
ppp协议进行拨号。ppp存在于用户空间和内核空间两个地方,用户空间的pppd应用程序完成拨号连接的管理功能;内核空间的ppp协议软件实现ppp
包的组帧/分帧等核心功能。ppp定义了自己的line
discipline模块,且到此为止,往下就不再有ppp相关的软件模块(参看图4的分层结构)。第二,尽可能多地实现ts27.010协议。虽然这个
协议的内容很丰富,但是由于wavecom通信模块只支持有限的几种格式,并且帧头部分还略有不同。这样实现起来就存在许多困难,只能在保证实现
wavecom复用协议并可靠工作的前提下,尽量实现ts27.010协议,以便于以后硬件和软件的升级。
4.2 mux driver的实现方案
正是基于以上两点考虑,决定将这个协议的实现放在line discipline和low-level driver两层之间,参看图5。这样,不需要对linux的tcp/ip协议栈软件和ppp软件作任何修改,就可以在复用模式下实现原有的无线上网功能。
图5给出了mux模块的函数调用和数据流程。tty layer、line discipline和serial driver是linux tty设备文件系统在内核中已有的三层,在前一节已经介绍。
正如笔者在实现ts27.010协议时所考虑的,为了不影响上层应用程序,mux必须支持标准的linux系统调用,如write()、 read()、ioctl()等。write()如果成功,则返回发送的字节数;如果失败则返回-1,并将errno(linux系统下一个全局变量,用 户接口可以根据这个值判断错误类型)置为合适的值。正如图5所示,write()并不是将数据直接发送出去,要发送的数据首先按照ts27.010协议的 要求(笔者使用wavecom模块,它有自己的协议要求)组成mux帧?然后根据数据的优先级排队,优先级高的数据首先被发送。 同样,对设备/dev/muxn(0<n<m=的标准的linux调用read()也不是由mux直接支持的。mux不会知道一个用户应用程序何时读设备 /dev/muxn(0<n<m=。read()功能由mux的上层(主要是tty层)支持。mux根据ts27.010协议(或者wavecom协议) 将物理链路上接收到的mux包解封装,然后将纯数据发送到设备/dev/muxn(0<n<m=的读缓冲区中。如果设备/dev/muxn(0<n<m) 没有足够的读缓冲空间,mux就会将数据放到自己的接收缓冲区中。 4.3 wavecom复用协议特殊情况的处理
在实现ts27.010协议时,考虑到wavecom协议的特殊情况,在完全实现wavecom复用功能的同时,尽可能多地实现ts27.010协 议。由于wavecom只能同时支持两个虚连接,所以这里的m=2。其中,/dev/mux0用于at命令,作为控制信息通道;/dev/mux1用于 ppp连接,作为数据通道。作为wavecom复用协议的一个严重缺陷,从图2、图3的帧结构可以看到,从串行链路提交来的数据只能区分出是at command数据还是data数据,而无法确定链路的信息,即无法确定数据是mux0接收,还是mux1接收。为了解决这个问题,笔者在实现时,将底层 提交的数据同时送给mux0和mux1?如果这两个设备都已经打开 。但是考虑到软件的效率和数据的可靠性,在向上层提交数据时,有以下两点例外:第 一,mux1是ppp专用的,在ppp没起来之前,mux1可以作为at命令通道,但是ppp连接成功后(ppp的line discipline已经替换掉了缺省的tty line discipline),它将不再接收at命令,所以此时底层提交的at命令帧不会送给mux1?第二,mux0作为at命令通道,将不接收ppp数据, 所以在ppp连接成功后,不会把0x7e开始和0x7e结束?ppp的帧同步标志字节 的data帧发送到mux1。
gprs网络作为一种过渡性质的2.5g网络,覆盖日益广泛。由于它的速率高、实时性好、费用低廉等诸多优势,日益被手持/车载等移动终端设备采 用。在使用gprs网络传输数据的同时,这些设备也必须能支持普通的无线业务,如语音、短消息等。ts 27.010协议很好地解决了这些业务的复用问题。笔者开发的这套linux上的multiplexing软件实现了这些功能,使得移动终端能够在ppp 连接不断开的情况下,可以打出/接听电话、发送/接收短消息。