Board logo

标题: 基于嵌入式Linux和MiniGUI的SIP电话设计 02 [打印本页]

作者: samwalton    时间: 2013-9-28 14:10     标题: 基于嵌入式Linux和MiniGUI的SIP电话设计 02

 当呼叫处理模块子线程收到IP网络上的“180 Ringing”消息和Linux内核的定时器超时消息后,则通过调用SendMessage(hWnd,MSG_180-Ringing,0,0L)向MiniGUI主线程发送MSG_180Ringing消息,主线程通过调用GetMessage()函数获取呼叫处理模块子线程所发过来的消息,通过调用DispatchMessage(&Msg)函数把这些消息发送到窗口过程函数进行处理。窗口过程函数收到相应的消息,首先判断消息的类型,若是MSG_180Ringing消息,然后调用TextOut(hdc,0,0,“对方正在响铃”)函数在窗口上显示“对方正在响铃”字样。
  呼叫处理模块子线程可直接调用eXoSIP协议栈所提供的API函数集,eXoSIP是在oSIP2的基础上对SIP消息的API作了更上层的封装,能够很容易实现SIP电话的呼叫过程控制。呼叫处理模块子线程实现的难点是当呼叫连接成功后,如何启动语音采集、语音编码、数据发送、数据接收、语音解码和语音播放6个子线程。本设计采用Linux线程间通信-管道机制向其它6个子线程发送启动标识,6个子线程接收到启动标识后,唤醒各自的线程,进行相应的语音处理和语音的传输。同样,当呼叫连接释放时,呼叫处理模块子线程向6个子线程发送停止标识,6个子线程接收到停止标识后,停止语音处理和语音的传输,阻塞各自的线程。
  语音采集模块、语音编码模块、数据发送模块、数据接收模块、语音解码模块和语音播放模块6个子线程的过程控制是一样的,首先进入主循环,调用Linux系统函数select()阻塞本线程,侦听本线程与呼叫处理模块子线程之间的管道,若管道中有数据,则调用系统函数read()读取数据,判断数据是否为启动标识,若是,则进入子循环进行相应的处理;若为其它数据,则重新回到新一轮的循环。进入子循环进行相应的处理的同时,将select()设为非阻塞模式,调用select()函数侦听本线程与呼叫处理模块子线程之间的管道,若管道中有数据,则调用系统函数read()读取数据,判断数据是否为停止标识,若为停止标识,则跳出子循环重新回到主循环,线程重新回到阻塞状态;若为其它数据,则不做任何处理,重新回到子循环。
  由于各子线程共享数据缓冲区队列,为了正确读写数据,在设计数据缓冲区队列结构和读写操作函数时,使用了Linux下线程间的同步和互斥机制,保证了对内存资源的安全共享。为了设计出通用的数据缓冲区队列结构和读写操作函数,不妨将向缓冲区写数据的子线程定义为生产者线程,将从缓冲区读取数据的子线程定义为消费者线程。为了保证对数据缓冲区队列进行安全的读写操作,生产者线程和消费者线程必须满足两个条件:
  (1)生产者线程写入缓冲区的数目不能超过缓冲区容量;
  (2)消费者线程读取的数目不能超过生产者线程写入的数目。
  为了实现这两个条件,在程序实现中使用了写指针和读指针来判断缓冲区是空还是满。在初始化时读指针和写指针为0;如果读指针等于写指针,则缓冲区是空的;如果(写指针+1)%N等于读指针,则缓冲区是满的,%表示取余数,N表示缓冲区队列的长度。
  3 结语
  本文提出了基于嵌入式Linux和MiniGUI的SIP电话终端的实现方案,并给出了各线程模块的实现方法,与传统的台式IP网络电话解决方案相比,本方案具有如下突出的特点与创新点:a.体积小、功耗低,由于系统所依赖的硬件平台是嵌入式系统平台,而嵌入式硬件平台本身具有体积小、功耗低特点。b.功能可扩展。由于嵌入式系统软硬件可裁剪,可以方便开发人员进行功能扩展。c.图形界面漂亮。由于系统采用嵌入式图形界面MiniGUI,可以开发出漂亮的图形界面。d.采用多线程机制和缓冲区队列对语音的采集与播放、语音的编码与解码和语音的实时传输进行并行处理,保证了语音通话的连续性。

  对系统进行测试的结果表明,本设计能够对呼叫进行稳键的控制,能够保证语音通话的连续性,对从事相关




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0