由于工作需要,对SipDroid和协议Sip进行了研究。以下是前期的研究记录。
从Sipdroid开始,因为程序是从这开始的。
这是Sip进入的界面, 启动时程序实例话了一个Sip引擎并进行了注册等操作,用CallsCursor描述了对象,用CallsAdapter适配器显示了它,如果用户没有设置服务
端口与没有设置预设的电话则会弹出对话框进行设置,使用了Receiver在显示进度以及定位更新等信息,添加了关于、退出、设置等菜单调用。
进入Receiver广播的分析
该广播处理了(开启与关闭虚拟网、注册引擎、网络发生改变时的处理、虚拟网发生的处理、数据改变的处理、电话状态改变的处理、亮度传感器的处理、蓝牙SCO
音频连接状态已改变、有线耳机插入或拔出的处理、手机屏幕锁屏和解锁都是会发广播出来的、用户被唤醒触发、电源管理、wiif状态改变、扫描wifi热点),实现
了构造引擎SipdroidEngine、铃声以及震动的开启与停止、来电去电以及空闲挂断的判断处理、通知栏信息显示、定位位置更新处理等处理。
RegisterService
这是一个注册服务,注册监控了网络连接状态、任何数据变化、手机状态变化、插槽变化、屏幕锁屏以及解屏等。
Caller
这是一个广播类,电话呼叫广播拦截,有拦截去电、来电等操作,详细记录了时间判断是否超时,判断是否为sip用户。
SipdroidEngine
程序的主要功能代码引擎,该类通过用户代理、注册代理以及用户代理简介实现通话以及视频,开始引擎是进行了电源管理、wifi管理、用户…等实例化。
SipdroidListener
只是一个监听的接口。
OwnWifi
这是一个wifi状态改变的广播,用于记录wifi的状态。
CreateAccount
创建帐号对话框,帐号属性--邮箱、服务地址、帐号、随机生成密码、端口。
Call
主要提供手机通话状态的信息。记录状态信息 空闲、活动、通话中、拨号中、警报中、来电中、等待中、丢失中。
ButtonGridLayout
主要的作用是设置显示的格式,它继承于父类:ViewGroup。
CallCard
这个类一开始以为是与Card相关的类,其实它本质上就是一个提供UI element的类,它会在通话开始到结束的整个过程中显示不同的界面变化。
CallerInfo
这个类用于对于给定的电话号码,查找出拨号人的信息,因此这个类会与Contacts后台的数据库会发生交互。
CallerInfoAsyncQuery
拨打信息同步查询,执行sql语句查询。
CallStateException
自定义手机状态异常
Connection
这个类提供关于通话连接信息,同时会对每一次的通过连接进行历史记录。
ContactsAsyncHelper
图像的异步访问,内部定义了加载完成接口,操作图像的加载以及显示。
Phone
这是一个接口类,提供了一些手机状态信息。
PhoneUtils
手机单元类
SlidingCardManager
管理滑动InCallScreen“电话卡”。在新的“简化”滑动卡的用户界面,该卡是始终处于下列状态之一:屏幕顶部的卡、屏幕底部的卡。
InCallScreen
电话显示,实现了传感器接口,通话中的屏幕显示,
Bluetooth
蓝牙工具,管理蓝牙的一个类,具备开启、关闭、判断可用等功能。
RtpStreamReceiver
是一个线程,一个通用的流接收机。
Activity2
调用通话中的屏幕
AutoAnswer
自动回复显示界面
CallScreen
来电时的显示操作界面,以及发送数据在线包、视频包,接受视频包等等。
ChangeAccount
帐号改变显示对话框。
Checkin
登记手续
InstantAutoCompleteTextView
显示自动匹配文本控件
LoopAlarm
保持在线广播,发送在线包。
LoopLocation
发送拍摄地点的广播
OneShotAlarm
一杆报警的广播
OneShotLocation
拍摄地点广播
Settings
设置界面,针对程序属性的设置。
SipRingtonePreference
铃声操作,有铃声选择器、保存铃声、恢复铃声等功能。
SIPUri
服务地址,创建拨打的界面。
VideoCamera
视频摄像,视频的操作,获得远程视频,并进行录制等等。
VideoCameraNew
视频解锁
VideoCameraNew2
重新连接
VideoPreview
视频预览
UserAgent
简单的SIP用户代理(UA)。它包括音频/视频应用。它可以使用外部音频/视频媒体应用工具。
目前仅鼠(强大的音频工具)和VIC作为外部应用程序的支持。
……
其它的直接看源码。
界面的类有:
org.sipdroid.sipua.ui.Sipdroid 主界面
org.sipdroid.sipua.ui.PSTN 拨打按钮界面
org.sipdroid.sipua.ui.SIP sip界面 同PSTN一样
org.sipdroid.sipua.ui.AutoAnswer 自动回复
org.sipdroid.sipua.ui.ChangeAccount 帐号改变
org.sipdroid.sipua.ui.SIPUri 服务地址
org.sipdroid.sipua.ui.Activity2 调用通话中的屏幕 转向通过屏幕
org.sipdroid.sipua.ui.Settings 设置界面
org.sipdroid.sipua.ui.VideoCamera 视频摄像视图
org.sipdroid.sipua.ui.InCallScreen 电话显示
服务的类有:
org.sipdroid.sipua.ui.RegisterService 注册服务的
广播接受的类有:
org.sipdroid.sipua.ui.OneShotAlarm 一杆报警的广播
org.sipdroid.sipua.ui.OneShotAlarm2 一杆报警的广播 标识是否有网进行注册服务
org.sipdroid.sipua.ui.LoopAlarm 保持在线的广播
org.sipdroid.sipua.ui.OwnWifi wifi广播 记录状态
org.sipdroid.sipua.ui.LoopLocation 接受拍摄地点的广播
org.sipdroid.sipua.ui.OneShotLocation 拍摄地点的广播
org.sipdroid.sipua.ui.Caller 电话呼叫广播拦截
org.sipdroid.sipua.ui.Receiver 接受广播(系统完成启动广播、网络连接的变化广播、Vpn 连接变化广播、数据状态改变广播、电话状态改变广播、亮度传感器
广播、蓝牙SCO音频连接状态已改变广播、有线耳机插入或拔出广播、手机屏幕锁屏和解锁广播、用户被唤醒触发广播、wiif状态改变广播)
Sipdroid
-->Receiver.engine(context).isRegistered(); 进行了引擎的生成,以及开启RegisterService。
-->PreferenceManager.getDefaultSharedPreferences(this).getBoolean(Settings.PREF_NOPORT, Settings.DEFAULT_NOPORT)
进行了无端口的判断,当没有设置的时候,会弹出一个对话框进行设置。
-->Receiver.engine(this).call(target, true) 进行拨打判断 最后使用了UserAgent.call进行了拨打。
-->Receiver.engine(this).registerMore(); 引擎更多的注册 设置本地ip地址、进行了枚举注册代理,如果注册了就显示出来。
-->onOptionsItemSelected(MenuItem item) 响应菜单,退出时关闭定位、停止引擎、清空、停止服务。
RegisterService
由Sipdroid里面的on开启,此处把监控数据变化、手机状态变化、插拔变化、屏幕解锁、网络变化等广播开启。
Receiver
-->SipdroidEngine mSipdroidEngine; 静态成员电话引擎,拨打电话的主要成员。
-->engine(context).register(); 引擎注册,sdk只有大于8,才会启动蓝牙。
-->engine(context).registerMore(); 更多注册代理
-->boolean isFast(int i) 是否快速响应,减少一些重复操作,当存在连接信息,则操作vpn虚拟网。
-->boolean isFastGSM(int i) 当存在连接是,减少一些操作。
-->void stopRingtone() 停止铃声
-->void onState(int state, String caller) 状态的改变标识,起初时只是建立连接,当前状态改变时,进行了数据流以及相关的操作。
-->void onText(int type, String text, int mInCallResId, long base) 设置通知栏内容显示
-->void updateAutoAnswer() 更新自动回复
-->void registered() 注册位置更新定位,定位分两种,一种是网络监听,一种是gps监听。
-->void enable_wifi(boolean enable) 分情况操作是否开启关闭wifi
-->void url(final String opt) 是一个多线程,主要是负责报告数据是否有错。
-->void broadcastCallStateChanged(String state, String number) 改变播放状态广播
--> void progress() 显示进展情况。
-->boolean on_vpn() 是否连接VPN虚拟网络
-->Handler mHandler = new Handler() 处理自定义的消息,主要有wifi 要求接入点扫描、开启wifi。
-->void onReceive(Context context, Intent intent) 接受(系统完成启动广播、网络连接的变化广播、Vpn 连接变化广播、数据状态改变广播、电话状态改变广
播、亮度传感器广播、蓝牙SCO音频连接状态已改变广播、有线耳机插入或拔出广播、手机屏幕锁屏和解锁广播、用户被唤醒触发广播、wiif状态改变广播)
SipdroidEngine
主要部分引擎,实现了注册代理监听接口。
-->public UserAgent[] uas; User Agent 用户代理
-->public RegisterAgent[] ras Register Agent 注册代理
-->private KeepAliveSip[] kas 保持在线包
-->public SipProvider[] sip_providers; 实现SIP传输层,是发送和接收SIP消息层
-->PowerManager.WakeLock[] wl 电源管理
-->WifiManager.WifiLock[] wwl; wifi网络管理
-->UserAgentProfile getUserAgentProfile(String suffix) 生成一个用户代理简介
-->public boolean StartEngine() 开始引擎,实例化了电源管理、wifi管理、用户代理、注册代理、保持连接、协议等等。
-->String getContactURL(String username, SipProvider sip_provider) 得到联系的地址
-->void setOutboundProxy(SipProvider sip_provider, int i) 设置传输绑定代理
-->public void CheckEngine() 匹配传输代理,有则绑定。
-->public void expire() 清零操作
-->public void unregister(int i) 卸载一些操作
-->public void registerMore() 更多注册 主要是用户代理简介
-->public void register() 根据用户代理简介进行注册
-->public void registerUdp() 同上一样
-->public void halt() 停止操作
-->public boolean isRegistered() 判断注册里是否已经注册
-->public boolean isRegistered(int i) 指定项是否已经注册
-->public void onUaRegistrationSuccess(RegisterAgent reg_ra,NameAddress target, NameAddress contact, String result)
根据注册代理、用户地址、目标地址进行注册。
-->public void listen() 对用户代理的进行监听
-->public boolean call(String target_url, boolean force) 主要的呼叫
-->public void answercall() 回复电话即接听
-->public void rejectcall() 拒绝电话,挂断。
-->public void togglehold() 转接
-->public void transfer(String number) 呼叫转让
-->public void togglemute() 切换静音
-->public void togglebluetooth() 切换到蓝牙
-->public int speaker(int mode) 设置说话模式
-->public void keepAlive() 保持在线
……
其它的看源码了。
sip协议部分-----SIP即时消息蠕虫RFC3428
1、sip协议介绍
总结:sip可以使用Internet端点(用户代理)来寻找参与者并且可以建立一个可共享的会话描述,可以建立基础的netword hosts(代理服务器),并且允许终端用户
注册上去,发出会话邀请或者发送其他请求。
2、sip协议功能概况
总结:sip是一个应用层的控制协议,可以用来建立、修改、和终止多媒体会话(或会议)。sip提供了一个基础,可以用来实现不同的服务。
3、协议的结构
总结:Sip是一个分层的协议。
第一层:语法和编码层。(编码方式采用了扩展的bnf范式)
第二层:传输层。(客户端如何发送请求和接受应答、服务器如何发送应答和接受请求)
第三层:事务层。(客户端或服务器的操作称为事物)
4、协议的定义
总结:
Address-of-Record:记录地址。(用户的公共地址)
Back-to-Back UserAgent:背对背的用户代理。(uac和uas的串连)
call:呼叫。(建立多媒体对话)
Call Leg:对话的别名。
Call Statefull:代理服务器的对话状态。
Client:客户端。(uac和uas都是客户端)。
Conference:一个包含多个参与方的多媒体会话。
Core:核心。(sip实体的特定类别,所有的核心,除了无状态代理服务器,都是事物用户)。
Dialog:对话。两个UA之间的端到端的对话。
Downstream:事物中的消息传递方向。
Final Response:终结响应。
Header:头域。(消息头)
Header Field:头域字段。
Header Field Value:头域值。
Home Domain:宿主机。(提供sip服务的主机)
Informational Response:提示应答。和临时应答一样。
Initiator、Calling Party、Caller:Invite初始化一个会话。
Invitation:一个Invite请求。
Invitee、Invited User、Called Party、Callee:被叫方。
Lcation Service:定位服务。
Loop:环路。(处理过程中需要检测和防止协议中出现的环路请求)
Loose Routing:丢失路由。
Message:消息。(Sip元素之间传送的协议数据即是消息)
Method:方法。(服务器请求处理的功能)
Outbound Proxy:对外代理服务器。
Parallel Search:并行搜索。
Provisional Response:临时应答。
Proxy、Proxy Server:代理、代理服务器。(本身即作为客户端也作为服务端,为其它客户端提供请求的转发服务)
Recursion:回路、递归。(响应请求 Uri的时候,会在3xx响应中陷入递归)
Redirect Server:重定向服务器。(一个产生3xx应答的uas服务器)
Registrar:登记员。(接受Register请求,把信息放到定位服务器中)
Regular Transaction:常规事务。(凡不包裹Invite、Ack、或者Cancel的)
Request:请求。(客户端发送到服务器的sip消息)
Response:应答。(服务端发送到客户端的sip消息)
Ringback:回铃声。
Route Set:路由集。(一个顺序得Sip或者Sips Uri)
Server:服务器。
Sequential Search:顺序查找。
Session:会话。(多媒体会话,sdp用户名、session id、网络类型、地址类型、地址元素)
Sip事务:客户端和服务端的事件。
Spiral:回溯。
Stateful Proxy:有状态的代理服务器。
Stateless Proxy:无状态的代理服务器。(不维持客户与服务端的事件状态)
Strict Routing:严格路由。(符合rfc2543协议)
Target Refresh Request:目标刷新请求。
Transaction User(TU):事务用户。(Transaction层之上的协议层,UAC核心、UAS core 和 proxy core)
Upstream:上行流。(事务中的消息流向方向)
URL-encoded:一串根据rfc2396编码的字符。
User Agent Client(UAC):用户代理客户端。
UAC Core:UAC 核心。
User Agent Server(UAS):用户代理服务器。
UAS Core:UAS 核心。
proxy、Location、Registrar:服务器都是逻辑实体。
5、Sip消息
总结:消息都是基于Rfc2822格式的。
一般消息 = 起始行 \n *消息包头 \n CRLF \n [消息正文]
起始行 = 请求行/状态行
5.1、请求
sip请求是根据起始行中的Request-Line来区分的。
Request-line 由CRLF结束。
Method:这个规范了6种方法,Register 登记联系信息,Invite、Ack、Cancel用于建立会话、Bye用于结束会话、Options用于查询服务器负载。
Sip-Version:请求和应答消息都包含当前使用的sip版本。
7.2、应答
总结:Sip应答和Sip请求的区别在于在Start-line中是否包含一个Status-line.
Status-code:是一个3位的数字result code,用来标志处理请求的一个结果。
Reason-Phrase是一个简短的Status-Code的说明。
有六类应答:
1xx:临时应答
2xx:成功处理
3xx:重定向--还需要附加的操作才能完成这个请求。
4xx:客户端错误
5xx:服务器错误
6xx:全局错误
7.3、头域
总结:sip头域遵循{H4.2}关于消息头的语法的定义,并且遵循多行的扩展头域的规则。
7.4、包体
总结:所有的应答和请求消息都可以有一个消息正文体。
7.5、分帧的sip消息(Framing Sip Messages)
总结:sip实现可以使用UDP或者其它非可靠传输协议,每一帧包括一个请求或者应答。
8、一般用户代理行为
总结:用户代理代表一个终端系统(UAC和UAS).
8.1、UAC特性
总结:一个合法的Sip请求必须至少包含如下头域(To、From、Cseq、Call-ID、Max-Forwards、Via),他们提供了用于路由用的核心信息,包含了消息的地址,响应
的路由,消息传递次数,详细的顺序,事务的唯一标识。请求行包含了请求的方法,Request-URI、Sip的版本号码。
Request-URI:To头域的值。
To头域:第一个并且也是最先指定请求的“逻辑”接收地,或者是这个请求的用户或资源的address-of-record。
From头域:包含了请求发起者的逻辑标志。
Call-ID:一个在一系列消息中,区分一组消息的唯一标志。
Cseq头域:用来区分和做为事务的顺序使用的。
Max-Forwards头域:用来限制请求到他的目的地中间的跳转。
Via头域:标志了用于事务传输的传输设备,并且也标志了应答送回的地址。
Contact头域:提供了访问后续请求的特定UA实例的联系方法(Sip或Sips Uri)。
8.2、UAS特性
总结:Uas遵循所规定的顺序来处理请求。(首先是身份认证,然后是方法判定,然后是头域,最后是剩余部分)
8.3、重定向服务器
总结:重定向机制,可以降低proxy服务器上的路由请求的压力,从而提高消息转发的效率。
9、取消一个请求(Cancel)
总结:Cancel请求的最大用处是取消需要服务器长时间处理的请求。
9.1、客户行为(Client Behavior)
总结:发送Cancel来取消一个非Invite请求总是形成一种赛跑的局面。
9.2、服务端行为(Server Behavior)
总结:服务端对Cancel请求的处理依赖于服务器的类型,一个无状态的proxy会转发这个请求,一个有状态的proxy可能会响应这个请求,并且自己再产生一些Cancel
请求,UAS会响应这个Cancel请求。
10、注册(egistrations)
10.1、概览
总结:
注册服务为特定地区的位置服务创建绑定关系,这个绑定关系是用来创建包含一个或者多个联系地址的address-of-record URL。
等级服务器(registrar)和proxy服务器都是逻辑上的角色,可以在网络中用一个设备来部署。
注册服务器(Registrar)必须能够对位置服务的数据进行读写,并且这个区域的proxy或者重定向服务器必须能够兼容读取相同的数据。
注册服务器(Registrar)可能和某个区域的proxy服务器部署在一起。
10.2、构造一个Register 请求
总结:Register 请求用来增加、删除、查询绑定资料。
10.2.1、增加绑定
总结:Register请求是向注册服务器发送一个包含对某一个address-of-record的地址的sip请求应当发送的实际联系地址。
注册并不需要更新所有的绑定,一般情况下,ua只更新它现在的联系地址。
10.2.2、删除绑定
总结:注册信息是一个纯粹软件的状态,并且如果不刷新会过期。
10.2.3、访问绑定
总结:如果注册请求头域中不包含Contact头域,那么注册服务器的绑定列表将不会改变。
10.2.4、刷新绑定
总结:每一个ua都对先前他建立的绑定信息刷新的义务,禁止对其它ua建立的绑定信息进行刷新,也可以通过一个register请求来刷新数个绑定请求。
10.2.5、设置内部时钟
总结:如果Register请求的应答中包含一个date头域,客户端可以用这个头域来校正当前内部的时钟。
10.2.6、寻找注册服务器
总结:ua有三种方法来决定想哪里发送注册请求,1、通过配置,使用address-of-record、广播方式;2、ua用请求的request-uri部分种的address-of-record的服
务器部分,用普通的sip服务器定位机制;3、ua可以通过监听广播的形式来获得注册服务器的地址。
10.2.7、传送一个请求
总结:uac遵循规定说明来提交transaction层来发送register请求。
10.2.8、错误响应
总结:Ua接收到一个423应答,他可能需要更改Register请求中的所有有效期,使得这些有效期必须大于等于423应答头中的min-expires头域中的有效期,并且重新
尝试发送这个register请求。
10.3、处理Register请求
总结:一个注册服务器就是一个uas,这个uas用来响应register的请求,并且维持一个绑定表,这个绑定表用来提供给它所管理的区域中的proxy服务器和重定向服
务器的。
11、查询能力
总结:sip方法option允许一个ua来查询另一个ua或者proxy服务器的能力。
11.1、构造Options请求
总结:一个options请求可以根据规定的标准构造方法来进行构造。
11.2、处理Options请求
总结:应答码的选择必须和处理Invite请求一样的应答码。
12、对话框(Dialog)
总结:对话是表现为两个用户代理(UA)之间的持续一段时间的点对点的sip关系,对话似的用户代理之间的关系顺序传递和两个用户代理之间的请求正确路由更加
容易。
12.1、创建一个对话
总结:对话是由对一组特定请求的没有失败的应答来创建的。
12.1.1、UAS行为
总结:当UAS响应一个请求给出一个应答,并且这个应答会建立一个对话框的时候,UAS必须拷贝所有的请求中的Record-Route头域到应答中去,并且必须维持这些参
数的顺序。
12.1.2、UAC行为
总结:当一个UAC发出一个请求,这个请求能够建立一个对话,它必须在Contact头域中提供一个机遇全局的sip或者Sips URI。
12.2、对话中的请求
总结:Ua发送和接收请将遵循UAS的规则,当两个UA之间的对话建立之后,他们都可以在对话中初始化一个新的事务(Transaction)。
12.3、终止对话
总结:在建立对话中的终结对话,跟请求方法无关,如果对话外的请求产生一了一个非2xx终结应答,任何前边请求创建的"早期对话"将会终止,bye方法将会终结一
个对话。
13、初始化一个会话
13.1、概览
总结:当UAC希望初始化一个会话,他首先构造一个invite请求,请求一个服务器来建立一个会话,这个请求可能会由proxy层层转发,最后到达一个或者多个可能能
够处理这个邀请的uas。
13.2、UAC处理
13.2.1、创建一个初始化的invite
总结:它遵循8.1.1节的步骤创建,除此之外还有专门针对invite的附加处理步骤。
13.2.2、处理invite应答
总结:当Invite请求被传送给invite的客户事务层进行处理,uas等待invite的应答。
13.3、UAS处理
13.3.1、处理Invite
总结:UAS核心从事务层收到Invite请求,首先根据8.2节定义的步骤进行处理,8.2节中定义的是跟对话内外无关的请求的处理。
14、更改已经存在的会话
总结:一个成功的Invite请求即会创建一个机遇两个用户之间的对话,也会基于请求、应答模式创建一个会话。
14.1、UAC行为
14.2、UAS行为
15、结束一个会话
总结:初始化的Invite产生了非2xx的终结应答,它也终结了由本次请求创建的任何会话,并且终结了所有的本次请求创建的会话。
15.1、使用BYE请求终止一个会话
总结:UAC核心处理部分创建一个新的非-Invite客户端事务,并且用它来处理Bye请求,UAS核心处理部分接受到Bye请求以后,首先检查它是否和现存的对话框匹配
,如果Bye并不匹配现存的任何一个对话,那么UAS应当产生一个481应答,并且传送给服务器事务。
16、proxy行为
16.1、概述
总结:proxy对于每一个新的请求来说,既可以作为有状态的也可以作为无状态的模式来处理,当作为无状态的处理模式的时候,proxy就是简单的转发,有状态的
proxy会保留这些信息(尤其是事务信息),保留每一个接收的请求和每一个接受请求的应答的相关信息。
16.2、有状态的proxy
总结:一个纯碎的sip事务处理引擎,它为每一个接收到的新的请求创建一个服务端事务。
16.3、验证请求
总结:合法的语法、URI scheme、最大转发次数、循环检测(loop detection)、proxy-require、proxy-authorization。
16.4、路由信息预处理
总结:如果Request-URI包含了maddr参数,proxy必须检查这个参数来看看是否在Proxy配置的可信任的地址列表或者可信任的区域列表中。如果Request-URI包含一
个maddr参数,并且这个参数包含了一个proxy可以信任的地址,并且这个请求是通过Request-URI中的端口和协议接收到的,proxy必须抽掉maddr和其它非缺省的端
口和通讯参数,并且继续处理。
16.5、确定请求的目的
总结:目的地集合可以由请求的内容决定或者由绝对位置服务提供,集合中的每一个目的地都由URI来表达。
16.6、请求转发
总结:当目的地集合不是空的时候,proxy可以开始转发这个请求,有状态的proxy可以按照任意的顺序处理这个目的地集合,它可以顺序处理多个目的地,上一个完
成前下一个不能开始。proxy转发请求都遵循一下步骤:
1、拷贝一个接收到的请求(拷贝必须包含接收到的请求的全部头域)
2、更新Request-URI(proxy通过这个机制来把请求转发到目的地)
3、更新Max-Forwards头域
4、可选增加一个Record-Route头域 (记录一些信息)
5、可选增加附加的头域
6、路由信息后处理
7、决定下一个节点地址、端口、通讯协议。
8、增加一个via头域值。
9、如果需要,增加一个Content-length头域
10、转发这个新的请求
11、设置定时器C(根据临时应答来更新的)
16.7、应答的处理
总结:当proxy收到一个应答的时候,它首先尝试定位一个与这个应答匹配的客户端事务,如果没有,proxy必须作为无状态的proxy来处理这个应答,如果有,转给
这个客户端事务进行处理。
当客户端事务把应答交给proxy层,将会执行下列步骤:
1、寻找适当的应答上下文(转发原始请求前创建的"应答上下文")
2、用临时应答来更新定时器C(如果应答是一个返回码是101-199的临时应答,proxy必须给这个客户端事务重新设置定时器C)
3、从最上边移除via(proxy从应答中移除via头域中最上面的值)
4、在应答上下文中增加应答(这个应答是从那个服务端事务中收到最佳终结应答的一个候选)
5、检查这个应答是否需要立刻发送
6、如果需要、从应答上下文选择最好的终结应答。
7、需要合并认证头域值(客户端需要接收到这些所有目的者的应答并且在下一次尝试的时候,为每一个目的地提供相关的身份证明)
8、可选的重写Record-Route头域值
9、转发应答(proxy必须位置应答上下文直到所有相关事务都已经终结,甚至在发送完成终结应答后还需要维持)
10、产生合适的Cancel请求(如果转发的应答是一个终结应答,proxy必须给依赖于这个应答上下文的所有客户端事务,产生Cancel请求。)
16.8、处理定时器C
总结:允许proxy重设定定时器就意味着允许proxy基于当前条件动态的扩展事务的生命周期。
16.9、处理通讯层的错误
总结:如果在转发请求的时候,通讯层报告了一个错误,那么proxy必须就像收到了一个503应答一样的处理。
16.10、Cancel处理
总结:在接收到一个匹配的Cancel请求的时候,proxy必须取消任何与应答上下文相关的客户端事务。
16.11、无状态的proxy
总结:当作为无状态的时候,proxy就是一个简单的消息转发者。
16.12、Proxy Route处理的总结
总结:在没有本地策略的情况下,proxy对于包含Route头域的请求处理可以归结于如下:
1、proxy会检查Request-URI。
2、proxy会检查Route头域的最上URI。
3、proxy会转发请求到最上的Route头域值所标志的URI或者Request-URI。
17、事务
总结:sip是一个基于事务处理的协议;部件之间的交互是通过一系列无关的消息交换所完成的。事务是一边基于UA或者有状态的proxy,另外一边也基于UA或者有状
态的proxy。
17.1、客户端事务
总结:客户端事务是通过维持一个状态机来提供服务的。
17.1.1.1、Invite客户事务
总结:invite请求包含了一个三方的握手。
17.1.1.2、正式的描述
17.1.1.3、构造ack请求
总结:在客户端事务中构造的ack请求必须包括与原始请求相同的Call-Id、From、Request-URI头域值。
17.1.2、非Invite客户端事务
17.1.2.1、非invite事务概述
总结:非invite事务并不使用ack。
17.1.2.2、正式的描述
17.1.3、客户端事务匹配应答
总结:当客户端事务的通讯层收到一个应答,他必须决定是否又客户端事务来处理这个应答,一个应答和一个客户端事务匹配的话,就有两个条件:
1、如果应答via最上边的branch参数和创建这个客户端事务的请求的Via最上边的branch参数相同。
2、如果Cseq头域的方法参数和创建事务的请求的方法相同。
17.1.4、处理通讯错误
总结:客户端事务应当通知TU这个通讯失败,并且客户端事务应当直接转到"Terminate"状态。
17.2、服务端事务
总结:用来传输请求到TU并且可靠的传输应答的,通过状态机来实现的。
17.2.1、Invite服务端事务
17.2.2、非Invite服务端事务
17.2.3、为服务端事务匹配请求
总结:事务匹配如下:
1、请求中的最上的Via头域的branch参数和创建本事务的请求的最上的via头域的branch参数一样
2、请求的最上的via头域的sent-by参数和创建本事务的请求的最上的via头域的send-by参数一样
3、请求的方法和创建笨事务的方法一样
17.2.4、处理通讯错误
总结:首先需要把应答发送一个备份的地点,如果失败,服务端事务一点通知TU发送失败,并且把状态切换到终止状态。
18、通讯(Transport)
总结:通讯层负责请求和应答在网络上的实际传输。通讯层负责管理像tcp/sctp之类通讯协议的长连接,或者在这些协议上的tls连接,并且包括管理打开这些连接
的使用者的管理。
18.1、客户(Clients)
18.1.1、发送请求
总结:通讯层的用户把请求交给通讯层的实例进行处理,包括ip地址端,通讯层实例,还有可能有多点广播的ttl。
18.1.2、接收应答
总结:当应答接收到的时候,客户端通讯层检查最上面的via头域值。如果“sent-by”参数不符合客户端通讯层在请求中插入的值,那么这个应答必须悄悄丢弃。
18.2、服务端
18.2.1、接收请求
总结:一个服务器应当能够接收从任何ip地址、端口和协议上过来的请求。
18.2.2、发送应答
总结:服务器事务使用最上边的via头域值来决定把应答发送到哪里。
18.3、分块
总结:在面向消息的通讯协议中,如果消息有一个Content-length头域,那么消息体就有可能包含很多字节。
18.4、错误处理
总结:错误的处理取决于出现错误的消息是请求还是应答,如果通讯层用户要求在一个可靠传输协议上发送一个请求,并且结果是一个连接错误,通讯层应该通知通
讯层用户这个发送错误。
19、常见消息部件(Common Message Components)
19.1、Sip和Sips统一资料标记
总结:sip或者sips的uri用来标记一个通讯用的资源,一个通讯资源的例子包含下列内容:
1、一个在线服务的用户
2、一个多线电话
3、消息系统中的邮箱
4、网关服务的Pstn电话号码
5、一个组织中的一个部门
19.1.1、Sip和Sips部件
19.1.2、Character Escaping Requirements(字符转码要求)
19.1.3、Sip和Sips URI例子
19.1.4、URI比较
总结:比较两个SIp或者Sips URI是否相等。
19.1.5、从URI中产生请求
总结:需要能够直接从一个uri来构造请求,uri可以是从名片,网页,或者甚至从某些协议内部得到,协议的实现必须包括构造请求的Request-URI中的transport、
maddr、ttl、user参数。
19.1.6、关联sip uri 和tel URL
总结:如果tel URL转换成为一个sip或者sips uri,那么tel url的整个电话描述,机器参数,都需要放在sip或者sips uri的userinfo部分。
19.2、Option Tags
总结:用来指明sip中的新options(扩展)的。
19.3、Tags
总结:"tag"参数用于sip消息中的to和from头域,它作为一个通用的机制的一部分来唯一标识一个对话,这个机制用call-id和两个从对话参与者的tag来标志一个对
话框。
20、头域
总结:头域参数的描述。
20.1、Accept
总结:空的Accept头域意味着不接受任何格式,如果没有Accept头域,服务器应当认为Accept缺省值是application/sdp以外,语义也是和http/1.1类似的语义。
20.2、Accept-Encoding
总结:类似Accept,但是限定了接收应答中的内容的编码[h3.5]。一个空的Accept-Encoding头域是允许的。
20.3、Accept-Language
总结:用来在请求中指定首选的语言的,这个首选的语言是在应答中的消息体中的原因分析,会话描述,或者状态报告的。如果没有这个参数,那么服务端应该假设
所有的语言客户端都是可以接
收的。
20.4、Alert-Info
总结:当invite请求有一个Alert-Info头域的时候,Alert-Info头域就包含的是给UAS的一个额外的信息,当在180(Ringring)应答中出现的时候,Alter-Info头域
给出了UAC一个额外的回铃信息。Alter-Info头域可能会带来潜在的安全隐患。
20.5、Allow
总结:Allow头域列出了UA支持的方法列表。
20.6、Authentication-Info
总结:该头域提供了和http类别相同的认证方法。
20.7、Authorization
总结:该头域包含了UA进行认证的信任书。
20.8、Call-ID
总结:Call-ID头域用来唯一区别一个特定的邀请或者一个特定客户端的所有注册项。
20.9、Call-Info
总结:该头域提供了对呼叫方或者被叫方的附加信息,如果出现在请求中则是呼叫方的信息,如果出现在应答中则是被叫方的。
20.10、Contact
总结:该头域提供了一个URI,这个URI的含义取决于是在请求还是在应答中,还包含了一个显示的名字,一个包含参数的uri,还有header参数组成。
20.11、Content-Disposition
总结:该头域描述了消息体,或者消息的多个部分,或者消息体的一个部分应被UAC或者UAS怎样解释。
20.12、Content-Encoding
总结:该头域是对“media-type”(媒体类型)的一个修正。首要应用于在不丢失媒体类型标记的情况下对消息体进行压缩处理。
20.13、Content-Language
20.14、Content-Length
总结:头域标志了消息体的大小,给消息的接受者,以10进制表示的数字。
20.15、Content-Type
总结:该头域标志了发给对方的消息体的媒体类型。
20.16、Cseq
总结:该头域包含了一个单个的数字序列号和请求的方法,这个序列号必须是表示成为的一个32位的无符号整数。
20.17、Date
总结:该头域包含了日期和时间。
20.18、Error-Info
总结:该头域提供了对有错误应答码的应答的附加消息。
20.19、Expires
总结:该头域给定了消息过期的相关时间。
20.20、From
总结:该头域表示了请求的来源地。
20.21、In-Reply-To
总结:该头域列举了本次呼叫相关的或者返回的Call-ID。这些Call-ID可以备客户端Cache起来。
20.22、Max-Forwards
总结:该头域必须在任何一个Sip请求中使用,来限制中间转发请求到下一个节点的proxy或者gateway的个数。
20.23、Min-Expires
总结:该头域包含了一个服务器所支持的内部状态(Soft-state)的最小的刷新时间间隔。这个包含被登记服务器所登记的Contact头域。
20.24、MIME-Version
总结:版本
20.25、Organization
总结:该头域包含了发出请求或者应答的sip节点所属的组织名字,这个名字段可以用来让客户端软件过滤呼叫。
20.26、Priority
总结:该头域标志了客户端评价的请求紧急程度。该头域描述了sip应当处理人工或者UA发过来的请求的优先级。
20.27、Proxy-Authenticate
总结:该头域用来进行认证使用的。
20.28、Proxy-Authorization
总结:该头域允许客户端向一个要求认证的Proxy证明自己的身份,包含了与UA认证信息相关的信任书。
20.29、Proxy-Require
总结:该头域用来表示请求中一定要求proxy支持的相关的特性。
20.30、Record-Route
总结:该头域是Proxy在请求中增加的,用来强制会话中的后续请求经过本proxy的。
20.31、Reply-To
总结:该头域包含了逻辑上返回的地URI,这个可以和From头域不同。
20.32、Require
总结:该头域用于UAC告诉UAS关于要求UAS支持那些特性。
20.33、Retry-After
总结:该头域可以用于500(Server Internal Error)或者503(Service Unavailable)应答,用来标志大约本服务还会处于不可用状态多久。
20.34、Route
总结:该头域用于强制一个请求经过一个proxy路由列表。
20.35、Server
总结:该头域包含了关于UAS处理请求所使用的软件信息。
20.36、Subject
总结:该头域提供了呼叫的一个概览,允许呼叫不用分析会话描述就可以大致过滤。
20.37、Supported
总结:该头域列举了UAC或者UAS支持的扩展。
20.38、Timestamp
总结:该头域描述了当UAC发送请求到UAS的时间戳。
20.39、To
总结:该头域定义了逻辑上请求的接受者。
20.40、Unsupported
总结:该头域列出了不被UAS支持的特性列表。
20.41、User-Agent
总结:该头域包含了发起请求的UAC信息。
20.42、Via
总结:该头域是用来描述请求当前经历的路径的,并且标志了应答所应当经过的路径。via头域的branch id参数提供了事务的标志,并且用于proxy来检查循环路由
。
20.43、警告
总结:Warning头域用来给应答的状态添加附加说明使用的,该头域值是在应答中包含的,并且包括了一个3位的警告代码,主机名和警告正文。
20.44、WWW-Authenticate
总结:该头域包含了认证信息。
21、应答代码
总结:该包含了并且扩展了http/1.1应答码。
21.1、临时应答1xx
总结:消息性质的应答,标志了对方服务器正在处理请求,并且还没有决定最后的应答,1xx应答并不是可靠传输的。
21.2、成功信息2xx
总结:请求成功
21.3、转发请求3xx
总结:该应答是用于提示用户的新位置信息的,或者为了满足呼叫而转发的额外服务地点。
21.4、请求失败4xx
总结:该应答定义了特定服务器响应的请求失败的情况。
21.5、Server Failure 5xx
总结:5xx应答是当服务器本身故障的时候给出的失败应答。
21.6、Global Failures 6xx
总结:该应答意味着这服务器给特定用户有一个最终的信息,并不只是在Request-URI的特定实例有最终信息。
22、使用http认证
总结:sip为认证系统提供了一个无状态的,试错机制,这个认证机制式基于http的认证机制的。
22.1、框架
22.2、用户到用户的认证
总结:当UAS收到一个UAC发起的请求,UAS在请求被处理之前进行身份认证。如果请求中没有信任书,UAS可以使用401拒绝认证,并且让客户端提供一个认证书。
22.3、proxy到用户的认证
总结:当UAC发送一个请求到Proxy服务器,proxy服务器可以在处理请求之前,验证原始请求的认证,如果请求中没有信任书,proxy可以用407拒绝这个原始请求,
并且要求客户端提供适当的信任书。
22.4、Digest认证方案
总结:对http Digest 认证方案的sip修改和简化。
23、S/MIME
总结:Sip消息可以加载一个MIME消息体,并且MIME标准包括了MIME内容的保密机制,确保完整性和机密性。
23.1、S/MIME认证
23.2、S/MIME密钥交换
总结:无论何时SIP的S/MIME使用了CMS SignedData消息,它必须包含由公钥所加密的信任书,用于检查签名。
23.3、加密MIME包体
23.4、Sip头隐私和用S/MIME的完整性:Sip地道
总结:作为提供端到端的某种程度认证来说,Sip头域的完整性或者机密性,Si/MIME可以把SIP消息通过"message/sip"的包体类型,整个装入一个MIME包体,并且接
着就像处理普通Sip包体一样,对这个大的包体用MIME安全性来保护。
……
还有很多,感兴趣的筒靴自己下载源码以及sip协议文档研究哟。
学习的目的是成熟!~