Symbian
Symbian Developer Library

SYMBIAN OS V9.4

Feedback

[Index] [Previous] [Next]


How to use the SIP Client API

[Top]


Protocols

This section describes the sequence that you need to follow to get specifc tasks done:

[Top]


Starting the SIP Client


[Top]


Closing the SIP Client

The application can delete any owned API object at any time.

Deleting the CSIP object causes the connection to the SIP server to be closed.

Deleting the CSIPConnection object causes the sub-session between the client and the server to be closed.

If an application deletes an object on which other objects are dependent, this can render the other objects unusable. Functions called on objects that are in an unusable state leave with the error code KErrSIPResourceNotAvailable, indicating that they cannot perform the requested operation.

For example, if an application has CSIPConnection and CSIPRegistrationBinding objects, and it then deletes the CSIPConnection object, then in most cases, subsequent attempts to use the CSIPRegistrationBinding object will fail. This is because CSIPRegistrationBinding cannot communicate with the server side of the SIP stack without the CSIPConnection object.

The following diagram shows the recommended order for deleting SIP Client API objects.


[Top]


Sending a SIP request

To send a SIP request:

Note that SendRequestL() initiates the server side processing of sending the MESSAGE, but time consuming tasks such as address resolving and socket operations are done only after the SendRequestL() call has returned. If an error occurs after SendRequestL() returns, e.g. a failure in address resolution, then the error is communicated to the application through one of the MSIPConnectionObserver::ErrorOccured() callback functions. It is important to understand that when SendRequestL() returns, the MESSAGE has not yet been sent to the network, and is being processed on the server side of the SIP stack.

Once SendRequestL() has returned and the sending of a MESSAGE is in progress on the shared server, there is no way for the application to cancel that operation. This also applies to other operation types. However, note that the CSIPClientTransaction::CancelL() function can be used to send a SIP CANCEL request after the application has sent an INVITE request.

When the SIP response message is received from the server side, the CSIPConnection object:

The application can determine the kind of response received by accessing the CSIPResponseElements object through CSIPClientTransaction. As the response is provisional, the application does not delete the CSIPClientTransaction object. A '200 response' will be received later, and the application can then delete the CSIPClientTransaction object.

creates a CSIPResponseElements object to represent the SIP response, attaches it to CSIPClientTransaction and notifies the application with MSIPConnectionObserver:: IncomingResponse.

The following figure shows the seqence of events iinvolved in sending a MESSAGE request and receiving two responses to it.


[Top]


Receiving a SIP request

A stand-alone SIP request is received through an existing CSIPConnection object. This creates CSIPRequestElements and CSIPServerTransaction objects to represent the incoming SIP request, before notifying the application through a call to one of the MSIPConnectionObserver::IncomingRequest() callback functions.

The application fetches information about the request by accessing the CSIPRequestElements object through the CSIPServerTransaction object passed to it via the callback function.

To send a response, the application creates a CSIPResponseElements object and passes it to CSIPServerTransaction::SendResponseL(). This causes the response to be passed to the server side for further processing. Once SendResponseL() has returned, the application no longer needs the CSIPServerTransaction object and can delete it.

The following diagram shows the sequence of events involved in receiving a MESSAGE and sending a response to it.


[Top]


Receiving a SIP request and creating a session

The SIP stack receives a SIP INVITE request from the network acting as UAS and creates an invite server transaction for the received request.

The SIP stack sends a '100 SIP response' to the remote UA. After comparing the received request with the stored application capabilities, the SIP stack routes the received INVITE request to the chosen application.

The application creates a CSIPInviteDialogAssoc object and the SIP stack creates an instance of CSIPDialog.

The application sends a '200 SIP response' to the remote UA.

The remote UA acknowledges the '200 SIP' response with ACK and a SIP session is created between the local and remote UA.

The following diagram shows the sequence of events involved in receiving a SIP request and creating a SIP dialog.


[Top]


Registration

To initiate a registration, the application must first create a CSIPRefresh object, and then create a CSIPRegistrationBinding object, passing CSIPRefresh to it. It is not mandatory to create a CSIPRefresh object; it is only needed if the registration is to be refreshed by the SIP stack.

Once the CSIPRegistrationBinding object exists, the application can initiate the registration process by calling RegisterL() on the CSIPRegistrationBinding object. CSIPRegistrationBinding forms a REGISTER request and communicates it to the server side of the SIP stack, instantiates CSIPClientTransaction object and returns it to the application.

When the '200 SIP response' is received from the server side, CSIPConnection creates the CSIPResponseElements object to contain the response, and then routes the response to CSIPRegistrationBinding.

CSIPRegistrationBinding attaches the response to CSIPClientTransaction. The application is notified about the response through one of the MSIPConnectionObserver::IncomingResponse() callback functions.

The application no longer needs the CSIPClientTransaction object and can delete it. It can use IsContextActive() to find out whether the registration has succeeded.

The following figure shows the sequence of events involved in registering with a refresh and receiving a '200 OK response'.


[Top]


Creating a dialog with INVITE

To create a dialog, the application creates CSIPInviteDialogAssoc and CSIPMessageElements objects.

The application needs to fill in the relevant SIP headers in the CSIPMessageElements object before passing it to CSIPInviteDialogAssoc using the CSIPInviteDialogAssoc::SendInviteL() function.

CSIPInviteDialogAssoc then:

When the '180 response' is received from the server side, CSIPConnection creates a CSIPResponseElements object to contain the response, and then routes the response to CSIPDialog. CSIPDialog attaches the response to CSIPClientTransaction. The application is informed about the receipt of the '180 response' through a call to one of the MSIPConnectionObserver:: IncomingResponse() callback functions.

When the '200 response' is received, similar processing occurs as with the '180 response'.

At this point, the application is expected to respond by sending an ACK request. This is done by invoking the CSIPInviteDialogAssoc::SendAckL() function, which forms the ACK request and sends it to the server side of the SIP stack.

Since there is a possibility that the INVITE request might fork at a proxy, the SIP stack’s server side waits a while for several possible responses. When the forking is no longer expected to happen, the SIP stack’s server side sends an InviteCompleted event. The SIP Client API forwards the InviteCompleted event to the application, indicating that the application can now delete the CSIPClientTransaction.

The following figure shows the sequence of events involved in sending an INVITE, receiving a response and sending ACK.


[Top]


Generating a '100 SIP response'

Applications are not allowed to send '100 responses'. The SIP stack generates a '100 response' automatically when it receives an INVITE request from the network.

[Top]


Responding to a CANCEL request

When the SIP stack receives a CANCEL request from the network, it automatically responds to it. CANCEL requests are never passed to an application.

Once these actions are complete, the SIP stack informs the application by calling the MSIPConnectionObserver::InviteCanceled() callback function.

[Top]


Sending a SIP request and responding to a HTTP Digest challenge

A SIP server in the signalling chain can challenge any SIP request initiated by the application with an HTTP Digest challenge by responding with a '401 SIP response', '407 SIP response' or a '494 SIP response'. The responses contain details of the challenge. These responses are never passed directly to the application. Instead, they are passed to the application through a call to the callback function MSIPHttpDigestChallengeObserver::ChallengeReceived().

For an application to be able to respond to a challenge, it must:

The application can either accept or reject the challenge:

If an application does not wish to receive HTTP Digest challenges at all, it must not create a CSIPHttpDigest object. In this event, the SIP stack calls the callback function MSIPConnectionObserver::ErrorOccured(), passing the error code KErrSIPForbidden.

Note that:

[Top]


Notification of a failed refresh

The following example shows how an application is notified when a refresh request within a dialog terminates after an error occurs. In this example the application has sent a SUBSCRIBE with refresh, and received a 2xx class response to the initial SUBSCRIBE. The SIP stack periodically sends a refreshed SUBSCRIBE.

After a couple of successfully refreshed SUBSCRIBEs later the remote server responds with a '481 response', and the application receives the following callback:

MSIPConnectionObserver::ErrorOccured(TInt aError, CSIPDialogAssocBase& aDialogAssoc)

If the value of aError is KErrSIPTerminatedWithResponse, then the actual SIP response that caused the refresh to end can be found as follows:

[Top]


Error handling

Errors are passed to an application either by calling callback functions or by leaving. See Cleanup support overview.

If an error occurs during the synchronous part of an operation initiated by the application, functions leave with an error code.

If an error occurs later during the asynchronous processing stage, the error is passed to the application through one of the MSIPConnectionObserver::ErrorOccured() callback functions. There are several overloaded variants of ErrorOccured() functions, each of them taking the error code and reference(s) to the SIP Client API object(s) that encountered the error:

If the callback function MSIPConnectionObserver::ConnectionStateChanged()is called and the aState parameter is either CSIPConnection::EInactive or CSIPConnection::EUnavailable, then all dialogs, registrations and stand-alone transactions using the CSIPConnection will have been terminated. To avoid a flood of callback calls in this kind of situation, calls to ErrorOccured() for the individual dialog, registration and transaction objects are not sent to the application.