SIP协议解析与实现(c和c 使用osip) 3

来源:互联网 发布:淘宝大闸蟹资质认证 编辑:程序博客网 时间:2024/05/01 20:20

第三章 SIP消息


SIP是一个基于文本的协议,它使用UTF-8字符集(RFC2279)。一个SIP消息可以是一个客户端发给服务器端的请求,也可以是一个服务器端发给客户端的应答。

无论是请求(RFC3261第7.1节)还是应答(RFC3261第7.2节)都是基于RFC2822描述的格式。只是在字符集和一些语法细节上有些差异。所有类型的消息都由一个开始行(start-line),一个或多个头头域,一个标识头域结束的空行,和一个可选的消息体(message-body)组成。
generic-message  =  start-line
                             *message-header
                             CRLF
                             [ message-body ]
         start-line       =  Request-Line / Status-Line
        
开始行、头域和头域结束都必须由换行回车符(CRLF)终止。注意,即使没有消息体,也要有头域标识结束的空行。

除了上述的字符集不同外,绝大多数SIP消息和头域的语法都与HTTP/1.1相同。但是,SIP不是HTTP的扩展。

第一节 请求


SIP请求的开始行是一个请求行(Request-Line)。一个请求行包含方法名(Method)、一个请求URI(Request-URI)和一个协议版本(SIP-Version)。它们之间用空格(SP)分割。

请求行以CRLF结束。请求行中,除了最后的CRLF外,不允许出现CR或者LF。各个元素中不允许有线性的空格(表示一个或多个连续的空格LWS)。
Request-Line  =  Method SP Request-URI SP SIP-Version CRLF

方法:这里定义六种方法,REGISTER用于注册联系信息。INVITE、ACK和CANCEL用于构建会议。BYE用于终止会议。OPTIONS用于查询服务器的能力。SIP的扩展协议可能定义其它的方法。

Request-URI:请求URI是一个在RFC3261第19.1或RFC2396中描述的SIP URI或SIPS URI。它指出一个请求发送给一个用户或者一个服务的地址。请求RUI必须不包含空格和控制字符,它必须不被嵌套在"<>"之内。
SIP元素可能支持模式不是“sip”或“sips”的URI。如RFC2806中描述的URI模式“tel”。SIP元素可以支持处理非“sip”和“sips”模式的URI。

SIP-Version:请求和应答消息都包含当前使用的SIP版本。目前这个版本信息必须是"SIP/2.0"。

第二节 应答


SIP应答的开始行是一个状态行(Status-Line).一个状态行由一个协议版本(SIP-Version),紧接着一个表示状态码(Status-Code)的数字和一个短语(Reason-Phrase)组成。它们用空格分割。除了最后的CRLF,不允许有CR或LF出现。
Status-Line  =  SIP-Version SP Status-Code SP Reason-Phrase CRLF

状态码是一个三位的整数,表示对请求的应答。短语是对状态码进行一个简短的描述。状态码是自动设定的,而短语是用户人为设定的。一个用户不需要看到短语。

状态码的最高位数字定义应答的分类。后两位数字没有分类意义。任何状态码在100~199之间的应答称为"1xx应答",任何状态码在200~299之间的应答称为"2xx应答",以此类推。SIP/2.0允许最高位为6个数字:
 1xx:临时的---已经接收到请求,继续向后传送该请求。
 2xx:成功---请求已经成功的接收到、被理解且被接受。
 3xx:重定向---为了完成请求,需要进一步处理。
 4xx:客户端错误---请求包含错误的语法或者在这个服务器不能完成。
 5xx:服务器错误---一个显然无效的请求,服务器处理错误。
 6xx:全局错误---请求在任何服务器都无法完成。
 
RFC3261第21节定义了这些类别并对每个状态码进行了描述。

第三节 头域


SIP头域在语法和语义上都与HTTP头域类似。语法格式如下:
header  =  "header-name" HCOLON header-value *(COMMA header-value)、
如果有多个相同名称的头域,可以将他们合并成一个头域,头域的值用逗号分割。
头域符合在RFC2822第2.2节介绍的一般头域的格式。每个头域由头域名称后面加一个冒号和头域的值组成。在RFC3261第25节详细介绍了消息头的语法。在冒号的两边可以有任意多个空格。但是通常在头域名称和冒号之间避免使用空格,而在冒号和头域值之间使用一个空格。
      Subject:            lunch
      Subject      :      lunch
      Subject            :lunch
      Subject: lunch
上面这些头域都是有效的并且他们是等价的。但是最后一个头域格式是被推荐使用的。

一个头域可以被扩充至多行。每个扩充的行至少要以一个空格或tab(HT)开始。这些空格或者tab被视为一个空格。所以下面这些头域是等价的:
      Subject: I know you're there, pick up the phone and talk to me!
      Subject: I know you're there,
               pick up the phone
               and talk to me!

不同头域名称的头出现的先后顺序并不重要。但是推荐将代理服务器需要处理的头域(如Via, Route, Record-Route, Proxy-Require, Max-Forwards, 和Proxy-Authorization)放在消息的顶部,以便加快解析效率。具有相同头域名称的头域的先后顺序是重要的。在一个消息中可以有多行头域名称相同的头域出现。这时,它与一个头域行和多个以逗号分割的头域值是等价的。如果采用多个相同头域值的头域行,那么它必须是容易被合并成单行的头域,且消息的语义不会因此而被改变。合并的时候,每个后出现的头域行的值被加在单行头域值的最前面,并用逗号与其它值分割。WWW-Authenticate, Authorization, Proxy-Authenticate, 和 Proxy-Authorization头域除外。如果它们出现多个相同的头域名称的头域,它们不能被合并。下面每组头域都是等价的:

   Route: <sip:alice@atlanta.com>
      Subject: Lunch
      Route: <sip:bob@biloxi.com>
      Route: <sip:carol@chicago.com>

      Route: <sip:alice@atlanta.com>, <sip:bob@biloxi.com>
      Route: <sip:carol@chicago.com>
      Subject: Lunch

      Subject: Lunch
      Route: <sip:alice@atlanta.com>, <sip:bob@biloxi.com>,
             <sip:carol@chicago.com>
            
下面各组头域都是有效的但是它们不等价:
      Route: <sip:alice@atlanta.com>
      Route: <sip:bob@biloxi.com>
      Route: <sip:carol@chicago.com>

      Route: <sip:bob@biloxi.com>
      Route: <sip:alice@atlanta.com>
      Route: <sip:carol@chicago.com>

      Route: <sip:alice@atlanta.com>,<sip:carol@chicago.com>,
             <sip:bob@biloxi.com>
            
头域的值可以使UTF-8的数字、空格、符号、分隔符或者引用字符串(带双引号的字符串)。一些头域在最后附加一系列以分好分割的参数名称、参数值对:
   field-name: field-value *(;parameter-name=parameter-value)
虽然参数个数是没有限制的,但是每个参数名称只能出现一次。

头域是不区分大小写的。除非特殊情况,头域名称、头域值、参数名称、参数值都不区分大小写。符号经常是小写的。除非特殊说明,引用字符串是区分大小写的。例如:
   Contact: <sip:alice@atlanta.com>;expires=3600
   等价于
   CONTACT: <sip:alice@atlanta.com>;ExPiReS=3600
   
   Content-Disposition: session;handling=optional
   等价于
   content-disposition: Session;HANDLING=OPTIONAL

下面这两个头域是不等价的:
   Warning: 370 devnull "Choose a bigger pipe"
   Warning: 370 devnull "CHOOSE A BIGGER PIPE"

   
第四节 头域分类


一些头域只对请求或只对应答有意义。它们分别被称为请求头域或者应答头域。如果一个在消息中出现的头域不符合它的分类(例如一个请求头域出现在应答消息中),那么它必须被忽略。RFC3261第20节定义了各个头域的分类。

第五节 简洁格式


SIP支持对一般头域名称的缩写形式。这对于不能传输大数据时会很有用处(例如,当使用UDP时,超过最大传输单元MTU)。这些缩写形式在RFC3261第20节定义。缩写形式的头域名称和长头域名称可以同时出现在一个消息中,并且语义不变。

原创粉丝点击