Symbian3/SDK/Source/GUID-0D579DDC-0A8A-5CFA-8194-CAA955B65A57.dita
author Dominic Pinkman <Dominic.Pinkman@Nokia.com>
Wed, 31 Mar 2010 11:11:55 +0100
changeset 7 51a74ef9ed63
parent 0 89d6a7a84779
permissions -rw-r--r--
Week 12 contribution of API Specs and fix SDK submission

<?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 id="GUID-0D579DDC-0A8A-5CFA-8194-CAA955B65A57" xml:lang="en"><title>Example
of a SIP Client Resolver Plug-in</title><prolog><metadata><keywords/></metadata></prolog><conbody>
<p>This is an example of a SIP Client Resolver plug-in called <codeph>CSimpleAppLauncher</codeph>. </p>
<p>In this example, the plug-in capabilities are not defined in a resource
file but are defined in the implementation as the <codeph>KCapabilities</codeph> literal
descriptor. </p>
<p>If capabilities are defined in the resource file instead of within the
implementation, they are defined in the <codeph>opaque_data</codeph> field
in XML format. See <xref href="GUID-0D579DDC-0A8A-5CFA-8194-CAA955B65A57.dita#GUID-0D579DDC-0A8A-5CFA-8194-CAA955B65A57/GUID-2B6A49E7-B483-59E2-B679-9828B483AB52">Example
of capabilities definition in XML format</xref>. </p>
<section id="GUID-1DF21E5C-9D66-5BBD-A1FD-91B5043D5D72"><title>Implementation
of CSimpleAppLauncher using CSIPResolvedClient interface</title> <p><b> CSimpleAppLauncher.H </b> </p> <codeblock id="GUID-25F9D5DF-0D59-5236-8E04-641F36C0DEF8" xml:space="preserve">#include "SipResolvedClient.h"

class CSimpleAppLauncher : public CSIPResolvedClient
{
public:    // Constructors and destructor
/**
 * Static constructor
 * @return An initialized instance of this class.
 */
static CSimpleAppLauncher* NewL();

/// Destructor
~CSimpleAppLauncher();

public: // from CSIPResolvedClient
TUid ChannelL(RStringF aMethod, 
      const TDesC8&amp; aRequestUri,
      const RPointerArray&lt;CSIPHeaderBase&gt;&amp; aHeaders,
      const TDesC8&amp; aContent,
      const CSIPContentTypeHeader* aContentType=0);

void ConnectL(TUid aUid);

const TDesC8&amp; Capabilities();

private: // Constructors

inline CSimpleAppLauncher() {}

// Second phase constructor
void ConstructL(); 
};
</codeblock> <p><b> CSimpleAppLauncher.CPP </b> </p> <codeblock id="GUID-D7CF3E31-D2E1-5CF6-AAD0-6CE028EB9412" xml:space="preserve">#include "CSimpleAppLauncher.h"

const TUid KMyApplicationUid = { 0x101F5D45 }; 

_LIT8(KCapabilities,
"&lt;SIP_CLIENT ALLOW_STARTING=\"YES\"&gt;&lt;SIP_HEADERS&gt;\
&lt;ACCEPT value=\"text/plain\"/&gt;&lt;/SIP_HEADERS&gt;&lt;/SIP_CLIENT&gt;");

// -----------------------------------------------------------------------------
// CSimpleAppLauncher::NewL
// -----------------------------------------------------------------------------
//
CSimpleAppLauncher* CSimpleAppLauncher::NewL()
{
CSimpleAppLauncher* self = new( ELeave ) CSimpleAppLauncher;
CleanupStack::PushL( self );
self-&gt;ConstructL();
CleanupStack::Pop( self );
return self;
}

// -----------------------------------------------------------------------------
// CSimpleAppLauncher::ConstructL
// -----------------------------------------------------------------------------
//
void CSimpleAppLauncher::ConstructL()
{
}

// -----------------------------------------------------------------------------
// CSimpleAppLauncher::~CSimpleAppLauncher
// -----------------------------------------------------------------------------
//
CSimpleAppLauncher::~CSimpleAppLauncher()
{
}

// -----------------------------------------------------------------------------
// CSimpleAppLauncher::ChannelL
// -----------------------------------------------------------------------------
//
TUid CSimpleAppLauncher::ChannelL(RStringF /*aMethod*/,
const TDesC8&amp; /*aRequestUri*/,
const RPointerArray&lt;CSIPHeaderBase&gt;&amp; /*aHeaders*/,
const TDesC8&amp; /*aContent*/,
const CSIPContentTypeHeader* /*aContentType*/)
{
// In the basic case application wants all the requests to itself
return KMyApplicationUid;

}

// -----------------------------------------------------------------------------
// CSimpleAppLauncher::ConnectL
// -----------------------------------------------------------------------------
//
void CSimpleAppLauncher::ConnectL(TUid aUid)
{
// application specific starting logic that leads to 
// the connection with the SIP. The same UID must be
// provided to SIP while invoking CSIP::NewL().
}
    

// -----------------------------------------------------------------------------
// CSimpleAppLauncher::Capabilities
// -----------------------------------------------------------------------------
//
const TDesC8&amp; CSimpleAppLauncher::Capabilities()
{
// if an application did not provide capabilities in the
// ECOM rsc-file this function will be invoked by the 
// resolution logic implementation.
return KCapabilities;
}
</codeblock> <p><b> 00000001.RSS </b> </p> <codeblock id="GUID-BA39D436-55CD-54AC-99F6-0AFDBE825E3F" xml:space="preserve">00000001.RSS 
#include &lt;RegistryInfo.rh&gt;

RESOURCE REGISTRY_INFO theInfo
   {
   // UID for the DLL
   dll_uid = 0x00000001;
   // Declare array of interface info
   interfaces = 
      {
      INTERFACE_INFO
         {
         // UID of interface that is implemented
         interface_uid = 0x102010DD;
         implementations = 
            {
            IMPLEMENTATION_INFO
               {
               implementation_uid = 0x00000001;
               version_no = 1;
               default_data = "101F5D45"; // SIP client application UID SIPTestUI in this case)
               }
            };
         }
     };
 }</codeblock> <p id="GUID-2B6A49E7-B483-59E2-B679-9828B483AB52"><b>Example
of capabilities definition in XML format</b> </p> <p>This is an example of
defining capabilities in XML format. </p> <codeblock id="GUID-AD845CAF-ADC0-5C53-BF4A-E02D9D5E6A15" xml:space="preserve">&lt;SIP_CLIENT ALLOW_STARTING="YES"&gt;
&lt;SIP_HEADERS&gt;
&lt;ACCEPT_CONTACT value="*;mobility="mobile";media="audio"" /&gt; 
&lt;ALLOW_EVENTS value="presence" /&gt; 
&lt;ACCEPT value="somecontent/type" /&gt; 
&lt;ACCEPT value="application/sdp" /&gt; 
&lt;/SIP_HEADERS&gt;
&lt;SDP_LINES&gt;
&lt;LINE name="m" value="audio 30000 RTP/AVP 98" /&gt; 
&lt;/SDP_LINES&gt;
&lt;/SIP_CLIENT&gt;
</codeblock> <p> <b>Note:</b> This XML file is an example to demonstrate how
to define capabilities in XML format. The contents of this file are not related
to the <codeph>CSimpleAppLauncher</codeph> example plug-in in anyway, as the
capabilities for the example plug-in is proved. </p> </section>
<section><title>Implementation of CSimpleAppLauncher2 using CSIPResolvedClient2
interface</title> <p>This is an example of SIP Client Resolver plug-in named <codeph>CSimpleAppLauncher2</codeph>. </p> <p><b>CSimpleAppLauncher2.h</b> </p> <codeblock id="GUID-AC545323-9326-506E-984C-CF831A3A6828" xml:space="preserve">#include "SipResolvedClient2.h"

class CSimpleAppLauncher2 : public CSIPResolvedClient2
      {
      public: // Constructors and destructor

/**
* Static constructor
* @return An initialized instance of this class.
*/
static CSimpleAppLauncher2* NewL();

/// Destructor
~CSimpleAppLauncher2();

       public: // from CSIPResolvedClient2

TBool MatchAcceptContactsL(
            RStringF aMethod,
            const CUri8&amp; aRequestUri,
            const RPointerArray&lt;CSIPHeaderBase&gt;&amp; aHeaders,
            const TDesC8&amp; aContent,
            const CSIPContentTypeHeader* aContentType,
            TUid&amp; aClientUid);

           TBool MatchEventL(
                RStringF aMethod,
                const CUri8&amp; aRequestUri,
                const RPointerArray&lt;CSIPHeaderBase&gt;&amp; aHeaders,
                const TDesC8&amp; aContent,
                const CSIPContentTypeHeader* aContentType,
                TUid&amp; aClientUid);

    TBool MatchRequestL(
                RStringF aMethod,
                const CUri8&amp; aRequestUri,
                const RPointerArray&lt;CSIPHeaderBase&gt;&amp; aHeaders,
                const TDesC8&amp; aContent,
                const CSIPContentTypeHeader* aContentType,
                TUid&amp; aClientUid );

    TBool ConnectSupported() ;

    void ConnectL( const TUid&amp; aClientUid );

    void CancelConnect( const TUid&amp; aClientUid );

    RPointerArray&lt;CSIPContentTypeHeader&gt; SupportedContentTypesL();

    RPointerArray&lt;CSdpMediaField&gt; SupportedSdpMediasL();

    void AddClientSpecificHeadersForOptionsResponseL(
                                        RPointerArray&lt;CSIPHeaderBase&gt;&amp; aHeaders );

       private: // Constructors

inline CSimpleAppLauncher2(){}

// Second phase constructor
void ConstructL(); 
      
       private: //Data

    RPointerArray&lt;CSIPAcceptContactHeader&gt; iAcceptContactHeaders;
    CSIPEventHeader*      iEvent;
    CSIPExtensionHeader*  iExtensionHeader; 
};
</codeblock> <p><b>CSimpleAppLauncher2.cpp</b> </p> <codeblock id="GUID-C65A4DFA-C332-5096-B885-017E9C8E7722" xml:space="preserve">#include "CSimpleAppLauncher2.h"

const TUid KResolvedClient2PluginUID = { 0x23456789 };


// -----------------------------------------------------------------------------
// CSimpleAppLauncher2::NewL
// -----------------------------------------------------------------------------
//
CSimpleAppLauncher2* CSimpleAppLauncher2::NewL()
    {
    CSimpleAppLauncher2* self = new( ELeave ) CSimpleAppLauncher2;
    CleanupStack::PushL( self );
    self-&gt;ConstructL();
    CleanupStack::Pop( self );
    return self;    
    }

// -----------------------------------------------------------------------------
// CSimpleAppLauncher2::ConstructL
// -----------------------------------------------------------------------------
//
void CSimpleAppLauncher2::ConstructL()
    {
    _LIT8(KACValue, "*;+resolvedexample2");
    iAcceptContactHeaders = CSIPAcceptContactHeader::DecodeL(KACValue());
    _LIT8(KEventValue,"precense.winfo.jinfo.kinfo");
    iEvent = CSIPEventHeader::DecodeL(KEventValue());
    iExtensionHeader = CSIPExtensionHeader::NewL( _L8("ExtraHeader"),
    _L8("resolvedClient2"));
    }

// -----------------------------------------------------------------------------
// CSimpleAppLauncher2::~CSimpleAppLauncher2
// -----------------------------------------------------------------------------
//
CSimpleAppLauncher2::~CSimpleAppLauncher2()
    {
    iAcceptContactHeaders.ResetAndDestroy();
    delete iEvent;
    delete iExtensionHeader;
    }

// -----------------------------------------------------------------------------
// CSimpleAppLauncher2::MatchAcceptContactsL
// From CSIPResolvedClient2
// -----------------------------------------------------------------------------
//
TBool CSimpleAppLauncher2::MatchAcceptContactsL(
    RStringF /*aMethod*/,
    const CUri8&amp; /*aRequestUri*/,
    const RPointerArray&lt;CSIPHeaderBase&gt;&amp; aHeaders,
    const TDesC8&amp; /*aContent*/,
    const CSIPContentTypeHeader* /*aContentType*/,
    TUid&amp; aClientUid)
    {
    
    TBool match = EFalse;
    if ( iAcceptContactHeaders.Count() )
        {
        CSIPAcceptContactHeader* acceptContact = 
           static_cast&lt;CSIPAcceptContactHeader*&gt;(iAcceptContactHeaders[0]);
           for (TInt i = 0;i &lt; aHeaders.Count() &amp;&amp; !match;i++)
                {
                CSIPAcceptContactHeader* ac = 
                      static_cast&lt;CSIPAcceptContactHeader*&gt;(aHeaders[i]);
                 if ( ac == acceptContact )
                     {
                     match = ETrue;
                     aClientUid.iUid = 0x23456789;
                     }
                }
        }
    return match;
    }

// -----------------------------------------------------------------------------
// CSimpleAppLauncher2::MatchEventL
// From CSIPResolvedClient2
// -----------------------------------------------------------------------------
//
TBool CSimpleAppLauncher2::MatchEventL(
    RStringF /*aMethod*/,
    const CUri8&amp; /*aRequestUri*/,
    const RPointerArray&lt;CSIPHeaderBase&gt;&amp; aHeaders,
    const TDesC8&amp; /*aContent*/,
    const CSIPContentTypeHeader* /*aContentType*/,
    TUid&amp; aClientUid)
    {
    TBool match = EFalse;
    if ( iEvent )
        {
           for (TInt i = 0;i &lt; aHeaders.Count() &amp;&amp; !match;i++)
                {
                CSIPEventHeader* event = 
                        static_cast&lt;CSIPEventHeader*&gt;(aHeaders[i]);
                if ( event == iEvent )
                    {
                    match = ETrue;
                    aClientUid.iUid = 0x23456789;
                    }
                }
        }
    return match;
    }

// -----------------------------------------------------------------------------
// CSimpleAppLauncher2::MatchRequestL
// From CSIPResolvedClient2
// -----------------------------------------------------------------------------
//
TBool CSimpleAppLauncher2::MatchRequestL(
    RStringF /*aMethod*/,
    const CUri8&amp; /*aRequestUri*/,
    const RPointerArray&lt;CSIPHeaderBase&gt;&amp; aHeaders,
    const TDesC8&amp; /*aContent*/,
    const CSIPContentTypeHeader* /*aContentType*/,
    TUid&amp; aClientUid)
    {
    TBool match = EFalse;
    if ( iExtensionHeader )
        {
           for (TInt i = 0;i &lt; aHeaders.Count() &amp;&amp; !match;i++)
                 {
                 CSIPExtensionHeader* extension = 
                        static_cast&lt;CSIPExtensionHeader*&gt;(aHeaders[i]);
                 if ( iExtensionHeader-&gt;Name() == extension-&gt;Name() )
                     {
                     match = ETrue;
                     aClientUid.iUid = 0x23456789;
                    }
                 }
        }
    return match;
    }

// -----------------------------------------------------------------------------
// CSimpleAppLauncher2::ConnectSupported
// From CSIPResolvedClient2
// -----------------------------------------------------------------------------
//
TBool CSimpleAppLauncher2::ConnectSupported()
    {
    return ETrue;
    }

// -----------------------------------------------------------------------------
// CSimpleAppLauncher2::ConnectL
// From CSIPResolvedClient2
// -----------------------------------------------------------------------------
//
void CSimpleAppLauncher2::ConnectL( 
    const TUid&amp; aClientUid )
    {
    // application specific starting logic that leads to 
    // the connection with the SIP. The same UID must be
    // provided to SIP while invoking CSIP::NewL().
    }

// -----------------------------------------------------------------------------
// CSimpleAppLauncher2::CancelConnect
// From CSIPResolvedClient2
// -----------------------------------------------------------------------------
//        
void CSimpleAppLauncher2::CancelConnect(
    const TUid&amp; /*aClientUid*/ )
    {
    }

// -----------------------------------------------------------------------------
// CSimpleAppLauncher2::SupportedContentTypesL
// From CSIPResolvedClient2
// -----------------------------------------------------------------------------
//        
RPointerArray&lt;CSIPContentTypeHeader&gt; 
        CSimpleAppLauncher2::SupportedContentTypesL()
    {
    RPointerArray&lt;CSIPContentTypeHeader&gt; headers;
    _LIT8 (KAppWithSdp, "application/sdp");
    CSIPContentTypeHeader* contentTypeHeader = 
    CSIPContentTypeHeader::DecodeL(KAppWithSdp());
    CleanupStack::PushL( contentTypeHeader );
    headers.AppendL( contentTypeHeader );
    CleanupStack::Pop( contentTypeHeader );
    return headers;
    }

// -----------------------------------------------------------------------------
// CSimpleAppLauncher2::SupportedSdpMediasL
// From CSIPResolvedClient2
// -----------------------------------------------------------------------------
//        
RPointerArray&lt;CSdpMediaField&gt; 
        CSimpleAppLauncher2::SupportedSdpMediasL()
    {
    RStringPool sdpStrPool = SdpCodecStringPool::StringPoolL();
    RStringF media = sdpStrPool.OpenFStringL(_L8("audio"));
    CleanupClosePushL(media);
    RStringF protocol = sdpStrPool.OpenFStringL(_L8("RTP/AVP"));
    CleanupClosePushL(protocol);
    CSdpMediaField* mediafield = 
    CSdpMediaField::NewL(media,0,protocol,_L8("formatlist"));
    CleanupStack::Pop(2);//media,protocol
    media.Close();
    protocol.Close();
    CleanupStack::PushL(mediafield);
    RPointerArray&lt;CSdpMediaField&gt; headers;
    headers.AppendL(mediafield);
    CleanupStack::Pop(mediafield);
    return headers;
    }

// -----------------------------------------------------------------------------
// CSimpleAppLauncher2::AddClientSpecificHeadersForOptionsResponseL
// From CSIPResolvedClient2
// -----------------------------------------------------------------------------
//        
void CSimpleAppLauncher2::AddClientSpecificHeadersForOptionsResponseL( 
                    RPointerArray&lt;CSIPHeaderBase&gt;&amp; aHeaders )
    {
    CSIPExtensionHeader* extHeader =  
        CSIPExtensionHeader::NewL( _L8("ExtraHeader"),   
    _L8("resolvedClient2"));
    CleanupStack::PushL( extHeader );
    TBool found(EFalse);
    for ( TInt i = 0;i &lt; aHeaders.Count() &amp;&amp; !found;i++ )
        {
        if ( aHeaders[i]-&gt;IsExtensionHeader() )
            {
              //It is plug-ins responsibility to check that the new extension 
              //header is not yet exsisiting in aHeaders array.

            if ( (static_cast &lt;CSIPExtensionHeader*&gt; (aHeaders[i]) )-&gt;Value() 
                   == extHeader-&gt;Value() &amp;&amp;(static_cast &lt;CSIPExtensionHeader*&gt; 
                             (aHeaders[i]) )-&gt;Name() == extHeader-&gt;Name() )
                {
                found = ETrue;
                CleanupStack::Pop( extHeader );
                delete extHeader;
                }
            }
        }
    if ( !found )
        {
        aHeaders.AppendL( extHeader );
        CleanupStack::Pop( extHeader );
        }
    }
</codeblock> </section>
</conbody></concept>