📄 using.txt
字号:
January 26. 2004
Using reSIProcate.
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:
=======
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.
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 a existing message, fetching the To header is simply:
<code>
const NameAddr& to = message->header(h_To);
</code>
The header methods are both accessors and setters. Accessing a header that isn't
in the message creates the header in a default state. So to set an empty message's
To header:
<code>
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");
</code>
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.
<code>
SipMessage* message;
if (!message->exists(h_To))
{
// complain bitterly
...
}
else
{
NameAddr& to = message->header(h_To);
...
}
</code>
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.
<code>
try
{
const SipMessage* message;
To::Type& to = message->header(h_To);
...
}
catch (SipMessage::Exception e)
{
// complain bitterly
...
}
</code>
The remove method is also overloaded for the access tokens. Removing a header
that does not exist is a no-op.
<code>
SipMessage* message = ...;
message->remove(h_RecordRoutes);
</code>
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 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.
<code>
NameAddrs& rr = message.header(h_RecordRoutes);
</code>
The collection of header values can be iterated in the usual stl like fashion.
<code>
for (NameAddrs::iterator i = rr.begin(); i != rr.end(); ++i)
{
NameAddr& r = *i;
...
}
</code>
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.
<code>
NameAddr na;
na.displayName() = "Alice";
na.uri() = Uri("sip:alice@company.com");
rr.push_back(na);
</code>
--
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:
<code>
if (message->isRequest())
{
...
}
</code>
Similarly for Status Line:
<code>
if (message->isResponse())
{
...
}
</code>
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:
====
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.
<code>
Pkcs7* pres = new Pkcs7();
...
message->setContents(pres);
</code>
Recursive multipart contents are supported.
--
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.
Table of headers
================
RFC name reSIP access token reSIP type
----------------------------------------------------------------
Accept h_Accepts Mimes
Accept-Encoding h_AcceptEncodings Tokens
Accept-Language h_AcceptLanguages Tokens
Alert-Info h_AlertInfos GenericUris
Allow h_Allows Tokens
Authentication-Info h_AuthenticationInfos Auths
Authorization h_Authorizations Auths
Call-ID h_CallID, h_CallId CallID, CallId
Call-Info h_CallInfos GenericUris
Contact h_Contacts NameAddrs
Content-Disposition h_ContentDisposition Token
Content-Encoding h_ContentEncoding Token
Content-Language h_ContentLanguages Tokens
Content-Length h_ContentLength IntegerCategory
Content-Type h_ContentType Mime
Content-Transfer-Encoding h_ContentTransferEncoding StringCategory
CSeq h_CSeq CSeqCategory
Date h_Date DateCategory
Error-Info h_ErrorInfos GenericUris
Expires h_Expires IntegerCategory
From h_From NameAddr
In-ReplyTo h_InReplyTo CallID, CallId
Max-Forwards h_MaxForwards IntegerCategory
MIME-Version h_MIMEVersion Tokens
Min-Expires h_MinExpires IntegerCategory
Organization h_Organization StringCategory
Priority h_Priority Token
Proxy-Authenticate h_ProxyAuthenticates Auths
Proxy-Authorization h_ProxyAuthorizations Auths
Proxy-Require h_ProxyRequires Tokens
Record-Route h_RecordRoutes NameAddrs
Reply-To h_ReplyTo NameAddr
Require h_Requires Tokens
Retry-After h_RetryAfter IntegerCategory
Route h_Routes NameAddrs
Server h_Server StringCategory
Subject h_Subject StringCategory
Supported h_Supporteds Tokens
Timestamp h_Timestamp StringCategory
To h_To NameAddr
Unsupported h_Unsupporteds Tokens
User-Agent h_UserAgent StringCategory
Via h_Vias Vias
Warning h_Warnings WarningCategories
WWW-Authenticate h_WWWAuthenticates Auths
(!dlb!: const headers accessors return non-const references -- should have const
and non-const versions of all settable accessors)
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 (*).
Table of reSIP header types
==========================
RequestLine
===========
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
==========
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 responseCode() int yes // dlb should be statusCode()
SIP-Version getSipVersion() Data no
Reason-Phrase reason() Data yes
RFC Headers:
<none>
Auth
====
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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -