Examples Showing the use of the SIP Client API

The following sections describe how to use the SIP Client API.

SIP Client API dependent objects

Create CSIP and CSIPConnection objects to use the SIP Client API:

iSIP = CSIP::NewL(KAppUid, *iMySIPObserver);
iConnection = CSIPConnection::NewL(*iSIP, KIapIdentifier,*iMyConnectionObserver);

Publishing the SIP contact address of a user

Create a SIP registration to publish the SIP contact address of a user. The AOR and a contact must be registered. In this example, create CSIPRefresh to automatically refresh the SIP stack when it is registered.

In the following code, localhost indicates the request for the SIP stack to replace it with a local address. The sip:user@localhost means that the SIP stack replaces the localhost with the local IP address. An application uses CSIPRegistrationBinding class to handle SIP registration. The application can also use the profile agent API for handling registration. The profile agents implement all the necessary call flows or behaviour for handling registration for both IETF and 3GPP IMS type networks. For more information about the profile agent API, see SIP Profile Agent API.

CSIPToHeader* aor = CSIPToHeader::DecodeL(_L8("sip:user@remote.registrar"));
CleanupStack::PushL(aor);

CSIPAddress* addr = CSIPAddress::DecodeL(_L8("sip:user@LOCALHOST"));
CleanupStack::PushL(addr);
CSIPContactHeader* contact = CSIPContactHeader::NewL(addr);
CleanupStack::Pop(addr);
CleanupStack::PushL(contact);

CSIPRefresh* refresh = CSIPRefresh::NewLC();

iRegistration = CSIPRegistrationBinding::NewL(*iConnection, aor, contact, refresh);

CleanupStack::Pop(3); //refresh, contact, aor

Initiating a REGISTER transaction

Create a CSIPRegistrationBinding object to start a REGISTER transaction.

iRegisterTransaction = iRegistration->RegisterL();

When you receive a 2xx response, the registration is active. Delete the transaction when the final response is received.

void CMyConnectionObserver::IncomingResponse(CSIPClientTransaction& aTransaction, CSIPRegistrationBinding& aRegistration)
    {
    if (aRegistration.IsContextActive())
        {
        // Registration has succeeded
        }

    if (aTransaction.ResponseElements()->StatusCode() >= 200)
        {
        // Final response received, transaction is no longer needed

        if (aTransaction == *iRegisterTransaction)
            {
            delete iRegisterTransaction;
            iRegisterTransaction = NULL;
            }
        }
    }

Creating a CSIPConnection instance for a different IAP

An INVITE request is received from the network. In this example the INVITE is received through a different IAP that does not have a CSIPConnection. Create a CSIPConnection instance for this IAP.

void CMySIPObserver::IncomingRequest(TUint32 aIapId, CSIPServerTransaction* aTransaction)
    {
    // Create an observer for the new CSIPConnection
    TRAPD(err, iMyOtherConnectionObserver = CMyConnectionObserver::NewL());
    // Handle leave condition

    // Create a new connection for the IAP
    TRAP(err, iOtherConnection = CSIPConnection::NewL(*iSIP, aIapId,
                                   *iMyOtherConnectionObserver));
    // Handle leave condition

    // Application owns the transaction
    iInviteServerTransaction = aTransaction;
    }

Creating a SIP dialog while responding to the INVITE request

The INVITE request is received and the application sends a response (101-299). This creates a SIP dialog. Before sending the response, create a CSIPInviteDialogAssoc.

iInviteAssoc = CSIPInviteDialogAssoc::NewL(*iInviteServerTransaction);

CSIPResponseElements* response = CSIPResponseElements::NewLC(180, SIPStrings::StringF(SipStrConsts::EPhraseRinging));

iInviteServerTransaction->SendResponseL(response);
CleanupStack::Pop(response);

Deleting the transaction object

When the user accepts the INVITE, it sends a '200 response' using the same transaction object. When a 2xx response is sent to an INVITE transaction it enters the CSIPTransactionBase::ETerminated state. Then the transaction is deleted.

CSIPResponseElements* response = CSIPResponseElements::NewLC(200, SIPStrings::StringF(SipStrConsts::EPhraseOk));
            
iInviteServerTransaction->SendResponseL(response);
CleanupStack::Pop(response);

delete iInviteServerTransaction;
iInviteServerTransaction = NULL;

No response is sent to a received ACK

When the ACK request arrives, SIP Client API creates a CSIPServerTransaction and passes the transaction object to the application using the MSIPConnectionObserver of the IAP through which the ACK is received. If no response is sent to an ACK the transaction object is deleted.

void CMyConnectionObserver::IncomingRequest(CSIPServerTransaction* aTransaction, CSIPDialog& aDialog)
    {
    if (aTransaction.Type() == SIPStrings::StringF(SipStrConsts::EAck))
        {
        // Might inspect the Content part of the ACK for SDP etc.
       // No response will be sent to an ACK
        delete aTransaction;
        }
    else
        {
        // Handle other requests
        }
    }

Getting the transaction timers values

The following example code shows how to get the transaction timers values from the Central Repository (CenRep).

#include <centralrepository.h>
#include <SIPSDKCRKeys.h>
TInt timerT1 = 0;
TInt timerT2 = 0;
CRepository* repository = CRepository::NewLC(KCRUidSIP);
User::LeaveIfError(repository->Get(KSIPTransactionTimerT1,timerT1));
User::LeaveIfError(repository->Get(KSIPTransactionTimerT2,timerT2));
CleanupStack::PopAndDestroy(repository);

Extension header definitions with the SIP Client API

The following is an example of the extension header definitions with the SIP Client API. SIP clients use Extension headers to send or receive SIP messages with methods that do not have default handling support implemented in the stack.

void CMyClass::ExtractHeadersL( CSIPMessageElements& aElements )
    {
    const RPointerArray<CSIPHeaderBase>& userHeaders = aElements.UserHeaders();
    for ( TInt I = 0; I < userHeaders.Count(); I++ )
        {
        const CSIPHeaderBase* header = userHeaders[ I ];
        
        // An example of a known already supported header.
        // This can be casted to the actual class.
        // It will be supported also in the future and does not cause SC/BC problems.
        
        if ( header->Name() == SIPStrings::StringF( SipStrConsts::ERAckHeader ) )
             {
             iRAckHeader = static_cast<CSIPRAckHeader*>(header->CloneL());
             }
         
        // An example of a SIP header that is currently supported as an extension.
        // The application must NOT make a static cast to CSIPExtensionHeader.
        // Instead it must use CSIPHeaderBase::ToTextValueL and parse the result.
        
        RStringF extensionName = SIPStrings::Pool().OpenFStringL( L8("Extension") );
        CleanupClosePushL( extensionName ); 
        if ( header->Name() == extensionName )
            {
            HBufC8* headerValue = header->ToTextValueLC();
            
            // Do application specific parsing and handling for the header
 
            CleanupStack::PopAndDestroy( headerValue );
            }
        CleanupStack::PopAndDestroy( 1 ); // extensionName
        }
    }