作者:nathan
转自:http://hi.baidu.com/nathan2007/blog/item/a097c6249570a2004d088df6.html
以下分析仍基于Fetion 2006 beta 2.1.0.0。
飞信所使用的协议版本标记是"SIP-C/2.0",协议栈中标记的版权信息是"Copyright (c) 2004-2006 China Mobile Limited. All rights reserved.",(再次说明飞信开发了很久了嘛;))。抓协议包初看的印象是,它基于IETF(Internet Engineering Task Force)所制定的标准SIP协议作了一丁点调整。关于标准的SIP协议,请参见IETF或RFC3261以及其它一些对它进行扩展的RFC,内容实在是太多了,不过如果有点基础的话,估计看个半小时的RFC就明白了个大概。另外,飞信照着微软做的,所以看微软的实时通信协议的说明也一样:Look。
一个SIP的请求消息的格式是:请求行+消息头+空行+消息体,请求行的格式是:SIP方法+空格+接受方uri+空格+SIP协议版本,如:
INVITE sip:bob@biloxi.com SIP/2.0
接下来是消息头部,消息头的格式跟http头格式一样,也是Field Name:Field Value的形式,如:
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds
Max-Forwards: 70
To: Bob <sip:bob@biloxi.com>
From: Alice <sip:alice@atlanta.com>;tag=1928301774
Call-ID: a84b4c76e66710@pc33.atlanta.com
CSeq: 314159 INVITE
Contact: <sip:alice@pc33.atlanta.com>
Content-Type: application/sdp
Content-Length: 142
IETF SIP中对这些Header Field均有专门的定义,见RFC3261以及IETF的SIP草案文档。Fetion的SIP-C/2.0协议中用到的Header Field有:
Authorization 缩写为"A"
CallID "I"
Contact "M"
ContentEncoding "E"
ContentLength "L"
ContentType "C"
CSeq "Q"
Date "D"
EndPoints "EP"
Event "N"
Expires "X"
From "F"
MessageID "XI"
ReferredBy "RB"
ReferTo "RT"
Require "RQ"
RosterManager "RM"
Source "SO"
Supported "K"
To "T"
Unsupported "UK"
WWWAuthenticate "W"
以上这些头域很多在RFC并没有定义,只在IETF的协议草案中有定义,如Event。SIP消息头后,由一个空行分隔,接下来就是SIP的消息体。消息体通过是用SDP协议描述的,见RFC2327,当然也有直接文本或XML表示的信息,消息体的格式按RFC中的定义,应由头部的Content-Type来决定,但飞信好象不是,具体是怎么定义,还没深入去研究,留待下次吧。
飞信所支持的SIP方法(SIP Method)有以下几种:
1. Ack方法。在Fetion的SIP-C/2.0中,缩写为"A",以下是一个Ack消息,会话(Session)发起方用以向SIP Proxy确认会话的开始:
A fetion.com.cn SIP-C/2.0
I: 16
Q: 1 A
T: sip:987654321@fetion.com.cn;p=1234
F: 123456789
其中:123456789是发起方的SIP地址,这个显然没按SIP标准来表达,只是用了一个飞信号码。sip:987654321@fetion.com.cn,这个是按标准表达的对方地址。
2.BENotify方法(Fetion缩写为"BN"),这不是个标准的SIP方法,既没在RFC中定义,也没出现在IETF的协议草案中,这是微软在其LCS中定义的:BENOTIFY ("best effort" notify)enhances server performance by eliminating the response requirement. Otherwise, a BENOTIFY request has the same behavior as NOTIFY. Applications that require NOTIFY support need to implement similar processing for BENOTIFY."(见MSDN)。就是个不需要回复的NOTIFY,微软扩展出这个方法是为了支持大量用户。以下是飞信的一个BENotify消息,表示用户987654321的在线状态的变化:
BN 123456789 SIP-C/2.0
Q: 13 BN
N: presence
X: xxxx
I: 9
L: xxx
<events><event type="PresenceChanged"><presence uri="sip:987654321@fetion.com.cn;p=xxxx"><basic value="100" device-id="PCCL025722" device-type="PC" device-caps="simple-im,im-session,temp-group" /></presence></event></events>
3.Bye方法(Fetion缩写为"B"),以下是一个BYE的请求消息,用以结束会话:
B fetion.com.cn SIP-C/2.0
F: 123456789
I: 11
Q: 2 B
T: sip:987654321@fetion.com.cn;p=1234
4.Cancel方法(C),用以取消正在进行中的INVITE请求。
5.Info方法(IN),用以在SIP协议中支持应用相关的控制信息,飞信传文件时,用到了这个方法。这是RFC中的一个扩展。以下是一个INFO方法的消息:
IN fetion.com.cn SIP-C/2.0
F: 123456789
I: 22
Q: 3 IN
T: sip:987654321@fetion.com.cn;p=1234
L: 266
<action type="share-content" method="request"><transmit type="relay" session-id="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" /><file name="xxxxxx.xx" size="xxx" url="HTTP://221.130.45.206/hds/RamRelayDownloadShareContent.aspx?FileUri=xxxxxxxxxxxxx" /></action>
6.Invite方法(I),这是用建立会话过程的SIP方法。以下是飞信的INVITE方法的一个协议消息,表示用户123456789要求和987654321建立会话,准备进行文本消息的通信:
I fetion.com.cn SIP-C/2.0
F: 123456789
I: 16
Q: 1 I
T: sip:987654321@fetion.com.cn;p=1234
K: text/html-fragment
K: multiparty
L: 137
v=0
o=-0 0 IN xxx.xxx.xxx.xxx:xxxx
s=session
c=IN IP4 xxx.xxx.xxx.xxx:xxxx
t=0 0
m=message 1769 sip sip:123456789@fetion.com.cn;p=xxxx
7.Message方法(M),这也是一个标准的SIP扩展,用以支持即时消息。以下是飞信的一个Message消息,用户123456789向用户987654321发消息说“Hello!你好” :
M fetion.com.cn SIP-C/2.0
F: 123456789
I: 16
Q: 2 M
T: sip:987654321@fetion.com.cn;p=1972
C: text/html-fragment
K: SaveHistory
L: 121
<Font Face='Arial' Color='-16777216' Size='9'>hello! </Font><Font Face='SimSun' Color='-16777216' Size='12'>你好</Font>
8.Negotiate方法(NEG),这是一个IETF定义的SIP的方法,好象没见纳入RFC? 用以在会话建立(INVITE)前的协商会话相关的参数,但没见飞信用啊....以后再说。
9.Notify方法(N),这是IETF定义的一个SIP扩展方法,并被RFC接纳,见RFC3265。消息见前面的BENotify。这个消息是需要进行回复的。
10.Options方法(O),标准的SIP方法,用来查询对端或服务器的能力。比如了解对方支持什么编码类型。在飞信传文件时使用了以下消息:
O fetion.com.cn SIP-C/2.0
F: 123456789
I: 22
Q: 2 O
K: ShareContent
T: sip:987654321@fetion.com.cn;p=xxxx
11.Refer方法(REF),这是已纳入RFC的一个SIP扩展方法,其功能是要求接受方通过使用在请求中提供的联系地址信息联系第三方。
12.Register方法(R),这是SIP的标准方法,用来向服务器登记。如以下飞信在注册时发出的消息:
R fetion.com.cn SIP-C/2.0
F: 123456789
I: 1
Q: 2 R
A: Digest response="xxxxxxxxxxxxxxxxxxxxxxxxxx",cnonce="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
L: 147
<args><device type="PC" version="131" /><caps value="simple-im;im-session;temp-group" /><events value="contact;permission;system-message" /></args>
13.Service方法(S),这是IETF定义的一个SIP扩展方法,好象未纳入RFC?用来向SIP服务器请求额外的服务。如一下飞信发出的消息:
S fetion.com.cn SIP-C/2.0
F: 123456789
I: 2
Q: 1 S
N: GetPersonalInfo
L: 172
<args><personal version="11" attributes="all" /><services version="11" attributes="all" /><config version="109" attributes="all" /><mobile-device attributes="all" /></args>
以上是飞信客户端要求服务器返回用户信息。又如:
S fetion.com.cn SIP-C/2.0
F: 123456789
I: 12
Q: 1 S
N: StartVoiceChat
L: 103
<args><voice-chat begin-date="2007-01-01 00:00:00.1234" /><users><user sid="987654321" /></users></args>
这是通过服务器开始飞信语聊。
14.Subscribe方法(SUB),这是IETF定义的一个SIP扩展方法,并被RFC接纳,见RFC3265。这个方法被用来向服务器订阅事件异步通知。服务器就会用NOTIFY或BENOTIFY(微软扩展的)方法,将事件通知给飞信客户端。如飞信订阅用户的presence事件,比如上线啊,下线啊什么的:
SUB fetion.com.cn SIP-C/2.0
F: 123456789
I: 1
Q: 1 SUB
N: presence
L: xxx
<args><subscription><contacts><contact uri="sip:xxxxxxxx@fetion.com.cn;p=xxxx" /><presence><basic attributes="all" /><personal attributes="all" /><extended types="sms;location;listening;ring-back-tone" /></presence></subscription></args>