gnugk代码解读之一:H.225.0呼叫信令路由的实现

简介
     Call signaling messages may be passed in two ways. The first method is Direct Endpoint Call Signaling, in which case the call signaling messages are passed directly between the endpoints. The second method is Gatekeeper Routed Call Signaling. In this method, the call signaling messages are routed through the gatekeeper between the endpoints. The choice of which methods is used is made by the gatekeeper.

     When Gatekeeper Routed call signaling is used, the gatekeeper may choose whether to route the H.245 control channel and logical channels.

Case I.
The gatekeeper doesn't route them. The H.245 control channel and logical channels are established directly between the endpoints.

Case II.
The H.245 control channel is routed between the endpoints through the gatekeeper, while the logical channels are established directly between the endpoints.

Case III.
The gatekeeper routes the H.245 control channel, as well as all logical channels, including RTP/RTCP for audio and video, and T.120 channel for data. In this case, no traffic is passed directly between the endpoints. This is usually called an H.323 Proxy, which can be regarded as an H.323-H.323 gateway. 

    本节介绍了上面第一种情况H.225.0呼叫路由在gnugk中实现过程。

相关类介绍

      涉及类:ProxyListener, ProxyHandleThread, ProxyConnectionThread
ProxyListener:专门监听gk呼叫端口的线程类。ProxyListener类不是直接继承Pthread(前面讲的线程都是),而是继承一个它的派生线程MyPThread,这个类设定了进程的等待,运行,关闭,释放等进程状态。

ProxyHandleThread:接受从呼叫端口发送过来的H.225呼叫信令,及对这些信令进行解码和转发用的线程类。一个ProxyHandleThread线程对象可处理多个呼叫通道的信令;gk可以创建多个多个ProxyHandleThread,提高呼叫处理的并发度。这种类线程也是MyPThread的派生线程。在其构造函数中,将执行Resume,使线程进入其exec()函数。最后还将建立一个新的ProxyHandleThread线程名为 lcHandler,这个线程又叫ProxyLc线程,主要处理媒体数据的传输。

HandlerList:是上面ProxyListener和ProxyHandleThread的管理类。主要成员函数是HandlerList ::LoadConfig()。这个函数就是取出设定参数值(包括RTP, t120, 245, q931 端口范围及网闸的呼叫端口值,默认是1721)。
然后建立ProxyListener类的线程:
       listenerThread = new ProxyListener(this, GKHome, port ? port : Q931PortRange.GetPort(), queueSize);
接着创建ProxyHandleThread类线程:
for (int i = handlers.size(); i < s; ++i)
        handlers.push_back(new ProxyHandleThread(i));
最后退回到主程序开始主流程。

SETUP消息代理过程

      以SETUP消息为例描述呼叫的代理过程。在ProxyListener线程执行中(ProxyListener::Exec()), 创建CallSignalSocket类对象,然后调用CallSignalSocket的TCPProxySocket::Accept()等待呼叫建立。当收到呼叫发起方的TCP连接时,将CallSignalSocket交给HandlerList类,然后交给当前的呼叫处理线程对象ProxyHandleThread,ProxyHandleThread再将CallSignalSocket保存在自己的socket列表中,然后ProxyHandleThread线程开始执行。 在执行中CallSignalSocket::ReceiveData(),接收数据开始处理。首先读TPKT头(ReadTPKT()),同时将数据读入到缓冲buffer中去(m_lastQ931->Decode(buffer) )。

接着H.225消息解码:
H225_H323_UU_PDU & pdu = signal.m_h323_uu_pdu;
H225_H323_UU_PDU_h323_message_body & body = pdu.m_h323_message_body;

然后根据消息类型进入不同的消息处理函数:
 switch (body.GetTag())
        case H225_H323_UU_PDU_h323_message_body::e_setup:
      ……
          changed = OnSetup(body);
                    ……
        case H225_H323_UU_PDU_h323_message_body::e_callProceeding:
                    ……  

       第一条收到的信令是H.225.0的SETUP消息,进入CallSignalSocket::OnSetup()的处理中。在处理过程中,创建一个新的CallSignalSocket。创建一个ProxyConnectThread线程,在ProxyConnectThread执行中,用刚才的CallSignalSocket与被叫方建立TCP连接,并转发SETUP信令到这个连接上,这样就完成了一个向被叫方转送SETUP消息的过程,实现了对SETUP消息的路由。最后在将CallSignalSocket交给ProxyHandleThread的socket列表中,再由ProxyHandleThread处理这个链路上接收的信令,进行后续信令的转发。

        需要提示的是,因为ProxyHandleThread线程需要同时代理多路呼叫,所以需要另外创建一个ProxyConnectionThread线程,使用该线程建立GK与被叫方的TCP连接,而不是直接在ProxyHandleThread中创建连接。目的是防止TCP连接建立过程太长,影响对其它呼叫通道的处理。

你可能感兴趣的:(gnugk代码解读之一:H.225.0呼叫信令路由的实现)