具体实施方式
下面参照附图详细说明本发明的技术方案。
如图1所示,为了实现上述发明目的,本发明提供一种图形终端环境中的分布式设备重定向系统,主要包括虚拟驱动模块、服务代理模块和终端代理模块,通过“应用→虚拟驱动模块→服务代理模块→终端代理模块→终端设备驱动→终端设备”的通道,将应用对设备的访问逻辑反映到终端设备上,并按照原通道的逆返回,实现设备重定向,满足多用户终端网络环境中的设备支持需要。
更具体地说,设备重定向系统包括虚拟驱动模块,支持注册/注销、监听端口和设备文件操作接口,基于重定向协议,实现与服务代理模块间的数据通信。其中,虚拟驱动模块又包括:
注册接口单元,注册的主次设备号与系统标准设备的设备号一致,根据实际的设备需要,注册多个次设备,满足扩展性要求。注册接口提供内核空间多线程支持,在新线程中提供端口监听功能。
端口监听单元,建立虚拟驱动到服务代理的重定向通道,完成通信端口的建立和监听。虚拟驱动接收服务代理发来的登陆会话标识sid,并记录sid与通信端口间的对应关系。
设备文件操作接口单元,按照设备打开、设备I/O控制、设备读写和设备关闭的过程支持标准设备访问接口。接口定义符合标准驱动设计原则,满足与标准设备的兼容性要求。
设备打开接口单元,与服务代理完成应用进程标识pid和会话标识sid的转换,根据结果判定启动应用的用户会话。将打开逻辑描述发送给服务代理,并接受来自服务代理的反馈。
设备I/O控制接口单元,将I/O控制逻辑描述发送给服务代理,并接受来自服务代理的反馈。
设备读接口单元,将读逻辑描述发送给服务代理,并接受来自服务代理的反馈,反馈中包含读设备获取的设备信息。
设备写接口单元,将写逻辑描述发送给服务代理,描述包含向设备写的数据,并接受服务代理的反馈。
设备关闭接口单元,将关闭逻辑描述发送给服务代理,并接受来自服务代理的反馈。
设备重定向系统还包括服务代理模块,用于实现多用户登陆支持,监视登陆用户情况,判断启动应用的用户;实现服务代理模块与虚拟驱动模块以及服务代理模块与终端代理模块间的通信接口和协议描述。其中,服务代理模块包括:
多线程管理单元,监听并管理多个终端用户登陆的会话环境。共享内存单元,记录用户会话标识。
“服务代理模块—虚拟驱动模块”通信接口单元,交互用户会话标识和应用进程标识,构建服务代理模块与虚拟驱动模块间的设备重定向通道,透明地实现两者间设备访问逻辑的传输。
“服务代理模块—终端代理模块”通信接口单元,构建服务代理模块与终端代理模块间的设备重定向通道,透明地实现两者间设备访问逻辑的传输。
设备重定向系统还包括终端代理模块,发送用户登陆请求,实现与服务代理模块间的通信接口和协议描述,解析设备访问逻辑继而操作终端本地设备。其中,终端代理模块包括:
“终端代理模块—服务代理模块”通信接口单元,发送登陆请求,构建终端代理模块与服务代理模块间的设备重定向通道。
访问逻辑解析单元,分析出不同的访问逻辑描述。
设备访问单元,根据解析结果访问终端本地设备,完成终端用户启动的应用程序执行的设备打开、I/O控制、设备读写和关闭操作,并将设备访问的反馈回传服务代理。
下面结合附图,首先对本发明的实施方式作功能描述,然后结合音频设备重定向的开发实例,详细描述设备重定向的信息交互过程。
虚拟驱动模块的设计与实现:
在图形终端应用中,应用服务器上的虚拟驱动通过内核或者模块方式运行,并监听来自终端服务代理的请求。用户如果未运行音频应用,则虚拟驱动和终端服务代理间的通信状态不变;如果用户运行服务器上的音频应用,则访问逻辑按照应用的描述执行。
虚拟驱动的注册/注销的实现遵循标准驱动设计,接口为init_module()和cleanup_module(),注册的主次设备号与系统标准设备的设备号一致,通过devfs_register_dev()和devfs_mk_dir()函数完成,满足服务器端设备描述一致性要求。
本发明的虚拟驱动通过kernel_thread(),启动监听线程,监听与服务代理之间的通信端口。监听过程如图所示。监听线程等待来自服务代理的连接请求,以便获取登陆或注销的会话信息。服务代理的请求格式为“会话描述+会话标识”。登陆和注销会话分别由“CN”和“DS”表示。虚拟驱动获取会话标识sid,对登陆会话将sid与通信端口间的对应关系记录到系统列表中,以备后用;对注销会话,将其和对应通信端口信息从列表中删除。
应用对设备的操作按照设备打开、设备I/O控制、设备读写和设备关闭的顺序进行。应用对设备的操作在驱动中通过设备文件操作接口file_operations结构定义实现。虚拟驱动主要通过“应用→虚拟驱动→服务代理→终端代理→终端设备驱动→终端设备”的通道,将应用对设备的访问逻辑反映到终端设备上,并按照原通道的逆返回。值得注意的是,每种访问逻辑都包含操作码和操作数,分别描述操作命令和操作对象。上述通信过程具有透明性,这种透明性一直保持在上述通信过程的始终,中间的虚拟驱动和各个代理并不关心命令的细节。分析工作在终端代理的最后进行。终端代理解析操作码和操作数,并根据结果通过标准的调用接口完成真正设备的I/O控制操作。
本发明通过虚拟驱动在内核中注册的打开设备接口,获取音频应用的进程标识pid,通过虚拟驱动与终端服务代理间的数据通信,将pid传至服务代理,并在代理上获得音频应用的启动用户会话标识sid,并返回驱动。合法的sid返回表明音频应用由合法终端登陆用户执行,查找sid与通信端口关系对照列表,获得与相应会话的通信端口,此时建立了用户和应用间的对应关系,服务于之后的不同会话进程数据的分离。过程如图2所示。同时,向应用返回正常打开信息。
应用在打开设备之后,需要通过设备I/O控制接口ioctl操作,对设备的I/O属性进行设置、获取和修改。I/O控制是设备驱动程序中较为复杂的操作,接口定义包含命令字(操作码)和参数(操作数)。本发明中应用在进行设备I/O控制操作时,虚拟驱动只是从系统调用接口得到应用程序使用的控制命令字并进行分析,针对操作码通过宏定义_IOC_DIR()获得操作类型是NONE、OUT、IN或者INOUT型命令,分别对应不带参数,设置参数,读取参数,协商参数四种类型,然后分别调用相应的处理过程,利用协议交互部分完成其功能,将应用对设备的I/O控制重定向到终端设备上。
在设备操作中,读写操作是发生最为频繁的操作,一般都处于应用程序的循环逻辑中。读写操作具有两个显著特点:一是操作数部分庞大,往往传递的是缓冲区指针;二是读写的状态需要返回,影响返回状态的因素较多。本发明在设计读写操作的通信协议时,操作数据缓冲区部分往往采用不定长方式,并配以长度字节描述实际缓冲区的大小。返回状态完全依赖于对终端设备实际操作的反馈。
本发明的关闭设备操作通过虚拟驱动模块与服务代理模块间定义的重定向协议,透明地传递给服务代理。
服务代理模块的设计和实现:
本发明中,服务代理模块主要包括信息发送和接收接口。信息发送接口实现从虚拟驱动接收各种请求,并重新打包成服务——终端代理间的协议格式(主要是字节序不同),将请求转发到客户端代理;信息接收接口从客户端代理接收各种应答,并重新打包成服务代理与虚拟驱动间的协议格式(主要是字节序不同),发往虚拟驱动。
终端代理模块的设计和实现
本发明中,客户端代理部分提供相应于服务代理模块收发的协议交互部分。此外,需要根据服务代理通知的访问逻辑描述,设计实现对本地设备的访问。对本地设备的访问采用标准的设备操作接口,操作结果的反馈需要返回给终端服务代理。
4、通信协议的设计和实现,即重定向协议的设计和实现:
包括三部分:设备发现、设备描述和设备访问。
设备发现主要实现对终端现有设备的发现、通知和反馈。某些设备在终端加电之初就已经存在并生效,比如键盘/鼠标、三卡(显卡、网卡和声卡)等。这些设备在用户登陆终端服务时就会通知服务代理并在服务端记录;而有些设备支持即插即用功能,USB设备就是如此。诸如此类的设备可能在用户登陆之前或之后与终端连接并通知终端服务。无论上述哪种情况,协议均需要向终端服务描述设备发现消息,并将终端服务的反馈描述返回至终端代理。
设备描述,设备一旦被发现,就需要终端能够向服务端提供设备的具体描述信息。描述信息至少应当包括设备类型、设备描述符、设备能力描述。
终端设备大致分为两类:字符设备和块设备。字符设备的输入/输出以字节为单位,而块设备的输入/输出以记录块或“扇区”为单位。通过数十年的发展,块设备和字符设备之间的界限已经模糊了,但还是沿用着这样的划分。
设备描述符主要是用于区分终端上的具体设备,可以直接采用终端设备描述符,比如音频设备可用dsp、mixer等,磁盘设备可用hda、sda等;也可以采用主次设备号描述,主次设备号的分配按照终端操作系统的设备的主次设备号描述,比如音频设备的dsp和mixer的主次设备号分别为14/3和14/0等。
设备能力描述是设备相关辅助信息,依赖于具体的设备,描述设备的当前I/O能力、使用状态等。设备能力描述也是服务于今后终端设备自适应能力支持的需要。
设备访问,在发明申请中主要介绍的是这部分的实现,描述设备的打开、I/O控制、读写和关闭逻辑。
本发明中,代理模块间的通信协议包括服务到终端的请求和终端到服务的响应两部分。分别描述如下:
1)请求数据包格式如表1所示:
表1 虚拟驱动到终端的数据包格式
长度 | 操作代码 | 参数字段表 |
2字节 | 1字节 | 可变长度 |
其中各字段定义如下:
长度字段:整个数据包的长度。
operations结构中操作的定义中并没有poll项。poll操作用于系统中的select调用,专门用于处理高速CPU和低速的外设操作之间的矛盾。Select系统调用的实质是将系统中单一进程的睡眠等待变成多目标的睡眠等待,提高整个系统的运行效率。如果终端服务进程调用了select系统调用,实际等待的应该是从远程终端上返回的操作,取决于两个因素:终端上的读等待过程和终端将所读结果经过网络传送到虚拟驱动。因此poll的调用实际应该对应于为虚拟驱动程序和终端之间提供数据传输的socket调用。因此在表2中并不需要规定将poll操作传送到终端的操作代码,对于poll操作只需要直接调用相应的socket的poll过程即可。
参数字段:规定相应操作代码的参数格式,具体格式如表3所示。其中参数类型规定此参数中数据的格式,如16位整数、32位整数、字节流等。只有当参数数据类型为字节流时,参数结构中才有参数长度字段。随后的参数值字段为实际的参数值。
表3 参数格式
参数类型 | 参数长度 | 参数值 |
1字节 | 2字节 | 可变长度 |
2)响应数据包格式如表4所示:
表4 终端设备操作响应
成功标记 | 长度 | 参数字段表 |
1字节 | 2字节 | 可变长度 |
其中各字段的意义如下:
成功标记:表示由应用发起的访问请求在终端实际设备上的执行结果,值为1表示执行成功,否则表示在执行过程中出错。
长度字段:表示后面的数据的总长度。
参数字段:具体格式如表所示。为此次操作的返回值或可选参数。
如图3所示,本发明的重定向方法包括以下步骤:
步骤100,加载虚拟驱动;
步骤110,启动服务代理,建立与虚拟驱动的连接;
步骤120,用户远程登陆(此时,通过服务代理,在虚拟驱动中记录会话标识sid与通信端口间的关系);
步骤130,用户在终端应用环境中启动应用;
步骤140,应用向虚拟驱动发出设备访问请求,形成设备访问逻辑;
步骤150,设备访问逻辑通过虚拟驱动传给服务代理;
步骤150,设备访问逻辑通过虚拟驱动传给服务代理;
步骤160,设备访问逻辑通过服务代理传给终端代理;
步骤170,终端代理解析访问逻辑,并实现本地设备访问;
设备访问的反馈由上述路线返回;
如图4所示,虚拟驱动的实现流程包括以下步骤:
步骤200,应用系统调用;
步骤210,判断系统调用的种类,如果系统调用为open调用,则执行下一步,如果系统调用为ioctl调用,则执行步骤230,如果为其它调用,则执行步骤240;其中,系统调用包括open调用,release调用,read调用,write调用,ioctl调用,poll调用。
步骤220,获取与相应会话通信的端口信息,执行步骤240;
步骤230,判断ioctl类型,并作相应处理,执行步骤240;
步骤240,协议交互;
步骤250,调用返回。
在步骤240中,如图5所示,1—3为访问逻辑映射,4—6为访问反馈。
在图形终端环境中,多媒体应用是一个重要的应用。为了满足对有声应用的支持,在终端网络中更好地支持音频设备,是本发明所研究的设备重定向的重点。
结合上述发明实施过程描述,以音频设备重定向为实施实例,描述本发明所述设备重定向的具体实施过程。随着声音设备硬件的发展和应用的丰富,音频应用需要声卡能够支持MIDI设备、混音器设备等。其中,混音器设备/dev/mixer作为音量调节工具,在多数音频应用中得到广泛应用。本发明具有较好的扩展性,可以支持多种设备描述。混音器的实现原理与传统音频设备完全相同,下面主要介绍针对传统音频设备/dev/dsp的实施实例。
1)用户登陆和注册
虚拟驱动首先以模块方式加载到内核中,在内核的注册过程如上所述。注册完毕启动端口监听线程,监听来自服务代理的信息(此时服务代理尚未启动)。启动服务代理,监听来自终端代理的信息。终端代理发起用户登陆请求,建立与服务代理的连接。对每一个新登陆的用户,服务代理分配用户会话标识sid,启动线程维护与用户的连接和数据通信。在线程中将用户的sid通过请求信息传递给虚拟驱动。虚拟驱动接收到服务代理传来的sid,记录sid与通信端口的关系信息,完成用户登陆和注册过程。
2)应用启动过程
终端用户通过图形接口启动服务上的音频应用程序。音频应用首先通过open命令,操作音频设备文件描述符/dev/dsp,进行音频设备的打开操作,这一操作信息通过内核传递给虚拟驱动的设备文件打开接口dev_open。在此接口中,按照上述过程,将获取到的应用进程标识pid传递给服务代理。服务代理得到pid,通过访问/proc文件系统,获取会话标识sid,并回传给虚拟驱动。虚拟驱动通过记录的sid和通信端口间的关系,获得与音频应用进程对应的会话通信的通信端口。
3)应用对声卡的访问
声卡的I/O控制比较丰富,可以设置和获取许多有关声卡设备属性的信息,以缓冲区信息为例,声卡可以设置和获取缓冲区的大小,这分别对应于上述OUT和IN型命令。应用中对声卡缓冲区设置的接口定义为:
ioctl(int audio_fd,int cmd,char*blocksize)
其中,audio_fd为声卡设备文件号,cmd为命令字,在此为SNDCTL_DSP_GETBLKSIZE,表示此命令需要获取缓冲区大小,blocksize为返回的缓冲区大小。此命令映射到虚拟驱动,虚拟驱动中的操作接口为
dev_ioctl(struct inode*inode,struct file*file,unsigned int cmd,unsigned long arg)
其中cmd对应命令字,arg对应参数。虚拟驱动需要通过_IOC_DIR(cmd)解析命令字的类型,根据类型将命令字和参数的组合透明地传给服务代理。
设置缓冲区大小及其他的I/O控制与上述过程是一样的。
对声卡设备的主要操作是读写声卡。应用对声卡的读写对应于音频录音和回放功能。下面以音频应用写缓冲区的接口为例介绍。音频应用写缓冲区的接口为:
write(int audio_fd,const void*buffer,size_t count)
其中audio_fd为声卡设备文件号,buffer为存储音频数据的缓冲区指针,count以字节为单位表示缓冲区大小。此命令映射到虚拟驱动,虚拟驱动中的操作接口为
dev_write(struct file*file,const char*buffer,size_t count,loff_t*ppos)
其中buffer为接收用户空间音频数据的缓冲区的指针,count为缓冲区大小。音频应用对声卡的写逻辑反映到虚拟驱动,既而透明地传递给服务代理。
音频应用的读逻辑与写逻辑映射过程类似,但数据流方向相反。
4)声卡的关闭
音频应用的设备关闭通过虚拟驱动传递给服务代理。
5)虚拟设备驱动的注销
虚拟驱动一旦加载后,一般不会从内核中注销。为了满足与标准设备驱动的一致性,虚拟驱动提供设备注销接口,通过devfs_unregister_chrdev()和devfs_unregister()实现。
上述介绍的是本发明的核心——虚拟设备驱动的实施实例。服务代理、终端代理与虚拟设备驱动共同构成了设备重定向的通信通道,实施的关键是通信协议的定义。下面以音频应用发生最频繁的音频数据写为例,介绍服务和终端代理间的通信协议。
服务代理接收到虚拟驱动的写操作命令后,按照代理间定义的设备重定向协议,组织数据包,发送给终端代理。例如如果每次写操作所写声音数据大小为4096字节,则构建数据包如下所示:
长度 | 操作代码 | 参数类型 | 参数长度 | 参数值 |
4100 | 3 | B | 4096 | 音频数据 |
其中长度字段为4100(1+1+2+4096),表示发送数据总长(不包括长度字段)为4100字节;操作码为3表明此操作为写操作;参数类型为”B”,表明后续数据为字节流;参数长度为4096,表明参数值字段长度为4096字节;参数值部分存放的是由音频应用来,并需要写到声卡中的音频数据。
由于声卡写操作只需反馈成功与否,因此,返回消息简单,仅描述是否成功即可。如果是声卡读或者I/O操作的IN型命令等,例如一次读4096字节数据,则返回消息如下所示:
成功标记 | 长度 | 参数类型 | 参数长度 | 参数值 |
1 | 4099 | B | 4096 | 音频数据 |
其中成功标记字段为1,表示返回有效;长度字段为4099,表示后续数据总长为4099字节;参数类型字段为“B”,表明后面的数据为字节流;参数长度字段为4096,表明参数值长度为4096字节;参数值部分为音频数据。
本发明的设备重定向方法实现简单,通用性强。在服务器上实现的是轻量虚拟驱动。与标准驱动相比,两者的设备文件的注册/注销和操作接口一致,但实际的设备操作却未执行,而是将应用的操作逻辑通过网络传输至终端,并将反馈返回至服务器上的应用。在这一通信过程中,虚拟驱动往往并不关心操作的细节,只是将设备访问逻辑通过网络传递至终端设备并原路返回。采用上述通信描述过程可以屏蔽不同设备访问细节的差异,具有很强的通用性;同时通过提供特定接口,对某些特殊需要的设备操作提供支持,具有较强的可扩展性;上述方式的通信逻辑清晰,服务代理和终端代理之间的网络通信采用智能网络应用协议的子集,即设备重定向协议。
最后应说明的是:以上实施例仅用以说明而非限制本发明的技术方案,尽管参照上述实施例对本发明进行了详细说明,本领域的普通技术人员应当理解:依然可以对本发明进行修改或者等同替换,而不脱离本发明的精神和范围的任何修改或局部替换,其均应涵盖在本发明的权利要求范围当中。