发布时间:2025-12-10 11:37:33 浏览次数:13
1、概述
1.1 SIP概念
会话初始协议SIP(Session Initiation Protocol)是一个应用层的控制协议,可以建立、修改和结束多媒体的会话。它是由IETF提出并主持研究的一个在IP网络上进行多媒体通信的应用层控制协议,它被用来创建、修改、和终结一个或多个参加者参加的会话进程。这些会话包括Internet多媒体会议、Internet电话、远程教育以及远程医疗等。即所有的因特网上交互式两方或多方多媒体通信活动,统称为多媒体会话。参加会话的成员可以通过组播方式、单播联网方式或者两者结合的方式进行通信。
总的来说,SIP能够支持下列五种多媒体通信的信令功能:
User location(用户定位):确定参加通信的终端用户的位置
User capabilities(用户能力):确定通信的媒体类型和参数
User availability(用户的可用性):决定被叫方是否愿意参加通信
Call setup(呼叫建立):振铃,在主叫和被叫直接建立呼叫的参数
Call handling(呼叫处理):包括呼叫转移和终止
2、协议消息
2.1 消息类型
SIP消息基于10646文本编码,且不区分大小写字符,分为请求消息和响应消息。
| 请求消息 | 消息含义 |
| INVITE | 发起会话请求,邀请用户加入一个会话,会话描述含于消息体中。对于两方呼叫来说,主叫方在会话描述中指示其能够接受的媒体类型及其参数。被叫方必需在成功响应消息的消息体中指明其希望接受哪些媒体,还可以指示其行将发送的媒体。如果收到的是关于参加会议的邀请,被叫方可以根据Call-ID或者会话描述中的标识确定用户已经加入该会议,并返回成功响应消息。 |
| ACK | 证实已收到对于INVITE请求的最终响应。该消息仅和INVITE消息配套使用。 |
| BYE | 结束会话 |
| CANCEL | 取消尚未完成的请求,对于已完成的请求(即已收到最终响应的请求)则没有影响 |
| REGISTER | 注册 |
| OPTIONS | 查询服务器的能力 |
| 序号 | 状态码 | 消息功能 |
| 1xx | 信息响应(呼叫进展响应) | 表示已经接收到请求消息,正在对其进行处理 |
| 100 | 试呼叫 | |
| 180 | 振铃 | |
| 181 | 呼叫正在前转 | |
| 182 | 排队 | |
| 2xx | 成功响应 | 表示请求已经被成功接受、处理 |
| 200 | OK | |
| 3xx | 重定向响应 | 表示需要采取进一步动作,以完成该请求 |
| 300 | 多重选择 | |
| 301 | 永久迁移 | |
| 302 | 临时迁移 | |
| 303 | 见其它 | |
| 305 | 使用代理 | |
| 380 | 代换服务 | |
| 4xx | 客户出错 | 表示请求消息中包含语法错误或者SIP服务器不能完成对该请求消息的处理 |
| 400 | 错误请求 | |
| 401 | 无权 | |
| 402 | 要求付款 | |
| 403 | 禁止 | |
| 404 | 没有发现 | |
| 405 | 不允许的方法 | |
| 406 | 不接受 | |
| 407 | 要求代理权 | |
| 408 | 请求超时 | |
| 410 | 消失 | |
| 413 | 请求实体太大 | |
| 414 | 请求URI太大 | |
| 415 | 不支持的媒体类型 | |
| 416 | 不支持的URI方案 | |
| 420 | 分机无人接听 | |
| 421 | 要求转机 | |
| 423 | 间隔太短 | |
| 480 | 暂时无人接听 | |
| 481 | 呼叫腿/事务不存在 | |
| 482 | 相环探测 | |
| 483 | 跳频太高 | |
| 484 | 地址不完整 | |
| 485 | 不清楚 | |
| 486 | 线路忙 | |
| 487 | 终止请求 | |
| 488 | 此处不接受 | |
| 491 | 代处理请求 | |
| 493 | 难以辨认 | |
| 5xx | 服务器出错 | 表示SIP服务器故障不能完成对正确消息的处理 |
| 500 | 内部服务器错误 | |
| 501 | 没实现的 | |
| 502 | 无效网关 | |
| 503 | 不提供此服务 | |
| 504 | 服务器超时 | |
| 505 | SIP版本不支持 | |
| 513 | 消息太长 | |
| 6xx | 全局故障 | 表示请求不能在任何SIP服务器上实现 |
| 600 | 全忙 | |
| 603 | 拒绝 | |
| 604 | 都不存在 | |
| 606 | 不接受 |
2.2 消息结构
2.3 消息参数
请求消息和响应消息都包括SIP头字段和SIP消息字段。SIP请求命令由起始行、消息头和消息体组成,通过换行符区分消息头中的每一条参数行。对于不同的请求消息,有些参数可选。
Call-ID:本地标识@主机
示例:
Call-ID:call-837575-3@192.168.1.13
其中, call-837575-3是全局唯一的本地标识,192.168.1.13是主机的IP地址。
用户每次开机时都需要向服务器注册,当SIP Client的地址发生改变时也需要重新注册。注册信息必须定期刷新。具体流程参考SIP协议详解。
4、exosip用法分析
以exosip源码中的示例程序分析,流程如下:
//初始化context_eXosip = eXosip_malloc ();if (eXosip_init (context_eXosip)) {syslog_wrapper (LOG_ERR, "eXosip_init failed");exit (1);}if (eXosip_listen_addr (context_eXosip, IPPROTO_UDP, NULL, port, AF_INET, 0)) {syslog_wrapper (LOG_ERR, "eXosip_listen_addr failed");exit (1);}if (localip) {syslog_wrapper (LOG_INFO, "local address: %s", localip);eXosip_masquerade_contact (context_eXosip, localip, port);}if (firewallip) {syslog_wrapper (LOG_INFO, "firewall address: %s:%i", firewallip, port);eXosip_masquerade_contact (context_eXosip, firewallip, port);}eXosip_set_user_agent (context_eXosip, UA_STRING);if (username && password) {syslog_wrapper (LOG_INFO, "username: %s", username);syslog_wrapper (LOG_INFO, "password: [removed]");if (eXosip_add_authentication_info (context_eXosip, username, username, password, NULL, NULL)) {syslog_wrapper (LOG_ERR, "eXosip_add_authentication_info failed");exit (1);}}{osip_message_t *reg = NULL;int i;regparam.regid = eXosip_register_build_initial_register (context_eXosip, fromuser, proxy, contact, regparam.expiry * 2, ®);if (regparam.regid < 1) {syslog_wrapper (LOG_ERR, "eXosip_register_build_initial_register failed");exit (1);}i = eXosip_register_send_register (context_eXosip, regparam.regid, reg);if (i != 0) {syslog_wrapper (LOG_ERR, "eXosip_register_send_register failed");exit (1);}}//处理for (;;) {eXosip_event_t *event;if (!(event = eXosip_event_wait (context_eXosip, 0, 1))) {osip_usleep (10000);continue;}eXosip_automatic_action (context_eXosip);switch (event->type) {case EXOSIP_REGISTRATION_SUCCESS:syslog_wrapper (LOG_INFO, "registrered successfully");break;case EXOSIP_REGISTRATION_FAILURE:regparam.auth = 1;break;default:syslog_wrapper (LOG_DEBUG, "recieved unknown eXosip event (type, did, cid) = (%d, %d, %d)", event->type, event->did, event->cid);}eXosip_event_free (event);}eXosip_malloc、eXosip_init等初始化SIP链接的一些内存和参数,这些都是直接调用源码,可以直接沿用。下面的处理流程,是解析服务器下发的报文,并按枚举宏的形式分别处理。
总体来说,exosip调用的逻辑比较清晰,源码钻研的意义对本人来说意义不大,所以能写的比较少,就这样贴出来做一个参考吧。