看来在用户空间实现多路复用协议,并将其实现为一个独立的后台进程倒是一个不错的方法。但如何在用户空间实现一个tty设备呢,可以用伪终端技术来实现。伪终端是BSD UNIX提出并实现的一个虚拟终端设备的技术,其特点是可以在用户空间创建一个虚拟tty设备,供其他使用tty设备的进程使用,使该进程认为是和真实的tty设备交互,实际上却可能是通过网络接口和远程计算机通讯。伪终端技术通过在内核实现虚拟设备向用户空间提供了一对伪终端设备,分别是伪终端主设备和伪终端从设备。伪终端从设备就是虚拟tty设备,伪终端主设备则由实际的通讯进程使用,可以是socket通讯进程,串口通讯进程。使用tty设备的进程向伪终端从设备写入的数据,则可以从伪终端主设备读到,实际的通讯进程向伪终端主设备写入的数据,则可以从伪终端从设备读到,从而实现了将一个实际的网络通讯伪装为与tty设备的通讯。
伪终端的使用步骤如下所示。
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 */
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
通过函数 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,Pseudo-tty drivers -- ptm and pts。
2.多路复用协议的实现,http://developer.berlios.de/projects/gsmmux/。