A session is an exchange of data between an association of participants. For example, a multimedia conference. A callee can be invited several times, by different calls, to the same session.
The Session Initiation Protocol (SIP) is an application layer control protocol that can establish, modify and terminate the multimedia sessions or calls. These multimedia sessions include multimedia conferences, distance learning, Internet telephony and similar applications. The data exchange within a session such as, the encoding or codec related to an audio/video media is taken care of by other protocols such as SDP (Session Description Protocol) and RTP. Refer to RFC 3261 for more details.
In addition to the APIs provided by the SIP stack, a high level API
encapsulating the SIP call flows inside the well published and used
RConnection
and RSubConnection
APIs
is also available. This is included in the Symbian OS from 9.2 version onwards.
A subset of the following SIP functionality is currently supported using
RConnection
and RSubConnection
APIs:
Both INVITE
and SUBSCRIBE
methods need
registration as a prerequisite. CSubConSIPInviteParamSet
and CSubConSIPSubscribeParamSet
classes provide the
related parameters.
An endpoint (can be a SIP enabled phone) which wants to initiate a SIP
session needs to register itself to a registrar. Registering with the SIP
Registrar is done using RConnection
. Refer to,
Connection Management, for
more details on RConnection
. ESOCK
provides
an interface for the user to access the SIP high level API. ESOCK interacts
with SIP high level API through Connection and SubConnection providers.
Connection and SubConnection providers are ESOCK
server side
components that will get loaded and called when
RConnection
and RSubConnection
API(s)
are used.
The figure shows the architecture layer where the application interacts
with SIP connection providers using SIPPARAMS. The second layer comprising of
RSocket
, RSubConnection
and
RConnection
constitutes the SIPPARAMS.
SIP high level API models the SIP with Connection and SubConnection Providers and thus makes it stackable against the unified comms-infras architecture. This enables the future connection convergence.
A profile data store is required to get registered with the SIP Registrar . A SIP registration profile is a data store containing the vital information required for registration such as AOR (IP address of registrar), etc.
The data profile must contain the following fields:
data profile type : internet,ims,others
profile name ietf, ims, others
IAP name
profile AOR list (IP address)
autoregistration
private ID
secutrity negotitiation
sigcomp
server ( IP address of registrar, outbound proxy)
server param (username, realm, pwd)
default
Manual registration is not possible by specifying parameters. If
connection details are not available, the connection is set up using the
default profile.flag
file.
Create an RConnection
to register to the SIP
Registrar using the following steps. RConnection
needs to
be opened on an existing socket server session,
RSocketServ
.
RSocketServ socketServer; // Create a client interface object to the socket server
RConnection con; // Create an RConnection object
TRequestStatus status = KErrNone; // object to hold the request completion status
// Establish the connection to the Socket server
User::LeaveIfError(socketServer.Connect()); // Returns KErrorNone if the connection is successful
CleanupClosePushL(socketServer);
TUint KAFSip = 0x10000; //SIP protocol family id
TInt err = con.Open (socketServer,KAFSip); //open the connection
TInt err1 = con.Start(); // Start Rconnection to initiate the registration
Once registration to the SIP registrar is successful,
RSubConnection
can be used to establish the SIP Invite or
SIP Subscribe session.
The RConnection
and
RSubConnection
that is established and opened can be used
for either inviting a call session or subscribing for the message status.
SIPPARAMS is used to simplify the interaction with the SIP stack by
abstracting the SIP functionality using the RConnection
and the RSubConnection
APIs. It currently supports basic
SIP functionality. However, the complete SIP functionality is made available
through the SIP stack APIs.
RSubConnection
is used to establish a SIP Invite
session. An invitation can be, for setting up of a voice call, a game session
etc.
A SIP invitation starts when an endpoint (VoIP Softphone, VoIP Hardware) tries to establish a session with a remote compliant endpoint. A successful SIP invitation consists of an INVITE-OK-ACK triplet message exchange. The calling endpoint tries to start a session with SIP INVITE. This is followed by OK from the called endpoint, and by ACK from the calling endpoint that finally establishes the SIP session.
A SIP session can be terminated by using BYE-200OK message exchange. Either the calling or the called party can initiate the termination.
RSubConnection
establishes the SIP session using
the three way handshake of INVITE-OK-ACK and terminates the call using
BYE-200OK.
RSubConnection
when used on behalf of the calling
endpoint, will handle the message exchange independently and provide the status
such as whether the session is established, denied or not reachable. The
calling endpoint must fill up the necessary SIP session parameters that will be
used to determine the target.
RSubConnection
when used on behalf of the called
endpoint will alert the user of an incoming call (SIP invitation). The incoming
call can be either accepted or rejected using
RSubConnection
. The application will be notified about the
outcome. The information about the calling endpoint will be provided in set of
specific parameters.
The SIP parameters for an outgoing call can be set using
CSubConSIPInviteParamSet
class. The code fragment below
shows how to initiate a call. It assumes that you have already registered with
the SIP registrar by creating an RConnection
object and called
Open()
on it as outlined in Creating an RConnection.
RSubConnection subCon; // Create an RSubConnection object
err=subCon.Open(socketServer,RSubConnection::ECreateNew,con); // Open subconnection onto the Rconnection
Set the SIP Invite parameters.
RSubConParameterBundle sipBundle; // create parameter bundle
// create SIP parameter set family
CSubConParameterFamily * family = CSubConParameterFamily::NewL(sipBundle,KSubConnCallDescrParamsFamily);
// create invite parameter set object
CSubConSIPInviteParamSet* sip = CSubConSIPInviteParamSet::NewL(*family,CSubConParameterFamily::ERequested);
Set the SIP header values to the parameter set.
_LIT8(KTo,"Sip:[email protected]"); // 'To' header, SIP URI of called endpoint
TPtrC8 ptrTo(KTo());
sip->SetToL(ptrTo); // Set'To', the target SIP URI to the SIP parameter set
_LIT8(KFrom, "Sip:[email protected]"); // 'From' header, SIP URI of calling endPoint
TPtrC8 ptrFrom(KFrom());
sip->SetFromL(ptrFrom); // Set the 'From' header field to the SIP parameter set
_LIT8(KContact,"Sip:[email protected]"); // 'Contact' header, the actual location of the calling endpoint
TPtrC8 ptrContact (KContact());
sip->SetContactL(ptrContact); //Set the 'Contact' to the SIP parameter set
_LIT8(KRemoteUri, "Sip:[email protected]"); // Remote URI, the actual Next hop or the Target
TPtrC8 ptrRemoteUri(KRemoteUri());
sip->SetRemoteUriL(ptrRemoteUri); // Set the 'RemoteUri' to the SIP parameter set
TInt err = SubCon.SetParameters(sipBundle); // Set The SIP parameters in the SubConnection
sipBundle.Close(); //close the parameter bundle
To establish the SIP Invite session, start the subconnection using
RSubConnection
. This initiates the Invite request.
//Start the subconnection, effectively sending an Invite
TInt subConRet = subCon.Start();
// Session is established
SIP supports subscription to events, for example, message waiting, to notify the subscriber about the current state of the event and any changes to its state.
An endpoint can subscribe to a specific service using a SIP SUBSCRIBE-200OK message exchange. The end point will be notified by means of a NOTIFY-200OK message exchange.
To send the subscription and receive notifications use
RSubConnection
. RSubConnection
is also used
to unsubscribe, which stops any further notifications.
The following code fragment shows how you can subscribe to a session
and receive notifications. It assumes that you have already registered with the
SIP registrar by creating an RConnection
object and called
Open()
on it as outlined in Creating an RConnection.
RSubConnection subCon;// Create an RSubConnection object
// Open subconnection onto the Rconnection
err=subCon.Open(socketServer,RSubConnection::ECreateNew,con);
Set the SIP Subscribe parameters using
CSubConSIPSubscribeParamSet
. This class provides the SIP
subscribe parameters that will be passed through the subconnection to the SIP
stack.
RSubConParameterBundle sipBundle; // create parameter bundle
//create SIP parameter set family
CSubConParameterFamily * family = CSubConParameterFamily::NewL(sipBundle,KSubConnCallDescrParamsFamily);
// create subscribe parameter set object
CSubConSIPSubscribeParamSet* sip = CSubConSIPSubscribeParamSet::NewL(*family,CSubConParameterFamily::ERequested);
Set to
, from
, contact
and
reqURI
header values to the SIP subscribe parameter set as
outlined in Initiating a session using INVITE.
// Set required information
_LIT8(KEventType, "messagewaiting"); // subscription event type
TPtrC8 ptrEventType (KEventType());
sip->SetEventTypeL(ptrEventType); //Set the subscription event type to 'messagewaiting'
_LIT8(KAcceptType, "application"); //accept type
TPtrC8 ptrAcceptType(KAcceptType());
sip->SetAcceptTypeL(ptrAcceptType); //set the accept type field to 'application'
_LIT8(KAcceptSubType, "indication"); //accept subtype
TPtrC8 ptrAcceptSubType(KAcceptSubType());
sip->SetAcceptSubTypeL(ptrAcceptSubType); //set the accept subtype
sip->SetExpires(3600); // set the subscription Refresh timings
sip->SetAutoRefresh(ETrue); // set Auto Refresh to 'on'
// pass SIP subscribe parameters via the subconnection
Tint err = subCon.SetParameters(sipBundle);
sipBundle.Close(); //close the parameter bundle
subCon.Start(); // Start the subscription
To receive notifications to the subscribed events,
CSubConSIPNotificationEvent
class is used.
// Wait and receive notifications to events
while(ETrue)
{
TNotificationEventBuf evtBuf; // Sub-connection event notiifcation object
TRequestStatus reqStatus; // request status object
User::WaitForRequest(reqStatus);
TInt eventId = evtBuf.Id(); // get sub-type id
TInt groupId = evtBuf.GroupId(); // get group id of the event
}
if (eventId == KSubConSIPNotificationEventType && groupId == KSubConSIPEventsUid)
{
CSubConSIPNotificationEvent * evtRes = (CSubConSIPNotificationEvent*)CSubConNotificationEvent::NewL(evtBuf);
CleanupStack::PushL(evtRes);
....................
....................
CleanupStack::PopAndDestroy(evtRes);
// Since We do not want to receive more notifications in this stage, break from the loop.
break;
}
// we can wait again for another notification
subCon.EventNotification( evtBuf,EFalse, reqStatus); //request for notification
Unsubscribe to events and unregister, refer to steps outlined in Terminating the session.
A remote party or a server may require authentication before it allows an endpoint to establish a session with another endpoint.
RSubConnection
provides an authentication
mechanism where the authentication information such as realm, username and
password need to be provided while initiating the call. If a challenge is
received then RSubConnection
provides the realm and
initiates a new session with authentication parameters.
Authentication parameters can be set in a subconnection parameter bundle as shown in the code fragment below.
Set the SIP authenticate parameter set using
CSubConSIPSubscribeParamSet
. This class provides the SIP
authenticate parameter values that will be passed via the subconnection to the
SIP stack.
RSubConParameterBundle sipBundle; // create parameter bundle
// Add authorisation parameters as new family
CSubConParameterFamily * family1 = CSubConParameterFamily::NewL(sipBundle,KSubConAuthorisationFamily );
// create authenticate parameter set object
CSubConSIPAuthenticateParamSet * authParam = CSubConSIPAuthenticateParamSet::NewL(*family1,CSubConParameterFamily::ERequested);
Set to
, from
, contact
,
reqURI
header field values to the SIP authenticate parameter set,
similar to that in Initiating a session using INVITE section.
_LIT8(KRealm, "SFTF");
_LIT8(KUserName, "MyUserName");
_LIT8(KPwd, "pass123");
authParam->SetRealmL(KRealm); //set the Realm parameter
authParam->SetUserNameL(KUserName); // set the username
authParam->SetPasswordL(KPwd); //set the password
TInt err = subCon.SetParameters(sipBundle); //set the Authenticate parameters to the subconnection
sipBundle.Close(); //close the parameter bundle
To terminate the call session or unsubscribe to events and unregister, follow the steps given in Terminating the session.
To terminate the SIP INVITE/SUBSCRIBE session,
send BYE message by closing the RSubConnection
session
unregister with the SIP registrar by closing the
RConnection
session.
Int ret = subCon.Stop(); // Terminate the session, send BYE message
subCon.Close(); // close the subconnection
con.Stop(); // Terminate the connection
con.Close(); // Close the connection