The following sections describe how to use the SIP Client API.
Create CSIP and CSIPConnection objects to use the SIP Client API:
iSIP = CSIP::NewL(KAppUid, *iMySIPObserver); iConnection = CSIPConnection::NewL(*iSIP, KIapIdentifier,*iMyConnectionObserver);
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.
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
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; } } }
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; }
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);
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;
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 } }
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);
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 } }