Use Overview

From reSIProcate
Jump to navigation Jump to search

ReSIProcate is an object oriented SIP interface and stack implemented in C++. The reSIProcate approach emphasizes consistency, type safety, and ease of use.

A central component of any SIP service is handling of SIP messages and their parts. A SIP message consists of headers, request/status line, and body.

Headers[edit]

Headers are accessed from messages with the header method. The header method is overloaded so that its return value is appopriate for each type of header. The actual header method is determined by the header type token passed to the overloaded header method.

Header Access Tokens[edit]

Each header type defined in RFC3261 has a corresponding header access token. For example, the header access tokens for To and From headers are h_To and h_From. The rule for determing the header access token from a header as named in RFC3261 is to remove all dashes from the header name and prefix the result with "h_". For example, "Content-Disposition" becomes h_ContentDisposition.

Given an existing message, fetching the To header is simply:

const NameAddr& to = message->header(h_To);

Well-formedness check[edit]

Each header-field-value type has a function that may be used to determine whether or not it is well-formed.

if(message->header(h_To).isWellFormed())
{
   // Do stuff with the header
}

Right now, isWellFormed() is minimally picky; it will only return false if the header-field-value is unparsable. It does not report the presence of forbidden characters, unless their presence makes it impossible to parse the header. No method exists to carry out a full, pedantic syntax check on a header-field-value. This functionality may be added in the future.

Accessor/Setters[edit]

The header methods are both accessors and setters. Accessing a header that isn't in the message creates the header in a default state if the message is non-const.

To set an empty message's To header:

SipMessage message;
// displayName and uri are accessor/setter methods on NameAddr, the storage class
// for To headers.
message.header(h_To).displayName() = "Speedy Shannon";
message.header(h_To).uri() = Uri("speedy@home.com");

Please note: If a header is malformed, and it has not yet been parsed, these accessors/setters will throw a ParseBuffer::Exception!

Existence Check[edit]

The header methods are used also to access existing headers. If you want to make sure that you are accessing an existing header and are not creating a default header, use the exists method. The exists method is overloaded with the same access tokens.

SipMessage* message;
if (!message->exists(h_To))
{
   // complain bitterly
   ...
}
else
{
   NameAddr& to = message->header(h_To);
   ...
}

Const Access[edit]

However, if the message variable is declared const, the header methods will not create a default instance of a missing header, but will throw SipMessage::Exception. This is a typical mode when working with incoming messages.

try
{
   const SipMessage* message;
   To::Type& to = message->header(h_To);
   ...
}
catch (SipMessage::Exception e)
{
   // complain bitterly
   ...
}

Remove[edit]

The remove method is also overloaded for the access tokens. Removing a header that does not exist is a no-op.

SipMessage* message = ...;
message->remove(h_RecordRoutes);

Single Instance[edit]

Each header type is either a single instance or multiple instance. For example, the header type To is single instance while the header type Record-Route is multiple instance. The return types differ accordingly.

Multiple Instance[edit]

Multiple instance headers are accessed through a collection of the appropriate header type. As a programming hint, access tokens for multiple headers are pluralized.

Similarly, the collection of each header type is named the pluralized header type. Below is an example accessing a collection of NameAddr instances.

NameAddrs& rr = message.header(h_RecordRoutes);

The collection of header values can be iterated in the usual stl like fashion.

for (NameAddrs::iterator i = rr.begin(); i != rr.end(); ++i)
{
   NameAddr& r = *i;
   ...
}

All collections of header values support begin, end, empty, size, front, back, push_back, push_front, reverse, and clear. Each collection is specific to the header type so no casting is necessary.

NameAddr na;
na.displayName() = "Alice";
na.uri() = Uri("sip:alice@company.com");
rr.push_back(na);

Request/Status Line[edit]

The request/status lines are special cases of headers. They are accessed by the header method with the header type tokens h_RequestLine and h_StatusLine. A message may have one or the other of these headers but never both. To determine if a message has a Request Line, use:

if (message->isRequest())
{
   ...
}

Similarly for Status Line:

if (message->isResponse())
{
   ...
}

Note that a newly created message has neither a request or status line. The application must add one or the other for the message to be well formed.

Body[edit]

A message body is accessed with the getContents method. The retured value is of type Contents*, an abstract type. The return value must be cast (dynamic_cast is recommended for runtime type safety) to be used. The content type of a message can be determined by examining the Content-Type header of the message.

New message contents are created by instantiating an instance of a type derived from Contents. For example, SdpContents. A variety of content types are currently supported, including mulitpart, signed, and Pkcs7. New content types can be created either inside or outside of the reSIP library (see Creating a New Contents Type).

Setting the contents of a message takes care of setting the Content-Type and Content-Length of the message.

Pkcs7* pres = new Pkcs7();
...
message->setContents(pres);

Alternatively, pass the newly created contents as an auto_ptr and avoid the copy:

std::auto_ptr<Contents> pres(new Pkcs7());
...
message->setContents(pres);

Recursive multipart contents are supported.

Header Types[edit]

Every RFC 3261 header has a corresponding access token. However, many of the headers have identical form. For example. The To and From header values both consist of a display name and a URI. The To and From headers are managed programmatically as NameAddr instances. The class that manages each header type is responsible for parsing header text, providing storage and access during the life of the message, and serializing the header value to text for transmission.

The table below shows the reSIP types for each of the built in RFC headers currently supported by reSIP. The reSIP type is the return type of a SipMessage header call with the access token as its argument. Plural values mean that the return value is a collection of the type indicated by the singular. The plural type exists in reSIP and is an STL like container.

RFC NamereSIP Access TokenreSIP Type
Accepth_AcceptsMimes
Accept-Contacth_AcceptContactsNameAddrs
Accept-Encodingh_AcceptEncodingsTokens
Accept-Languageh_AcceptLanguagesTokens
Alert-Infoh_AlertInfosGenericUris
Allowh_AllowsTokens
Allow-Eventsh_AllowEventsTokens
Answer-Modeh_AnswerModeToken
Authentication-Infoh_AuthenticationInfosAuths
Authorizationh_AuthorizationsAuths
Call-IDh_CallIDCallId
Call-Infoh_CallInfosGenericUris
Contacth_ContactsNameAddrs
Content-Dispositionh_ContentDispositionTokens
Content-Encodingh_ContentEncodingTokens
Content-IDh_ContentIdTokens
Content-Languageh_ContentLanguagesTokens
Content-Lengthh_ContentLengthUInt32Category
Content-Typeh_ContentTypeMime
Content-Transfer-Encodingh_ContentTransferEncodingStringCategory
CSeqh_CSeqCSeqCategory
Dateh_DateDateCategory
Error-Infoh_ErrorInfosGenericUris
Eventh_EventToken
Expiresh_ExpiresExpiresCategory
Flow-Timerh_FlowTimerUInt32Category
Fromh_FromNameAddr
History-Infoh_HistoryInfosNameAddrs
Identityh_IdentityStringCategory
Identity-Infoh_IdentityInfoGenericUri
In-ReplyToh_InReplyToCallId
Joinh_JoinCallId
Max-Forwardsh_MaxForwardsUInt32Category
MIME-Versionh_MIMEVersionTokens
Min-Expiresh_MinExpiresUInt32Category
Min-SEh_MinSEExpiresCategory
Organizationh_OrganizationStringCategory
P-Asserted-Identityh_PAssertedIdentitysNameAddrs
P-Associated-URIh_PAssociatedUrisNameAddrs
P-Called-Party-IDh_PCalledPartyIdNameAddr
P-Preferred-Identityh_PPreferredIdentitysNameAddrs
P-Media-Autorizationh_PMediaAuthorizationTokens
Pathh_PathsNameAddrs
Priorityh_PriorityTokens
Priv-Answer-Modeh_PrivAnswerModeToken
Privacyh_PrivacysPrivacyCategorys
Proxy-Authenticateh_ProxyAuthenticatesAuths
Proxy-Authorizationh_ProxyAuthorizationsAuths
Proxy-Requireh_ProxyRequiresTokens
Reasonh_ReasonsTokens
Record-Routeh_RecordRoutesNameAddrs
Refer-Subh_ReferSubToken
Refer-Toh_ReferToNameAddr
Referred-Byh_ReferredByNameAddr
Reject-Contacth_RejectContactsNameAddrs
Remote-Party-IDh_RemotePartyIdsNameAddrs
Replacesh_ReplacesCallId
Reply-Toh_ReplyToNameAddr
Request-Dispositionh_RequestDispositionTokens
Requireh_RequiresTokens
Retry-Afterh_RetryAfterUInt32Category
RSeqh_RSeqUInt32Category
RAckh_RAckRAckCategory
Routeh_RoutesNameAddrs
Security-Clienth_SecurityClientTokens
Security-Serverh_SecurityServerTokens
Security-Verifyh_SecurityVerifyTokens
Serverh_ServerStringCategory
Service-Routeh_ServiceRoutesNameAddrs
Session-Expiresh_SessionExpiresExpiresCategory
SIP-ETagh_SIPETagToken
SIP-If-Matchh_SIPIfMatchToken
Subjecth_SubjectStringCategory
Subscription-Stateh_SubscriptionStateToken
Supportedh_SupportedsTokens
Target-Dialogh_TagetDialogCallId
Timestamph_TimestampStringCategory
Toh_ToNameAddr
Unsupportedh_UnsupportedsTokens
User-Agenth_UserAgentStringCategory
Viah_ViasVias
Warningh_WarningsWarningCategories
WWW-Authenticateh_WWWAuthenticatesAuths

The following table lists each of the reSIP types for managing headers. A complete list of accessors is included for each type. Recall that many headers are multi-valued; the return type in the multi-valued cases must be iterated to get to the types shown. Multi-values headers are identified with multi-valued.

RequestLine[edit]

 RFC name: 
   Request-Line
 Description:
   The first line of a request message. Does not correspond to a header proper
   but is accessed with the header interface in reSIP.
 Example:
   INVITE sip:bob@biloxi.com SIP/2.0
 Parts:
    RFC Name          accessor            reSIP type      settable
    --------------------------------------------------------------
    Request-URI       uri()               Uri             yes
    Method            getMethod()         MethodTypes     yes
    Method            unknownMethodName() Data            yes
    SIP-Version       getSipVersion()     Data            no

RFC Headers: <none>

StatusLine[edit]

 RFC name: 
   Status-Line
 Description:
   The first line of a response message. Does not correspond to a header proper
   but is accessed with the header interface in reSIP.
 Example:
   SIP/2.0 200 OK
 Parts:
    RFC Name          accessor            reSIP type      settable
    --------------------------------------------------------------
    Status-Code       statusCode()        int             yes
    SIP-Version       getSipVersion()     Data            no
    Reason-Phrase     reason()            Data            yes

RFC Headers: <none>

Auth[edit]

 RFC name: 
    challenge
 Description:
   Identifies the authentication scheme in a challenge response.
 Example:
   Digest-Authenticate: username="Alice", realm="atlanta.com",
                        nonce="84a4cc6f3082121f32b42a2187831a9e",
                        response="7587245234b3434cc3412213e5f113a5432"
 Parts:
    RFC Name          accessor        reSIP type      settable
    ----------------------------------------------------------
    auth-scheme       scheme()        Data            yes

RFC Headers:

  • Authentication-Info
  • Authorization multi-valued
  • Proxy-Authenticate multi-valued
  • Proxy-Authorization multi-valued
  • WWW-Authenticate multi-valued

Note that the parameters to the Auth type are comma separated. reSIP correctly interprets the commas as separating parameters and not header values.

CSeqCategory[edit]

 RFC name:
   CSeq
 Description:
   Places the message in sequence in the call.
 Example:
   CSeq: 314159 INVITE
 Parts:
   RFC Name          accessor            reSIP type      settable
   --------------------------------------------------------------
                     sequence()          int             yes
   Method            method()            MethodTypes     yes
                     unknownMethodName() Data            no

RFC Headers:

  • CSeq

CallId[edit]

 RFC name:
   Call-ID
 Description:
   Uniquely identifies the call.
 Example:
   Call-ID: a84b4c76e66710@pc33.atlanta.com
 Parts:
   RFC Name          accessor        reSIP type      settable
   ----------------------------------------------------------
                     value()         Data            yes

RFC Headers:

  • Call-ID

Note: C++ type synonym for CallID

DateCategory[edit]

 RFC name:
   SIP-date
 Description:
   Human readable date string.
 Example:
   Date: Sat, 13 Nov 2010 23:29:00 GMT
 Parts:
   RFC Name          accessor        reSIP type      settable
   ----------------------------------------------------------
   wkday             dayOfWeek()     DayOfWeek       yes
   date1
                     dayOfMonth      int             yes
                     month()         int             yes
                     year()          int             yes
   time
                     hour()          int             yes
                     minute()        int             yes
                     second()        int             yes

RFC Headers:

  • Date

GenericUri[edit]

 RFC name:
   absoluteURI
 Description:
   Non-structured human readable URI.
 Example:
   Alert-Info: <http://www.example.com/sounds/moo.wav>
 Parts:
   RFC Name          accessor        reSIP type      settable
   ----------------------------------------------------------
                     uri()           Data            yes

RFC Headers:

  • Alert-Info
  • Call-Info
  • Error-Info

ExpiresCategory[edit]

 RFC name: expires

 Description:
   Seconds to expiration.
 Example:
   Expires: 5
 Parts:
   RFC Name          accessor        reSIP type      settable
   ----------------------------------------------------------
                     value()         int             yes

RFC Headers:

  • Expires

Mime[edit]

 RFC name:
   media-type
 Description:
   Mime type and sub-type.
 Example:
   Content-Type: application/sdp
 Parts:
   RFC Name          accessor        reSIP type      settable
   ----------------------------------------------------------
   m-type            type()          Data            yes
   m-subtype         subType()       Data            yes

RFC Headers:

  • Accept multi-valued
  • Content-Type

NameAddr[edit]

 RFC name:
   name-addr
 Description:
   URI and display name.
 Example:
   To: Bob <sip:bob@biloxi.com>
 Parts:
   RFC Name          accessor        reSIP type      settable
   ----------------------------------------------------------
   display-name      displayName()   Data            yes
   addr-spec         uri()           Uri             yes

RFC Headers:

  • Contact multi-valued
  • From
  • Record-Route multi-valued
  • Refer-To
  • Referred-By
  • Reply-To
  • Route multi-valued
  • To

StringCategory[edit]

 RFC name:
   TEXT-UTF8-TRIM
 Description:
   Unstructured human readable text.
 Example:
   Organization: Boxes by Bob
 Parts:
   RFC Name          accessor        reSIP type      settable
   ----------------------------------------------------------
                     value()         Data            yes

RFC Headers:

  • Content-Transfer-Encoding
  • Organization
  • Server
  • Subject
  • User-Agent
  • Timestamp
  • Extension Header multi-valued

Token[edit]

 RFC name:
   token
 Description:
   A word.
 Example:
   Accept-Encoding: gzip
 Parts:
   RFC Name          accessor        reSIP type      settable
   ----------------------------------------------------------
                     value()         Data            yes

RFC Headers:

  • Accept-Encoding multi-valued
  • Accept-Language multi-valued
  • Allow multi-valued
  • Allow-Events multi-valued
  • Content-Disposition
  • Content-Encoding
  • Content-Language multi-valued
  • Event
  • Mime-Version
  • Priority
  • Proxy-Require multi-valued
  • Require multi-valued
  • Security-Client multi-valued
  • Security-Server multi-valued
  • Security-Verify multi-valued
  • Subscription-State multi-valued
  • Supported multi-valued
  • Unsupported multi-valued

UInt32Category[edit]

 RFC name:
   1*DIGIT
 Description:
   An integer.
 Example:
   Max-Forwards: 70
 Parts:
   RFC Name          accessor        reSIP type      settable
   ----------------------------------------------------------
                     value()         int             yes
   comment           comment()       Data            yes

RFC Headers:

  • Content-Length does not permit (comment) but reSIP does
  • Max-Forwards does not permit (comment) but reSIP does
  • Min-Expires does not permit (comment) but reSIP does
  • Retry-After

Via[edit]

 RFC name:
   via-parm
 Description:
   Via entry.
 Example:
   Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds
 Parts:
   RFC Name          accessor          reSIP type      settable
   ------------------------------------------------------------
   protocol-name     protocolName()    Data            yes
   protocol-version  protocolVersion() Data            yes
   transport         transport()       Data            yes
   host              sentHost()        Data            yes
   port              sentPort()        int             yes

RFC RFC Headers:

  • Via (multi-valued)

WarningCategory[edit]

 RFC name:
   warning-value
 Description:

 Example:

 Parts:
   RFC Name          accessor      reSIP type      settable
   --------------------------------------------------------
   warn-code         code()        int             yes
   warn-agent        hostname()    Data            yes
   warn-text         text()        Data            yes

RFC Headers:

  • Warning multi-valued

Parameters[edit]

Parameters are accessed from headers. The syntax is similar to header access. Like headers, there is an overloaded accessor method. For parameters, this method is param. The argument to param is a parameter type token indicating the parameter to be accessed. The parameter type token always begins with "p_" and the rest is camelCase starting with a lowercase.

For example:

const Data& tag = msg->header(h_To).param(p_tag);

Like headers, there is also an overloaded exists method and an overloaded remove method. For both methods, the argument is again the parameter type token.

According to the grammar, each header has a set of acceptable parameters. Some headers accept no parameters. reSIP makes a simplifying assumption; all headers can have all parameters. While it is the goal of reSIP that every legal SIP message be parseable, reSIP does not strictly enforce production of legal SIP. In practice, correct usage will result in legal SIP, but it is not very difficult to use reSIP to produce a problematic message. Take home lesson -- the reSIP programmer must take responsibilty when adding parameters to a header.

A corollary to this simplifying assumption is that the form of a parameter is independent of the header it appears in. A ttl parameter must always be followed by an integer even when used in a header that does not specify the syntax for a ttl parameter. (!dlb! potential compatibility issue)

Parameters, like headers, corresponds to a small set of classes that manage parsing, accesing, and serializing to text.

RFC namereSIP access tokenreSIP type
+sip.instancep_InstanceQuotedDataParameter
access-typep_accessTypeDataParameter
actorp_actorQuotedDataParameter
algorithmp_algorithmDataParameter
app-idp_appIdDataParameter
applicationp_applicationExistsParameter
boundaryp_boundaryDataParameter
branchp_branchBranchParameter
charsetp_charsetDataParameter
cnoncep_cnonceQuotedDataParameter
compp_compDataParameter
controlp_controlExistsParameter
d-algp_dAlgDataParameter
d-qopp_dQopDataParameter
d-verp_dVerQuotedDataParameter
datap_dataExistsParameter
descriptionp_descriptionQuotedDataParameter
directoryp_directoryDataParameter
documentp_documentDataParameter
domainp_domainQuotedDataParameter
durationp_durationUInt32Parameter
early-onlyp_earlyOnlyExistsParameter
effective-byp_effectiveByUInt32Parameter
eventsp_eventsQuotedDataParameter
expirationp_expirationQuotedDataParameter
expiresp_expiresUInt32Parameter
extp_extensionDataParameter
extensionsp_extensionsQuotedDataParameter
filenamep_filenameDataParameter
from-tagp_fromTagDataParameter
grp_grExistsOrDataParameter
handlingp_handlingDataParameter
idp_idDataParameter
isfocusp_isfocusExistsParameter
languagep_languageQuotedDataParameter
lrp_lrExistsParameter
maddrp_maddrDataParameter
methodp_methodDataParameter
methodsp_methodsQuotedDataParameter
micalgp_micalgDataParameter
mobilityp_mobilityQuotedDataParameter
modep_modeDataParameter
modelp_modelQuotedDataParameter
namep_nameDataParameter
ncp_ncDataParameter
network-userp_networkUserDataParameter
noncep_nonceQuotedDataParameter
obp_obExistsParameter
opaquep_opaqueQuotedDataParameter
permissionp_permissionDataParameter
priorityp_priorityQuotedDataParameter
profile-typep_profileTypeDataParameter
protocolp_protocolQuotedDataParameter
pub-gruup_pubGruuQuotedDataParameter
purposep_purposeDataParameter
qp_qQValueParameter
qopp_qopDataParameter
realmp_realmQuotedDataParameter
reasonp_reasonDataParameter
receivedp_receivedDataParameter
refresherp_refresherDataParameter
reg-idp_regidUInt32Parameter
responsep_responseQuotedDataParameter
retry-afterp_retryAfterUInt32Parameter
rinstancep_rinstanceDataParameter
rportp_rportRportParameter
schemesp_schemesQuotedDataParameter
serverp_serverDataParameter
sigcomp-idp_sigcompIdQuotedDataParameter
sitep_siteDataParameter
sizep_sizeDataParameter
smime-typep_smimeTypeDataParameter
stalep_staleDataParameter
tagp_tagDataParameter
temp-gruup_tempGruuQuotedDataParameter
textp_textExistsOrDataParameter
to-tagp_toTagDataParameter
transportp_transportDataParameter
ttlp_ttlUInt32Parameter
typep_typeQuotedDataParameter
urip_uriQuotedDataParameter
urlp_urlQuotedDataParameter
userp_userDataParameter
usernamep_usernameDataParameter or QuotedDataParameter
vendorp_vendorQuotedDataParameter
versionp_versionQuotedDataParameter
videop_videoExistsParameter

BranchParameter[edit]

 RFC name:
   
 Description:
   May have RFC 3261 marker, may have reSIP specific data, may have client
   data.
 Example:
   Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds
 Parts:
   accessor                    reSIP type      settable
   ----------------------------------------------------
   hasMagicCookie()            bool            no
   getTransactionId()          Data            no
   incrementTransportSequence  void            no
   reset(const Data&)          void            yes
   clientData()                Data            yes

RCF Parameters:

  • branch

DataParameter[edit]

 RFC name:
   token
 Description:
   Quoted or unquoted. Unquoted must be single word.
 Example:
   Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds
 Parts:
   accessor                reSIP type      settable
   ------------------------------------------------
   value()                 Data            yes
   isQuoted()              bool            no
   setQuoted(bool)         void            yes

RFC parameters:

  • access-type
  • algorithm
  • boundary
  • charset
  • comp
  • d-alg
  • d-qop
  • directory
  • filename
  • from-tag
  • handling
  • id
  • maddr
  • method
  • micalg
  • mode
  • name
  • nc
  • permission
  • purpose
  • reason
  • received
  • require
  • rinstance
  • server
  • site
  • size
  • smime-type
  • stale
  • tag
  • to-tag
  • transport
  • user
  • extension
  • username
  • refresher
  • profile-type
  • document
  • app-id
  • network-user
  • qop

ExistsOrDataParameter[edit]

 RFC name:

 Description:
   Either has no value; and is not followed by "=" or 
   contains a Data token Quoted or unquoted. Unquoted must be single word.
 Example:
   Reason: SIP ;cause=200 ;text="Call completed elsewhere"
 Parts:
   accessor                reSIP type      settable
   ------------------------------------------------
   value()                 Data            yes
   isQuoted()              bool            no
   setQuoted(bool)         void            yes

RFC parameters:

  • text
  • gr

ExistsParameter[edit]

 RFC name:

 Description:
   Has no value; is not followed by "=".
 Example:
   Record-Route: <sip:p1.example.com;lr>
 Parts:
   accessor                reSIP type      settable
   ------------------------------------------------
   value()                 bool            yes

RFC parameters:

  • data
  • control
  • application
  • video
  • isfocus
  • ob
  • lr
  • early-only

IntegerParameter[edit]

 RFC name:

 Description:
   Integer
 Example:
   sip:alice@atlanta.com;maddr=239.255.255.1;ttl=15
 Parts:
   accessor                reSIP type      settable
   ------------------------------------------------
   value()                 int             yes

RFC parameters:

QValueParameter[edit]

 RFC name:
   qvalue
 Description:
   0-1 inclusive, up to three digits after decimal point.
 Example:
   Accept-Language: da, en-gb;q=0.8, en;q=0.7
 Parts:
   accessor                reSIP type      settable
   ------------------------------------------------
   value()                 QValue          yes
   qval()                  int (0-1000)    yes

RFC parameters:

  • q

QuotedDataParameter[edit]

 RFC name:
   quoted-string
 Description:
   Quoted text.
 Example:
   Authorization: Digest username="bob",
                  realm="biloxi.com",
                  nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
                  uri="sip:bob@biloxi.com",
                  qop=auth,
                  nc=00000001,
                  cnonce="0a4f113b",
                  response="6629fae49393a05397450978507c4ef1",
                  opaque="5ccc069c403ebaf9f0171e9517f40e41"
 Parts:
   accessor                reSIP type      settable
   ------------------------------------------------
   value()                 Data             yes

RFC Parameters:

  • mobility
  • description
  • events
  • priority
  • methods
  • schemes
  • language
  • type
  • actor
  • extensions
  • +sip.instance
  • pub-gruu
  • temp-gruu
  • cnonce
  • d-ver
  • domain
  • expiration
  • nonce
  • opaque
  • protocol
  • realm
  • response
  • uri
  • vendor
  • model
  • version
  • url
  • sigcomp-id

RportParameter[edit]

 RFC name:
   rport
 Description:
   May have a value or not.
 Example:
   Via: SIP/2.0/UDP whistler.gloo.net:6064;rport=6064;received=192.168.2.220;branch=z9hG4bK-kcD23-4-1
 Parts:
   accessor            reSIP type      settable
   --------------------------------------------
    port()             int             yes
    hasValue()         bool            no

RFC Parameters:

  • rport

UInt32Parameter[edit]

 RFC name:

 Description:
   Integer
 Example:
   sip:alice@atlanta.com;maddr=239.255.255.1;ttl=15
 Parts:
   accessor                reSIP type      settable
   ------------------------------------------------
   value()                 UInt32          yes

RFC Parameters:

  • reg-id
  • duration
  • expires
  • retry-after
  • ttl
  • effective-by


MethodTypes[edit]

  • ACK
  • BYE
  • CANCEL
  • INVITE
  • NOTIFY
  • OPTIONS
  • REFER
  • REGISTER
  • SUBSCRIBE
  • RESPONSE
  • MESSAGE
  • INFO
  • PRACK
  • PUBLISH
  • SERVICE
  • UPDATE

Uri[edit]

 RFC name:
   addr-spec
 Description:
   URI
 Example:
    sip:alice:secretword@atlanta.com;transport=tcp
 Parts:
   RFC Name          accessor          reSIP type      settable                                      
   ------------------------------------------------------------                                      
   header            embedded()        SipMessage      yes                                           
   userinfo+hostport getAor()          Data            no                                            
   userinfo+host     getAorNoPort()    Data            no                                            
                     hasEmbedded()     bool            no                                            
   host              host()            Data            yes                                           
   host              opaque()          Data            yes                                           
   password          password()        Data            yes                                           
   port              port()            int             yes                                           
   userinfo          user()            Data            yes  // note: does not include user parameters
                     userParameters()  Data            yes
                     scheme()          Data            yes

Uri Parameters[edit]

A URI can have parameters. This can be confusing when a Uri is part of a NameAddr header which can also have parameters. The NameAddr parameters can be disambiguated from the Uri parameters by enclosing the Uri in angle brackets. However, in general, parameter attribution can be ambiguous. When parameters can be interpreted to belong the either a Uri or NameAddr, the Uri receives the parameters:

  • maddr
  • ttl,
  • user
  • method
  • lr

The NameAddr receives any remaining parameters.

Contents[edit]

 RFC name:
   message-body
 Description:
   Base class for all content types. Each derived content type defines its own
   parse, accessors and stream rendering.
 Example:

     --boundary42
     Content-Type: message/sip

     INVITE sip:bob@biloxi.com SIP/2.0
     Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8
     To: Bob <bob@biloxi.com>
     From: Alice <alice@atlanta.com>;tag=1928301774
     Call-ID: a84b4c76e66710
     CSeq: 314159 INVITE
     Max-Forwards: 70
     Date: Thu, 21 Feb 2002 13:02:03 GMT
     Contact: <sip:alice@pc33.atlanta.com>
     Content-Type: application/sdp
     Content-Length: 147

     v=0
     o=UserA 2890844526 2890844526 IN IP4 here.com
     s=Session SDP
     c=IN IP4 pc33.atlanta.com
     t=0 0
     m=audio 49172 RTP/AVP 0
     a=rtpmap:0 PCMU/8000

     --boundary42
     Content-Type: application/pkcs7-signature; name=smime.p7s
     Content-Transfer-Encoding: base64
     Content-Disposition: attachment; filename=smime.p7s;
        handling=required

     ghyHhHUujhJhjH77n8HHGTrfvbnj756tbB9HG4VQpfyF467GhIGfHfYT6
     4VQpfyF467GhIGfHfYT6jH77n8HHGghyHhHUujhJh756tbB9HGTrfvbnj
     n8HHGTrfvhJhjH776tbB9HG4VQbnj7567GhIGfHfYT6ghyHhHUujpfyF4
     7GhIGfHfYT64VQbnj756

     --boundary42-
 Parts:
   accessor                   reSIP type      settable  notes                                      
   ----------------------------------------------------------
   exists                     bool            no
   remove                     void	       no
   header		       <various>       yes 
     // shared header types 
     H_ContentType::Type& header(const H_ContentType& headerType) const; 
     H_ContentDisposition::Type& header(const H_ContentDisposition& headerType) const; 
     H_ContentTransferEncoding::Type& header(const H_ContentTransferEncoding& headerType) const; 
     H_ContentLanguages::Type& header(const H_ContentLanguages& headerType) const; 

     // MIME specific header types 
     H_ContentID::Type& header(const H_ContentID& headerType) const; 
     H_ContentDescription::Type& header(const H_ContentDescription& headerType) const; 

     int& verion() {return mVersion;} 
     int& minorVersion() {return mMinorVersion;}

Declaring a Contents Type[edit]

class NewContents : public Contents
{
   public:
      static const NewContents Empty;
      NewContents();
      NewContents(const Data& text);
      NewContents(HeaderFieldValue* hfv, const Mime& contentType);
      NewContents(const Data& data, const Mime& contentType);
      NewContents(const NewContents& rhs);
      virtual ~NewContents();
      NewContents& operator=(const NewContents& rhs);
      virtual Contents* clone() const;
      virtual Data getBodyData() const;
      static const Mime& getStaticType() ;
      virtual std::ostream& encodeParsed(std::ostream& str) const;
      virtual void parse(ParseBuffer& pb);
      // new content specific interfaces...
      static bool init();
   private:
      // new content specific store...
};

Defining a Contents Type[edit]

MultipartRelatedContents[edit]

MultipartMixedContents[edit]

MultipartSigned[edit]

SdpContents[edit]

Pkcs7Contents[edit]

OctetContents[edit]

SipMessage[edit]

SipMessage is an object-oriented representation of a message. A SipMessage can be created from the serialized form received from the wire or can be built up in an application and serialized and sent over the wire.

Headers[edit]

A detailed listing of the supported headers and their storage/parser type is here.

SipMessage has an array of built in headers and a list of unknown/extension headers. In either case, the header value or values are accessed with the overloaded header method and a header access token.

std::cerr << msg->header(h_To).uri().host() << std::endl;

The header access token is also used to check for the existence of a header:

if (msg->exists(h_Routes))
{
   ....

The header acesss token is also used to remove a header. It is not an error to remove a header that is not present in the message.

msg->remove(h_Warnings);

The header method will create a header value if the request header is not present in the message and the message is not const. So headers can be added to non-const messages simply by accessing the header.

msg->header(h_To) = NameAddr("Joe <joseph@example.com>");

If the message is const, accessing a header that is not present in the message will raise a SipMessage::Exception. Often, a SIP element will check if the header exists before accessing it rather than handle the exception.

Some headers have multiple values. The values of a multi-valued header are maintained in a container class named after the type contained. For example, msg->header(h_Contacts) returns a reference to NameAddrs. The containers have STL container syntax.

for (NameAddrs::const_iterator i = msg->header(h_Contacts).begin(); i != msg->header(h_Contacts.end(); ++i)
{
    const NameAddr& na = *i;
    ...;

Multi-valued header values correspond to comma separated values with one header or multiple header lines each with their own header. When serialized to the wire, multiple values are emitted comma separated.

Contents[edit]

reSIP represents a message body as a derived Content instance. The contents instance associated with the SipMessage is accessible:

SdpContents* sdp = dynamic_cast<SdpContents*>(msg->getContents());

SipMessage also acts somewhat like an auto_ptr<Contents>. SipMessage supports releaseContents() and

std::auto_ptr<Contents> contents(new SdpContents));
// populate the sdp... then set into message
msg->setContents(contents);

The setContents that takes a Contents* copies the contents through the pointer before assigning it to the SipMessage.

Other Interfaces[edit]

SipMessage can deterine if it is a request:

if (msg->isRequest())
{
    ...

SipMessage can determine if it is a response:

if (msg->isResponse())
{
    ...

A message can be neither a request or a response if it is locally created (as opposed to being deserialzed from the wire) and has neither a request nor status line.

New Content Type[edit]

Extension Header[edit]

SIP is an open specification. Elements may add headers that are not generally known. Extension headers are always of type StringCategory and are multiple valued but not comma separated. Extension headers may have parameters, however, not all stacks will consider semi-colons in extension headers significant, so extension header parameters may cause interop problems.

Extension headers are declared, for example:

static const resip::ExtensionHeader h_XFoos("X-Foo");

They are used similarly to built-in headers; the h_XFoos declared above is a header access token.

msg->header(h_XFoos).push_back(StringCategory("value"));

Extension parameters[edit]

SIP is an open specification. Elements may add parameters that are not generally known. Extension parameters are always of type Data. An extension parameter may not have a value; that is, it can act as an exists parameter. An extension parameter may occur on any header including an extension header.

Extension parameters are declared, for example:

static const resip::ExtensionParameter p_xstid("x-stid");

Extension parameters are be used like other parameters:

msg->header(h_To).param(p_xstid) = "2134";


Header Access Via Strings[edit]

Sometimes it is desirable to access SIP header information using strings instead of using the header type objects discussed above. This is especially useful when wanting to make behavior externally configurable (ie. a datastore or configuration file). For example: If header X contains some string Y, then reject a request - where X and Y are runtime configurable parameters and not known at compilation time.

Sample Code:

  // Check to see if it is a standard header
  Headers::Type headerType = Headers::getType(headerName.c_str(), headerName.size());
  if(headerType != Headers::UNKNOWN)
  {
     Data headerData;
     const HeaderFieldValueList* hfv = msg.getRawHeader(headerType);
     for(HeaderFieldValueList::const_iterator it = hfv->begin(); it != hfv->end(); it++)
     {
        it->toShareData(headerData);
        // Do something with headerData.....
     }
  }
  else // Check if custom header
  {
     ExtensionHeader exHeader(headerName);
     if(msg.exists(exHeader))
     {
        const StringCategories& exHeaders = msg.header(exHeader);
        for(StringCategories::const_iterator it = exHeaders.begin(); it != exHeaders.end(); it++)
        {
           // Do something with it->value()
        }
     }
  }