Symbian3/SDK/Source/GUID-77E02E43-A72A-52DC-A22B-31FABE5B658D.dita
author Dominic Pinkman <dominic.pinkman@nokia.com>
Tue, 20 Jul 2010 12:00:49 +0100
changeset 13 48780e181b38
parent 0 89d6a7a84779
permissions -rw-r--r--
Week 28 contribution of SDK documentation content. See release notes for details. Fixes bugs Bug 1897 and Bug 1522.

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
<!-- This component and the accompanying materials are made available under the terms of the License 
"Eclipse Public License v1.0" which accompanies this distribution, 
and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
<!-- Initial Contributors:
    Nokia Corporation - initial contribution.
Contributors: 
-->
<!DOCTYPE concept
  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept xml:lang="en" id="GUID-77E02E43-A72A-52DC-A22B-31FABE5B658D"><title>Examples Showing the use of the SIP Client API</title><prolog><metadata><keywords/></metadata></prolog><conbody><p>The following sections describe how to use the SIP Client API. </p> <ul><li id="GUID-C9BF535A-9B75-5133-BBC5-3341A3671126"><p> <xref href="GUID-77E02E43-A72A-52DC-A22B-31FABE5B658D.dita#GUID-77E02E43-A72A-52DC-A22B-31FABE5B658D/GUID-6E3797D8-507F-5D7B-B601-DABCE95EC87C">SIP Client API dependent objects</xref>  </p> </li> <li id="GUID-22A2CB82-E384-5137-99E9-CE39FF248971"><p> <xref href="GUID-77E02E43-A72A-52DC-A22B-31FABE5B658D.dita#GUID-77E02E43-A72A-52DC-A22B-31FABE5B658D/GUID-0D3FB3DF-9316-554E-AC08-62C8D33B7F5E"> Publishing the SIP contact address of a user</xref>  </p> </li> <li id="GUID-0417F827-6C56-5EE9-B1B2-FE82A757E452"><p> <xref href="GUID-77E02E43-A72A-52DC-A22B-31FABE5B658D.dita#GUID-77E02E43-A72A-52DC-A22B-31FABE5B658D/GUID-0B246AE6-F0D1-56D4-9367-AF8678D5DB0F">Initiating a REGISTER transaction</xref>  </p> </li> <li id="GUID-A6E71991-EE51-59CD-AD38-B976F623300A"><p> <xref href="GUID-77E02E43-A72A-52DC-A22B-31FABE5B658D.dita#GUID-77E02E43-A72A-52DC-A22B-31FABE5B658D/GUID-E1F1952C-F56A-53D8-BD7E-C39E3E2566FD">Creating a CSIPConnection instance for a different IAP</xref>  </p> </li> <li id="GUID-D3732A15-A3B2-530E-991F-8B3311677853"><p> <xref href="GUID-77E02E43-A72A-52DC-A22B-31FABE5B658D.dita#GUID-77E02E43-A72A-52DC-A22B-31FABE5B658D/GUID-4E2849A8-36BB-5986-BA33-71E39FA5FCE7">Creating a SIP dialog while responding to the INVITE request</xref>  </p> </li> <li id="GUID-F701EF01-D87C-5665-B5B2-8AAC9A8790DD"><p> <xref href="GUID-77E02E43-A72A-52DC-A22B-31FABE5B658D.dita#GUID-77E02E43-A72A-52DC-A22B-31FABE5B658D/GUID-9C1A5E22-7E45-5346-B266-7767161816BA">Deleting the transaction object</xref>  </p> </li> <li id="GUID-079B944B-6026-5AAF-AAD2-390476641272"><p> <xref href="GUID-77E02E43-A72A-52DC-A22B-31FABE5B658D.dita#GUID-77E02E43-A72A-52DC-A22B-31FABE5B658D/GUID-66B8C7BF-0157-5108-BFE9-510144C0F61C">No response is sent to a received ACK</xref>  </p> </li> <li id="GUID-3C83FD0B-8040-5E36-8844-69FF156FA3A9"><p> <xref href="GUID-77E02E43-A72A-52DC-A22B-31FABE5B658D.dita#GUID-77E02E43-A72A-52DC-A22B-31FABE5B658D/GUID-5A707F15-A679-5FE0-943D-FE246514F852">Getting the transaction timers values</xref>  </p> </li> <li id="GUID-BBC6F83A-760B-597C-B3AD-0DEBBC62EC3C"><p> <xref href="GUID-77E02E43-A72A-52DC-A22B-31FABE5B658D.dita#GUID-77E02E43-A72A-52DC-A22B-31FABE5B658D/GUID-2436DD1E-A388-5D77-A745-22D264770D95"> Extension headers definition with the SIP Client API </xref>  </p> </li> </ul> <section id="GUID-6E3797D8-507F-5D7B-B601-DABCE95EC87C"><title>SIP Client API dependent objects</title> <p>Create <xref href="GUID-AFB2603A-8A35-3E70-8EC2-229C9726F00B.dita"><apiname>CSIP</apiname></xref> and <xref href="GUID-2A070F4D-A35B-3505-BE86-E6C7A2F27B94.dita"><apiname>CSIPConnection</apiname></xref> objects to use the SIP Client API: </p> <codeblock id="GUID-60B89CAD-CB12-521D-8C34-AF8DDC56495B" xml:space="preserve">iSIP = CSIP::NewL(KAppUid, *iMySIPObserver);
iConnection = CSIPConnection::NewL(*iSIP, KIapIdentifier,*iMyConnectionObserver);
</codeblock> </section> <section id="GUID-0D3FB3DF-9316-554E-AC08-62C8D33B7F5E"><title> Publishing the SIP contact address of a user</title> <p>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 <xref href="GUID-3C166C85-6E17-323B-9CD3-B3E2836DC1C3.dita"><apiname>CSIPRefresh</apiname></xref> to automatically refresh the SIP stack when it is registered. </p> <p>In the following code, <codeph>localhost</codeph> indicates the request for the SIP stack to replace it with a local address. The <codeph>sip:user@localhost</codeph> means that the SIP stack replaces the localhost with the local IP address. An application uses <xref href="GUID-48AA01D5-CE7B-3C22-B2E0-529261121EC4.dita"><apiname>CSIPRegistrationBinding</apiname></xref> 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 <xref href="GUID-BDD99F37-FD44-56FF-A849-015FCEE8F2D9.dita">SIP Profile Agent API</xref>. </p> <codeblock id="GUID-E80C2B5B-8FA4-5DBD-9FB0-1DB4AE851E64" xml:space="preserve">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</codeblock> </section> <section id="GUID-0B246AE6-F0D1-56D4-9367-AF8678D5DB0F"><title>Initiating a REGISTER transaction </title> <p>Create a <xref href="GUID-48AA01D5-CE7B-3C22-B2E0-529261121EC4.dita"><apiname>CSIPRegistrationBinding</apiname></xref> object to start a <codeph>REGISTER</codeph> transaction. </p> <codeblock id="GUID-2C9251DE-298C-5E36-B601-49F33D5EA4F7" xml:space="preserve">iRegisterTransaction = iRegistration-&gt;RegisterL();</codeblock> <p>When you receive a 2xx response, the registration is active. Delete the transaction when the final response is received. </p> <codeblock id="GUID-320F575F-166F-5A4B-AFE9-EDFF6345CFB0" xml:space="preserve">void CMyConnectionObserver::IncomingResponse(CSIPClientTransaction&amp; aTransaction, CSIPRegistrationBinding&amp; aRegistration)
    {
    if (aRegistration.IsContextActive())
        {
        // Registration has succeeded
        }

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

        if (aTransaction == *iRegisterTransaction)
            {
            delete iRegisterTransaction;
            iRegisterTransaction = NULL;
            }
        }
    }</codeblock> </section> <section id="GUID-E1F1952C-F56A-53D8-BD7E-C39E3E2566FD"><title> Creating a CSIPConnection instance for a different IAP</title> <p>An <codeph>INVITE</codeph> request is received from the network. In this example the INVITE is received through a different IAP that does not have a <codeph>CSIPConnection</codeph>. Create a <codeph>CSIPConnection</codeph> instance for this IAP. </p> <codeblock id="GUID-31AAF5A5-79B1-512B-A649-53562C9940EA" xml:space="preserve">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;
    }</codeblock> </section> <section id="GUID-4E2849A8-36BB-5986-BA33-71E39FA5FCE7"><title>Creating a SIP dialog while responding to the INVITE request</title> <p>The INVITE request is received and the application sends a response (101-299). This creates a SIP dialog. Before sending the response, create a <xref href="GUID-B4A2FBBD-2B5F-3E64-800D-C4E9203679A8.dita"><apiname>CSIPInviteDialogAssoc</apiname></xref>. </p> <codeblock id="GUID-A1CD9786-DA64-5495-9F08-F4FE382C2EE9" xml:space="preserve">iInviteAssoc = CSIPInviteDialogAssoc::NewL(*iInviteServerTransaction);

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

iInviteServerTransaction-&gt;SendResponseL(response);
CleanupStack::Pop(response);</codeblock> </section> <section id="GUID-9C1A5E22-7E45-5346-B266-7767161816BA"><title>Deleting the transaction object</title> <p>When the user accepts the <codeph>INVITE</codeph>, it sends a '200 response' using the same transaction object. When a 2xx response is sent to an <codeph>INVITE</codeph> transaction it enters the <xref href="GUID-93256B64-49C9-37F1-9A4E-72C521759749.dita#GUID-93256B64-49C9-37F1-9A4E-72C521759749/GUID-DF7E4DCE-1F6D-3F2A-A638-5516A733AA9D"><apiname>CSIPTransactionBase::ETerminated</apiname></xref> state. Then the transaction is deleted. </p> <codeblock id="GUID-A2CBCF0A-4E6B-58BD-AFDA-44D57F248C27" xml:space="preserve">CSIPResponseElements* response = CSIPResponseElements::NewLC(200, SIPStrings::StringF(SipStrConsts::EPhraseOk));
            
iInviteServerTransaction-&gt;SendResponseL(response);
CleanupStack::Pop(response);

delete iInviteServerTransaction;
iInviteServerTransaction = NULL;</codeblock> </section> <section id="GUID-66B8C7BF-0157-5108-BFE9-510144C0F61C"><title> No response is sent to a received ACK</title> <p>When the ACK request arrives, SIP Client API creates a <xref href="GUID-7E54C95E-5155-30B1-8169-A59778774403.dita"><apiname>CSIPServerTransaction</apiname></xref> and passes the transaction object to the application using the <xref href="GUID-B889A3FD-3B14-3785-90AE-3546F0C9A5D4.dita"><apiname>MSIPConnectionObserver</apiname></xref> of the IAP through which the ACK is received. If no response is sent to an ACK the transaction object is deleted. </p> <codeblock id="GUID-A6B15426-09EA-5C93-AF78-91D304F7A47E" xml:space="preserve">void CMyConnectionObserver::IncomingRequest(CSIPServerTransaction* aTransaction, CSIPDialog&amp; 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
        }
    }</codeblock> </section> <section id="GUID-5A707F15-A679-5FE0-943D-FE246514F852"><title>Getting the transaction timers values</title> <p>The following example code shows how to get the transaction timers values from the Central Repository (CenRep). </p> <codeblock id="GUID-6DF49D97-642A-551A-9D7B-45BE2F4050BE" xml:space="preserve">#include &lt;centralrepository.h&gt;
#include &lt;SIPSDKCRKeys.h&gt;
TInt timerT1 = 0;
TInt timerT2 = 0;
CRepository* repository = CRepository::NewLC(KCRUidSIP);
User::LeaveIfError(repository-&gt;Get(KSIPTransactionTimerT1,timerT1));
User::LeaveIfError(repository-&gt;Get(KSIPTransactionTimerT2,timerT2));
CleanupStack::PopAndDestroy(repository);</codeblock> </section> <section id="GUID-2436DD1E-A388-5D77-A745-22D264770D95"><title> Extension header definitions with the SIP Client API </title> <p>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. </p> <codeblock id="GUID-C25C4DE0-AE63-55BC-8366-387E931EF611" xml:space="preserve">void CMyClass::ExtractHeadersL( CSIPMessageElements&amp; aElements )
    {
    const RPointerArray&lt;CSIPHeaderBase&gt;&amp; userHeaders = aElements.UserHeaders();
    for ( TInt I = 0; I &lt; 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-&gt;Name() == SIPStrings::StringF( SipStrConsts::ERAckHeader ) )
             {
             iRAckHeader = static_cast&lt;CSIPRAckHeader*&gt;(header-&gt;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-&gt;Name() == extensionName )
            {
            HBufC8* headerValue = header-&gt;ToTextValueLC();
            
            // Do application specific parsing and handling for the header
 
            CleanupStack::PopAndDestroy( headerValue );
            }
        CleanupStack::PopAndDestroy( 1 ); // extensionName
        }
    }
</codeblock> </section> </conbody></concept>