SIP-message = Request | Response Request = Request-Line *( general-header | request-header | entity-header ) double-return [message-body] ; Note - each header ends with a return and the end of headers is a double return. For line folding, the folded header must begin with 1*( SP | HT ) message-body = Request-Line = Method SP Request-URI SP SIP-Version return Request-URI = URI = SIP-URL = "sip:" [userinfo "@" ] hostport url-parameters [ headers] userinfo = user [ ":" password ] user = *( unreserved | escaped | "&" | "=" | "+" | "$" | ",") password = *( unreserved | escaped | "&" | "=" | "+" | "$" | "," ) hostport = host [ ":" port ] host = hostname | IPv4address hostname = *(domainlabel "." ) toplabel [ "." ] domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum toplabel = alpha | alpha *( alphanum | "-" ) alphanum IPv4address = 1*digit "." 1*digit "." 1*digit "." 1*digit port = * digit ; empty port field is allowed url-parameters = *( ";" url-parameter ) url-parameter = transport-param | user-param | method-param | ttl-param | maddr-param | other-param transport-param = "transport=" ( "udp" | "tcp" ) ttl-param = "ttl=" ttl ttl = 1*3 DIGIT ; 0 to 255 maddr-param = "maddr=" host user-param = "user=" ( "phone" | "ip" ) method-param = "method=" Method tag-param = "tag=" UUID UUID = 1*( hex | "-" ) other-param = ( token | ( token "=" ( token | quoted-string ))) headers = "?" header *( "&" header ) header = hname "=" hvalue hname = 1*uric hvalue = *uric uric = reserved | unreserved | escaped reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | "," digits = 1*DIGIT telephone-subscriber = global-phone-number | local-phone-number global-phone-number = "+" 1*phonedigit [isdn-subaddress] [post-dial] local-phone-number = 1*(phonedigit | dtmf-digit | pause-character) [isdn-subaddress] [post-dial] isdn-subaddress = ";isub=" 1*phonedigit post-dial = ";postd=" 1*(phonedigit | dtmf-digit | pause-character) phonedigit = DIGIT | visual-separator visual-separator = "-" | "." pause-character = one-second-pause | wait-for-dial-tone one-second-pause = "p" wait-for-dial-tone = "w" dtmf-digit = "*" | "#" | "A" | "B" | "C" | "D" general-header = Accept | Accept-Encoding | Accept-Language | Call-ID | Contact | CSeq | Date | Encryption | Expires | From | Record-Route | Timestamp | To | Via entity-header = Content-Encoding | Content-Length | Content-Type request-header = Authorization | Contact | Hide | Max-Forwards | Organization | Priority | Proxy-Authorization | Proxy-Require | Route | Require | Response-Key | Subject | User-Agent |WWW-Authenticate response-header = Allow | Authorization | Proxy-Authenticate | Retry-After | Server | Unsupported | Warning | WWW-Authenticate Method = "INVITE" | "ACK" | "OPTIONS" | "BYE" | "CANCEL" | "REGISTER" Accept = "Accept" ":" #( media-range [ accept-params ] ) media-range = ( "*/*" | ( type "/" "*" ) | ( type "/" subtype ) ) *( ";" parameter ) parameter = attribute "=" value attribute = token value = token | quoted-string accept-params = ";" "q" "=" qvalue *( accept-extension ) accept-extension = ";" token [ "=" (token | quoted-string ) ] Accept-Encoding = "Accept-Encoding" ":" 1#( content-coding ) codings = ( content-coding | "*" ) content-coding = token Accept-Language = "Accept-Language" ":" 1#( language-range [ ";" "q" "=" qvalue ] ) language-range = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" ) Proxy-Authorization = "Proxy-Authorization" ":" credentials Proxy-Authenticate = "Proxy-Authenticate" ":" 1#challenge User-Agent = "User-Agent" ":" 1*( product | comment ) Server = "Server" ":" 1*( product | comment ) Response = Status-Line *( general-header | response-header | entity-header ) double-return [ message-body ] ; Note - each header ends with a return and the end of headers is a double return. For line folding, the folded header must begin with 1*( SP | HT ) Status-Line = SIP-version SP Status-Code SP Reason-Phrase SIP-version = "SIP/2.0" Status-Code = Informational | Success | Redirection | Client-Error | Server-Error | Global-Failure | extension-code extension-code = 3 DIGIT Reason-Phrase = * Informational = "100" ; Trying | "180" ; Ringing | "181" ; Call Is Being Forwarded | "182" ; Queued Success = "200" ; OK Redirection = "300" ; Multiple Choices | "301" ; Moved Permanently | "302" ; Moved Temporarily | "303" ; See Other | "305" ; Use Proxy | "380" ; Alternative Service Client-Error = "400" ; Bad Request | "401" ; Unauthorized | "402" ; Payment Required | "403" ; Forbidden | "404" ; Not Found | "405" ; Method Not Allowed | "406" ; Not Acceptable | "407" ; Proxy Authentication Required | "408" ; Request Timeout | "409" ; Conflict | "410" ; Gone | "411" ; Length Required | "413" ; Request Entity Too Large | "414" ; Request-URI Too Large | "415" ; Unsupported Media Type | "420" ; Bad Extension | "480" ; Temporarily not available | "481" ; Call Leg/Transaction Does Not Exist | "482" ; Loop Detected | "483" ; Too Many Hops | "484" ; Address Incomplete | "485" ; Ambiguous | "486" ; Busy Here Server-Error = "500" ; Internal Server Error | "501" ; Not Implemented | "502" ; Bad Gateway | "503" ; Service Unavailable | "504" ; Gateway Time-out | "505" ; SIP Version not supported Global-Failure = "600" ; Busy Everywhere | "603" ; Decline | "604" ; Does not exist anywhere | "606" ; Not Acceptable message-header = field-name ":" [ field-value ] CRLF field-name = token field-value = *(field-content | LWS ) field-content = Allow = "Allow" ":" 1#Method Call-ID = ( "Call-ID" | "i" ) ":" token local-id = 1*uric Contact = ( "Contact" | "m" ) ":" ("*" | (1# ((name-addr | addr-spec ) [ *( ";" contact-params ) ] [ comment ]))) name-addr = [ display-name ] "<" addr-spec ">" addr-spec = SIP-URL | URI display-name = *token | quoted-string contact-params = "q" "=" qvalue | ("action" "=" "proxy" | "redirect") | ( "expires" "=" delta-seconds | DQUOTE SIP-date DQUOTE) | extension-attribute extension-attribute = extension-name [ "=" extension-value ] Content-Encoding = ( "Content-Encoding" | "e" ) ":" 1#content-coding Content-Length = ( "Content-Length" | "l" ) ":" 1*DIGIT Content-Type = ( "Content-Type" | "c" ) ":" media-type media-type = type "/" subtype *( ";" parameter ) type = token subtype = token CSeq = "CSeq" ":" 1*DIGIT Method Date = "Date:" SIP-date SIP-date = rfc1123-date Encryption = "Encryption" ":" encryption-scheme 1*SP #encryption-params encryption-scheme = token encryption-params = token "=" ( token | quoted-string) Expires = "Expires" ":" ( SIP-date | delta-seconds ) From = ( "From" | "f" ) ":" ( name-addr | addr-spec ) *( ";" addr-params ) *(";" extension-params) addr-params = tag-param tag-param = "tag=" UUID Hide = "Hide" ":" ( "route" | "hop" ) Max-Forwards = "Max-Forwards" ":" 1*DIGIT Organization = "Organization" ":" *TEXT-UTF8 Priority = "Priority" ":" priority-value priority-value = "emergency" | "urgent" | "normal" | "non-urgent" Record-Route = "Record-Route" ":" 1# name-addr Require = "Require" ":" 1#option-tag Proxy-Require = "Proxy-Require" ":" 1#option-tag option-tag = token Response-Key = "Response-Key" ":" key-scheme 1*SP #key-param key-scheme = token key-param = token "=" ( token | quoted-string ) Retry-After = "Retry-After" ":" ( SIP-date | delta-seconds ) [ comment ] [ ";" "duration" "=" delta-seconds ] Route = "Route" ":" 1#name-addr Subject = ( "Subject" | "s" ) ":" *TEXT-UTF8 Timestamp = "Timestamp" ":" *(DIGIT) [ "." *(DIGIT) ] [ delay ] delay = *(DIGIT) [ "." *(DIGIT) ] To = ( "To" | "t" ) ":" (name-addr | addr-spec ) *( ";" addr-params ) *(";" extension-params) ; Extension params are allowed in From to and Via Unsupported = "Unsupported" ":" 1#option-tag Via = ( "Via" | "v") ":" 1#(sent-protocol sent-by *( ";" via-params ) [ comment ] ) *(";" extension-params) ; Extension params are allowed in From to and Via via-params = via-hidden | via-ttl | via-maddr | via-received | via-branch via-hidden = "hidden" via-ttl = "ttl" "=" ttl via-maddr = "maddr" "=" maddr ; Note: maddr not defined but it should be host via-received = "received" "=" host via-branch = "branch" "=" token sent-protocol = protocol-name "/" protocol-version "/" transport protocol-name = "SIP" | token protocol-version = token transport = "UDP" | "TCP" | token sent-by = (host [ ":" port ] ) | ( concealed-host ) concealed-host = token Warning = "Warning" ":" 1#warning-value warning-value = warn-code SP warn-agent SP warn-text warn-code = 3 DIGIT warn-agent = (host [ ":" port ] ) | pseudonym ; the name or pseudonym of the server adding the Warning header, for use in debugging pseudonym = token warn-text = quoted-string WWW-Authenticate = "WWW-Authenticate" ":" 1#challenge auth-scheme = token challenge = auth-scheme 1*SP realm *("," auth-param) realm = "realm" "=" realm-value auth-param = token "=" string credentials = basic-credentials | (auth-scheme #(auth-params)) basic-credentials = "Basic" SP basic-cookie basic-cookie = pgp-challenge = * (pgp-params ) pgp-params = realm | pgp-version | pgp-algorithm | nonce realm = "realm" "=" realm-value realm-value = quoted-string pgp-version = "version" "=" DQUOTE digit *( "." digit ) *letter DQUOTE pgp-algorithm = "algorithm" "=" ( "md5" | "sha1" |token ) nonce = "nonce" "=" nonce-value nonce-value = quoted-string Authorization = "Authorization" ":" credentials pgp-response = realm | pgp-version | pgp-signature | signed-by | nonce pgp-signature = "signature" "=" quoted-string signed-by = "signed-by" "=" DQUOTE URI DQUOTE pgp-eparams = 1# ( pgp-version | pgp-encoding | pgp-key) pgp-encoding = "encoding" "=" "ascii" | token pgp-key = "key" "=" quoted-string OCTET = %x00-ff ; any 8-bit sequence of data CHAR = %x00-7f ; any US-ASCII character (octets 0 - 127) upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" alpha = lowalpha | upalpha digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" alphanum = alpha | digit CTL = %x00-1f | %x7f ; any US-ASCII control character (octets 0 -- 31) and DEL (127) CR = %d13 ; US-ASCII CR, carriage return character LF = %d10 ; US-ASCII LF, line feed character SP = %d32 ; US-ASCII SP, space character HT = %d09 ; US-ASCII HT, horizontal tab character return = CR | LF | CRLF ; typically the end of a line unreserved = alphanum | mark double-return = (CR CR) | (LF LF) | (CR LF CR LF) mark = "-" | "_" | "." | "!" | "~" | "*" | " ' " | "(" | ")" escaped = "%" hex hex LWS = [CRLF] 1*( SP | HT ) ; linear whitespace TEXT-UTF8 = hex = "A" | "B" | "C" | "D" | "E" | "F" | "a" | "b" | "c" | "d" | "e" | "f" | digit token = 1* (alphanum | "-" | "." | "$" | "%" | "*" | "_" | "+" | "~" | "`" | "'") separators = "(" | ")" | "<" | "" | "@" | "," | ";" | ":" | "\" | "<" | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT comment = "(" *(ctext | quoted-pair | comment) ")" ctext = quoted-string = ( DQUOTE *(qdtext | quoted-pair ) DQUOTE ) qdtext = quoted-pair = "\" CHAR delta-seconds = 1*DIGIT ; This is not spec. in 2543 and no reference is given (its in H.3.3.2) qvalue = ( "0" [ "." 0*3 DIGIT ] ) | ( "1" [ "." 0*3("0") ] ) URI-reference = ([ absoluteURI | relativeURI] [ "#" fragment] ) | (sip-url ) ; According to 2453:4.3 - ReqURI is SIPUri (without certain tokens) or GeneralURI absoluteURI = scheme ":" ( hier-part | opaque-part ) relativeURI = (net-path | abs-path | rel-path ) [ "?" query ] hier-part = ( net-path | abs-path ) [ "?" query ] opaque-part = uric-no-slash *uric uric-no-slash = unreserved | escaped | ";" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | "," net-path = "//" authority [ abs-path ] abs-path = "/" path-segments rel-path = rel-segment [ abs-path ] rel-segment = 1*(unreserved | escaped | ";" | "@" | "&" | "=" | "+" | "$" | "," ) scheme = alpha *( alpha | digit | "+" | "-" | "." ) authority = server-H | reg-name reg-name = 1*( unreserved | escaped | "$" | "," | ";" | ":" | "@" | "&" | "=" | "+" ) server-H = [ [ userinfo-H "@" ] hostport ] userinfo-H = *( unreserved | escaped | ";" | ":" | "&" | "=" | "+" | "$" | "," ) path = [ abs-path | opaque-part ] path-segments = segment *( "/" segment ) segment = *pchar *( ";" param ) param = *pchar pchar = unreserved | escaped | ":" | "@" | "&" | "=" | "+" | "$" | "," query = *uric fragment = *uric product = token ["/" product-version] product-version = token rfc1123-date = wkday "," SP date1 SP time SP "GMT" date1 = 2DIGIT SP month SP 4DIGIT ; day month year (e.g., 02 Jun 1982) time = 2 DIGIT ":" 2 DIGIT ":" 2DIGIT ; 00:00:00 - 23:59:59 wkday = "Mon" | "Tue" | "Wed" | "Thu" | "Fri" | "Sat" | "Sun" month = "Jan" | "Feb" | "Mar" | "Apr" | "May" | "Jun" | "Jul" | "Aug" | "Sep" | "Oct" | "Nov" | "Dec" announcement = proto-version origin-field session-name-field information-field uri-field email-fields phone-fields connection-field bandwidth-fields time-fields key-field attribute-fields media-descriptions proto-version = "v=" 1*DIGIT return ;this memo describes version 0 origin-field = "o=" username space sess-id space sess-version space nettype space addrtype space addr return session-name-field = "s=" text return information-field = ["i=" text return] uri-field = ["u=" uri return] email-fields = *("e=" email-address return) phone-fields = *("p=" phone-number return) connection-field = ["c=" nettype space addrtype space connection-address return] ;a connection field must be present ;in every media description or at the ;session-level bandwidth-fields = *("b=" bwtype ":" bandwidth return) time-fields = 1*( "t=" start-time space stop-time *(return repeat-fields) return) [zone-adjustments return] repeat-fields = "r=" repeat-interval space typed-time 1*(space typed-time) zone-adjustments = time space ["-"] typed-time *(space time space ["-"] typed-time) key-field = ["k=" key-type return] key-type = "prompt" | "clear:" key-data | "base64:" key-data |"uri:" uri key-data = email-safe | "~" | %x22 attribute-fields = *("a=" attribute return) media-field = "m=" media space port ["/" integer] space proto 1*(space fmt) return media-descriptions = *( media-field information-field *(connection-field) bandwidth-fields key-field attribute-fields ) media = 1*(alpha-numeric) ;typically "audio", "video", "application" ;or "data" fmt = 1*(alpha-numeric) ;typically an RTP payload type for audio ;and video media proto = 1*(alpha-numeric) ;typically "RTP/AVP" or "udp" for IP4 port = 1*(DIGIT) ;should in the range "1024" to "65535" inclusive ;for UDP based media attribute = (att-field ":" att-value) | att-field att-field = 1*(alpha-numeric) att-value = byte-string sess-id = 1*(DIGIT) ;should be unique for this originating username/host sess-version = 1*(DIGIT) ;0 is a new session connection-address = multicast-address | addr multicast-address = 3*(decimal-uchar ".") decimal-uchar "/" ttl [ "/" integer ] ;multicast addresses may be in the range ;224.0.0.0 to 239.255.255.255 start-time = time | "0" stop-time = time | "0" time = POS-DIGIT 9*(DIGIT) ;sufficient for 2 more centuries repeat-interval = typed-time typed-time = 1*(DIGIT) [fixed-len-time-unit] fixed-len-time-unit = "d" | "h" | "m" | "s" bwtype = 1*(alpha-numeric) bandwidth = 1*(DIGIT) username = safe ;pretty wide definition, but doesn't include space email-address = email | email "(" email-safe ")" | email-safe "<" email ">" email = phone-number = phone | phone "(" email-safe ")" | email-safe "<" phone ">" phone = "+" POS-DIGIT 1*(space | "-" | DIGIT) ;there must be a space or hyphen between the ;international code and the rest of the number. nettype = "IN" ;list to be extended addrtype = "IP4" | "IP6" ;list to be extended addr = FQDN | unicast-address FQDN = 4*(alpha-numeric | "-" | ".") ;fully qualified domain name as specified in RFC1035 unicast-address = IP4-address | IP6-address IP4-address = b1 "." decimal-uchar "." decimal-uchar "." b4 b1 = decimal-uchar ;less than "224"; not "0" or "127" b4 = decimal-uchar ;not "0" IP6-address = text = byte-string ;default is to interpret this as I0-10646 UTF8 ;ISO 8859-1 requires a "a=charset:ISO-8859-1" ;session-level attribute to be used byte-string = 1*( %x01-09 | %x0b | %x0c | %x0e-ff) ;any byte except NUL, CR or LF decimal-uchar = DIGIT | POS-DIGIT DIGIT | ("1" 2*(DIGIT)) | ("2" ("0" | "1" | "2" | "3" | "4") DIGIT) | ("2" "5" ("0" | "1" | "2" | "3" | "4" | "5")) integer = POS-DIGIT *(DIGIT) POS-DIGIT = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" email-safe = safe | space | tab safe = alpha-numeric | "'" | "'" | "-" | "." | "/" | ":" | "?" | %x22 | "#" | "$" | "&" | "*" | ";" | "=" | "@" | "[" | "]" | "^" | "_" | "`" | "{" | "|" | "}" | "+" | "~" | "<" space = SP tab = HT CRLF = DQUOTE =