SIP 协议

实习期间,接触到SIP,对其略有所闻。SIP(Session Initiation Protocol) 协议是类似于http的基于文本的协议,应用层的信令控制协议。用于创建,修改和释放一个或多个参与者的会话。主要用于IP电话,视频等。

SIP协议支持TCP和UDP,端口5060.也可以穿越防火墙(NAT).SIP协议为用户两端建立连接,然后使用RTP协议进行两端的语音通信。两端建立连接,类似于TCP的三次握手;两端通话结束,要断开连接,goodbye确认。

此图显示一个sip的具体例子:

INVITE sip:user2@there.com To:sip:user2@there.com From:sip:user1@here.com …..(user1’s SDP not shown)

"SIP"

现成已经有实现SIP协议解析的库,比较短小精悍的osip和其扩展的Exosip。我们的项目就是基于Exosip的基础上进行开发的。

osip比较重要的一个数据结构osip_message,用于封装发送和接受的数据。

osip_message
1
2
3
4
5
6
7
8
9
10
struct osip_message {
  char *sip_version;
  osip_uri_t *req_uri;
  char *sip_method;          /**<METHOD(SIP request only)*/
  int statue_code;          /**<status Code(SIP answer only)*/
  char *reason_phrase;       /**<Reason Phrase(SIP answer only)*/
  osip_from_t *from;          /**<From header **/
  osip_to_t   *to;            /**<To header**/
  ......
}  

EXoisp扩展库支持事件类型的数据结构,用于识别状态的转移,到什么状态。

osip_event
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct eXosip_event{
  eXosip_event_type_t type;
  char    textinfo[256];
  void*   external_reference;
  osip_message_t * request;
  osip_message_t * response;
  osip_message_t * ack;
  int tid;      /**unique id for transations(to be used for answers)**/
  int did;      /**unique id for SIP dialogs**/
  int rid;      /**unique id for registration**/
  int cid;      /**unique id for calls(but multiple dialogs!)**/
  int sid;      /**unique id for outgoing subscriptions*/
  int nid;        /**unique id for incoming subscription*/
  int ss_status;    
  int ss_reason;
}
库的使用:初始化eXosip
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <eXosip2/eXosip.h>
eXosip_t *ctx;
int i;
int port=5060;
TRACE_INITIALIZE (6, NULL);
ctx = eXosip_malloc();
if (ctx==NULL)
  return -1;
i=eXosip_init(ctx);
if (i!=0)
  return -1;
i = eXosip_listen_addr (ctx, IPPROTO_UDP, NULL, port, AF_INET, 0);/*Open a UDP socket for signalling*/
if (i!=0)
  {
    eXosip_quit(ctx);
    fprintf (stderr, "could not initialize transport layer\n");
    return -1;
  }
处理eXosip2事件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
eXosip_event_t *evt;
for (;;)
{
    evt = eXosip_event_wait (ctx, 0, 50);
    eXosip_lock(ctx);
    eXosip_automatic_action (ctx);
    eXosip_unlock(ctx);
    if (evt == NULL)
      continue;
    if (evt->type == EXOSIP_CALL_NEW)  /**Answer 180 Ringing to an incoming INVITE**/
      {
          eXosip_lock (ctx);
          eXosip_call_send_answer (ctx, evt->tid, 180, NULL);
      eXosip_unlock (ctx);
      }
    else if (evt->type == EXOSIP_CALL_ACK)
      {
      ....
      ....
      }
    else if (evt->type == EXOSIP_CALL_ANSWERED)
      {
      ....
      ....
      }
    else .....
    ....
    ....
    eXosip_event_free(evt);
}

Comments