MMI后台实现后,一直没有考虑如何通过多路复用协议和
GSM模组通讯,使得可以在通过
GPRS拨号上网时可以同时拨打电话和收发短信。在网上无意中发现了
motorola的多路复用实现,看了一下,觉得不大好。
motorola在
linux下实现多路复用协议的方法是通过实现一个内核模块,在该内核模块实现了多路复用协议,并创建了多个
tty设备给用户空间的程序使用,每个
tty设备是多路复用的一个虚拟通路。这样
MMI后台可以使用不同的
tty设备实现和
GSM模
组的多路通讯。这种方法在使用上有几个不好的地方,首先是将其实现为一个内核模块,增加了编译时的麻烦,而且当内核升级后,该内核模块就无法编译通过了,
需要修改源代码。第二是不好查看打印信息,只有控制台才能看到内核模块的打印信息,在远程登录的终端上是看不到的,而远程登录是常用的工作方式。第三是不
好控制模组的激活和关闭,多路复用的内核模块和用户空间的进程
(MMI后台
)通讯不方便。
看来在用户空间实现多路复用协议,并将其实现为一个独立的后台进程倒是一个不错的方法。但如何在用户空间实现一个tty设备呢,可以用伪终端技术来实现。伪终端是BSD UNIX提出并实现的一个虚拟终端设备的技术,其特点是可以在用户空间创建一个虚拟tty设备,供其他使用tty设备的进程使用,使该进程认为是和真实的tty设备交互,实际上却可能是通过网络接口和远程计算机通讯。伪终端技术通过在内核实现虚拟设备向用户空间提供了一对伪终端设备,分别是伪终端主设备和伪终端从设备。伪终端从设备就是虚拟tty设备,伪终端主设备则由实际的通讯进程使用,可以是socket通讯进程,串口通讯进程。使用tty设备的进程向伪终端从设备写入的数据,则可以从伪终端主设备读到,实际的通讯进程向伪终端主设备写入的数据,则可以从伪终端从设备读到,从而实现了将一个实际的网络通讯伪装为与tty设备的通讯。
伪终端的使用步骤如下所示。
int fdm fds;
char *slavename;
extern char *ptsname();
fdm = open("/dev/ptmx", O_RDWR); /**//* open master */
grantpt(fdm); /**//* change permission of slave */
unlockpt(fdm); /**//* unlock slave */
slavename = ptsname(fdm); /**//* get name of slave */
fds = open(slavename, O_RDWR); /**//* open slave */
ioctl(fds, I_PUSH, "ptem"); /**//* push ptem */
ioctl(fds, I_PUSH, "ldterm"); /**//* push ldterm */
通过函数
open()打开设备“
/dev/ptmx”,可以得到一对伪终端的主从设备,得到的
fd是主设备的文件描述符,从设备的设备名可以通过函数
ptsname()得到,用
open()函数打开从设备名的设备,即可得到从设备的文件描述符。但此时从设备还不能打开,需要调用函数
grantpt()接受从设备,修改从设备的访问权限,调用函数
unlockpt()解锁从设备,才能够打开从设备。
ptsname(),
grantpt(),
unlockpt()这几个函数的具体作用大家可以通过
man命令查看。
因此,可以创建一个实现了多路复用协议的独立后台进程,由其为每个虚拟串口创建一个虚拟tty设备,供MMI后台和PPPD进程使用。MMI后台和PPD进程使用不同的虚拟tty设备,以实现同时进行GPRS拨号上网和拨打电话、收发短信的功能。具体做法是,多路复用的后台进程通过三次打开“/dev/ptmx”设备,得到三对伪终端的主从设备。然后调用函数grantpt()和unlockpt()使得从设备可用,通过函数ptsname()得到从设备的设备名。在指定的虚拟tty设备名和实际得到的从设备名之间建立一个符号链接,MMI后台和PPPD进程就可以打开指定的虚拟tty设备通过多路复用协议和模组进行通讯了。
具体的实现方法和代码可以参考如下的链接。
http://developer.berlios.de/projects/gsmmux/
参考文档:
1.伪终端驱动-ptm和pts,。
2.多路复用协议的实现,http://developer.berlios.de/projects/gsmmux/。
阅读(1280) | 评论(0) | 转发(0) |