既然要学习freeswitch,怎么能不了解sip协议呢
什么是sip协议
sip协议是一种文本协议,一种应用层协议,基于tcp和udp协议的上层应用协议。和http协议很像。
sip协议中各参数解析
比如我们看一个简单的发送邀请invite的sip消息:
recv 1079 bytes from udp/[192.168.65.1]:42618 at 16:09:58.572279:
------------------------------------------------------------------------
INVITE sip:1001@172.19.0.2 SIP/2.0
Via: SIP/2.0/UDP 192.168.65.1:42618;rport;branch=z9hG4bKPjiJ7.rwIawzm0lk8Q7O.o4sltbVBn6iEy
Max-Forwards: 70
From: "bob" <sip:1000@172.19.0.2>;tag=KtYGxt-exgC4DgqF7KPmg.1QzTH.MnER
To: sip:1001@172.19.0.2
Contact: <sip:1000@192.168.65.1:42618;ob>
Call-ID: RoPuqmZKmxrFaAHav2B2Yx.hB9mXk6ks
CSeq: 16711 INVITE
Route: <sip:192.168.31.188;lr>
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Supported: replaces, 100rel, norefersub
User-Agent: Telephone 1.6
Content-Type: application/sdp
Content-Length: 476
下面我们简单的分别介绍一下主要的几个参数的含义
- 第一行的 INVITE sip:1001@172.19.0.2 SIP/2.0
-
invite类似于http请求中的get post put delte 等请求方法,sip中表示一个发起一次呼叫请求,可以理解为字面意思,邀请别人进行通话
sip协议中主要有六种方法:
register:注册
invite:初始化一个会话,发一个呼叫
ACK:对invite消息进行响应
CANCEL:取消请求
BYE:终止一个会话,可以理解为挂断电话
OPTIONS: 查询服务器能力,也可以用作类似ping测试或者心跳保持 -
sip:1001@172.19.0.2类似于http请求中的/index.html,表示请求资源。sip中表示对端的地址。叫做sip的uri,格式为sip:名称@主机地址
-
SIP/2.0 表示sip协议版本号
- Call-ID
每个会话的唯一标识 - CSeq 顺序号,用于统一会话中的区分事务
- From 请求来源
- To 请求接受方地址
- Via 请求消息经过的路径或者说路由,如果sip经过n此代理服务器转发,则会有n条Via记录
- Contact 对端的联系地址,本例子中表示能在192.168.65.1:42618找到1001,这个东西十分重要。基本上对每一个消息的回复都会去根据这个属性寻找地址。就如上一节中我们发现的30秒挂断问题就是由于这个地址不对引起的。当然,地址寻找的优先级是route>Contact>from
- Content-Length 消息征文长度
- Content-Type 消息类型
完成流程
下面我们通过一个完整的流程来大致说明一下sip消息中各个参数在呼叫流程中的应用
-
第一步:
1000向fs发起invite呼叫请求,接收方为To: sip:1001@172.19.0.2,因为1001也是注册到fs上的,fs的地址为172.19.0.2,序列号为16711,contact为sip:1000@192.168.65.1:42618;ob,让我们记住上面的地址。 -
第二步:fs回应这个请求
回应码为407表示未认证,序列号也为16711,说明和上一个请求是一对的。同时返回了Proxy-Authenticate里面的加密参数,告诉你要按照我给的这些参数按照某种加密方式进行加密(此处不解释) -
第三步:1000对认证请求的回应ack
可以看到序列号还是16711 -
第四步:1000重新发起呼叫请求
可以看到序列号变了,变成了16712,不是16711了,表明这是一个新的会话了
- 第五步:
fs回应100 trying,告诉1000:我收到呼叫请求了,我去执行你的请求呼叫1001了
-
第六步:fs发出invite请求,
fs向1001发出邀请。注意序列号:87300907,又变了 -
第七步:
1001对上一步的回应,我知道了。(此处注意,1001其实也是一个ua)
-
第八步:
fs收到1001回应的180,我开始振铃了 -
第九步:fs回应183,会话进行中。注意序列号是16712,这是第五步的序列号
-
第十步:收到200ok,注意序列号是87300907,是第六步fs发出邀请时候的序列号。
-
第十一步:fs回应200ok
-
第十二步:收到ack,注意序列号是16712
-
第十三步:
收到1001发过来的bye,表明1001挂断了电话,序列号7406 -
第十四步:fs发出200OK,回应上一步的挂断请求,ok,你挂吧。我知道了
-
第十五步:fs向1000发出bye,即1001挂断后,fs把1000也挂了
-
第十六步:收到1000回应的200ok,好的,fs,你挂吧
可能大家看上面这一大段一大段的截图可能头疼,下面我们用sngrep把整个完整的流程整理一下大家可能就能明白了: