diff -r 89d6a7a84779 -r 25a17d01db0c Symbian3/PDK/Source/GUID-0D579DDC-0A8A-5CFA-8194-CAA955B65A57.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/PDK/Source/GUID-0D579DDC-0A8A-5CFA-8194-CAA955B65A57.dita Fri Jan 22 18:26:19 2010 +0000 @@ -0,0 +1,489 @@ + + + + + +Example +of a SIP Client Resolver Plug-in +

This is an example of a SIP Client Resolver plug-in called CSimpleAppLauncher.

+

In this example, the plug-in capabilities are not defined in a resource +file but are defined in the implementation as the KCapabilities literal +descriptor.

+

If capabilities are defined in the resource file instead of within the +implementation, they are defined in the opaque_data field +in XML format. See Example +of capabilities definition in XML format.

+
Implementation +of CSimpleAppLauncher using CSIPResolvedClient interface

CSimpleAppLauncher.H

#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& aRequestUri, + const RPointerArray<CSIPHeaderBase>& aHeaders, + const TDesC8& aContent, + const CSIPContentTypeHeader* aContentType=0); + +void ConnectL(TUid aUid); + +const TDesC8& Capabilities(); + +private: // Constructors + +inline CSimpleAppLauncher() {} + +// Second phase constructor +void ConstructL(); +}; +

CSimpleAppLauncher.CPP

#include "CSimpleAppLauncher.h" + +const TUid KMyApplicationUid = { 0x101F5D45 }; + +_LIT8(KCapabilities, +"<SIP_CLIENT ALLOW_STARTING=\"YES\"><SIP_HEADERS>\ +<ACCEPT value=\"text/plain\"/></SIP_HEADERS></SIP_CLIENT>"); + +// ----------------------------------------------------------------------------- +// CSimpleAppLauncher::NewL +// ----------------------------------------------------------------------------- +// +CSimpleAppLauncher* CSimpleAppLauncher::NewL() +{ +CSimpleAppLauncher* self = new( ELeave ) CSimpleAppLauncher; +CleanupStack::PushL( self ); +self->ConstructL(); +CleanupStack::Pop( self ); +return self; +} + +// ----------------------------------------------------------------------------- +// CSimpleAppLauncher::ConstructL +// ----------------------------------------------------------------------------- +// +void CSimpleAppLauncher::ConstructL() +{ +} + +// ----------------------------------------------------------------------------- +// CSimpleAppLauncher::~CSimpleAppLauncher +// ----------------------------------------------------------------------------- +// +CSimpleAppLauncher::~CSimpleAppLauncher() +{ +} + +// ----------------------------------------------------------------------------- +// CSimpleAppLauncher::ChannelL +// ----------------------------------------------------------------------------- +// +TUid CSimpleAppLauncher::ChannelL(RStringF /*aMethod*/, +const TDesC8& /*aRequestUri*/, +const RPointerArray<CSIPHeaderBase>& /*aHeaders*/, +const TDesC8& /*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& 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; +} +

00000001.RSS

00000001.RSS +#include <RegistryInfo.rh> + +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) + } + }; + } + }; + }

Example +of capabilities definition in XML format

This is an example of +defining capabilities in XML format.

<SIP_CLIENT ALLOW_STARTING="YES"> +<SIP_HEADERS> +<ACCEPT_CONTACT value="*;mobility="mobile";media="audio"" /> +<ALLOW_EVENTS value="presence" /> +<ACCEPT value="somecontent/type" /> +<ACCEPT value="application/sdp" /> +</SIP_HEADERS> +<SDP_LINES> +<LINE name="m" value="audio 30000 RTP/AVP 98" /> +</SDP_LINES> +</SIP_CLIENT> +

Note: 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 CSimpleAppLauncher example plug-in in anyway, as the +capabilities for the example plug-in is proved.

+
Implementation of CSimpleAppLauncher2 using CSIPResolvedClient2 +interface

This is an example of SIP Client Resolver plug-in named CSimpleAppLauncher2.

CSimpleAppLauncher2.h

#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& aRequestUri, + const RPointerArray<CSIPHeaderBase>& aHeaders, + const TDesC8& aContent, + const CSIPContentTypeHeader* aContentType, + TUid& aClientUid); + + TBool MatchEventL( + RStringF aMethod, + const CUri8& aRequestUri, + const RPointerArray<CSIPHeaderBase>& aHeaders, + const TDesC8& aContent, + const CSIPContentTypeHeader* aContentType, + TUid& aClientUid); + + TBool MatchRequestL( + RStringF aMethod, + const CUri8& aRequestUri, + const RPointerArray<CSIPHeaderBase>& aHeaders, + const TDesC8& aContent, + const CSIPContentTypeHeader* aContentType, + TUid& aClientUid ); + + TBool ConnectSupported() ; + + void ConnectL( const TUid& aClientUid ); + + void CancelConnect( const TUid& aClientUid ); + + RPointerArray<CSIPContentTypeHeader> SupportedContentTypesL(); + + RPointerArray<CSdpMediaField> SupportedSdpMediasL(); + + void AddClientSpecificHeadersForOptionsResponseL( + RPointerArray<CSIPHeaderBase>& aHeaders ); + + private: // Constructors + +inline CSimpleAppLauncher2(){} + +// Second phase constructor +void ConstructL(); + + private: //Data + + RPointerArray<CSIPAcceptContactHeader> iAcceptContactHeaders; + CSIPEventHeader* iEvent; + CSIPExtensionHeader* iExtensionHeader; +}; +

CSimpleAppLauncher2.cpp

#include "CSimpleAppLauncher2.h" + +const TUid KResolvedClient2PluginUID = { 0x23456789 }; + + +// ----------------------------------------------------------------------------- +// CSimpleAppLauncher2::NewL +// ----------------------------------------------------------------------------- +// +CSimpleAppLauncher2* CSimpleAppLauncher2::NewL() + { + CSimpleAppLauncher2* self = new( ELeave ) CSimpleAppLauncher2; + CleanupStack::PushL( self ); + self->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& /*aRequestUri*/, + const RPointerArray<CSIPHeaderBase>& aHeaders, + const TDesC8& /*aContent*/, + const CSIPContentTypeHeader* /*aContentType*/, + TUid& aClientUid) + { + + TBool match = EFalse; + if ( iAcceptContactHeaders.Count() ) + { + CSIPAcceptContactHeader* acceptContact = + static_cast<CSIPAcceptContactHeader*>(iAcceptContactHeaders[0]); + for (TInt i = 0;i < aHeaders.Count() && !match;i++) + { + CSIPAcceptContactHeader* ac = + static_cast<CSIPAcceptContactHeader*>(aHeaders[i]); + if ( ac == acceptContact ) + { + match = ETrue; + aClientUid.iUid = 0x23456789; + } + } + } + return match; + } + +// ----------------------------------------------------------------------------- +// CSimpleAppLauncher2::MatchEventL +// From CSIPResolvedClient2 +// ----------------------------------------------------------------------------- +// +TBool CSimpleAppLauncher2::MatchEventL( + RStringF /*aMethod*/, + const CUri8& /*aRequestUri*/, + const RPointerArray<CSIPHeaderBase>& aHeaders, + const TDesC8& /*aContent*/, + const CSIPContentTypeHeader* /*aContentType*/, + TUid& aClientUid) + { + TBool match = EFalse; + if ( iEvent ) + { + for (TInt i = 0;i < aHeaders.Count() && !match;i++) + { + CSIPEventHeader* event = + static_cast<CSIPEventHeader*>(aHeaders[i]); + if ( event == iEvent ) + { + match = ETrue; + aClientUid.iUid = 0x23456789; + } + } + } + return match; + } + +// ----------------------------------------------------------------------------- +// CSimpleAppLauncher2::MatchRequestL +// From CSIPResolvedClient2 +// ----------------------------------------------------------------------------- +// +TBool CSimpleAppLauncher2::MatchRequestL( + RStringF /*aMethod*/, + const CUri8& /*aRequestUri*/, + const RPointerArray<CSIPHeaderBase>& aHeaders, + const TDesC8& /*aContent*/, + const CSIPContentTypeHeader* /*aContentType*/, + TUid& aClientUid) + { + TBool match = EFalse; + if ( iExtensionHeader ) + { + for (TInt i = 0;i < aHeaders.Count() && !match;i++) + { + CSIPExtensionHeader* extension = + static_cast<CSIPExtensionHeader*>(aHeaders[i]); + if ( iExtensionHeader->Name() == extension->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& 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& /*aClientUid*/ ) + { + } + +// ----------------------------------------------------------------------------- +// CSimpleAppLauncher2::SupportedContentTypesL +// From CSIPResolvedClient2 +// ----------------------------------------------------------------------------- +// +RPointerArray<CSIPContentTypeHeader> + CSimpleAppLauncher2::SupportedContentTypesL() + { + RPointerArray<CSIPContentTypeHeader> 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<CSdpMediaField> + 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<CSdpMediaField> headers; + headers.AppendL(mediafield); + CleanupStack::Pop(mediafield); + return headers; + } + +// ----------------------------------------------------------------------------- +// CSimpleAppLauncher2::AddClientSpecificHeadersForOptionsResponseL +// From CSIPResolvedClient2 +// ----------------------------------------------------------------------------- +// +void CSimpleAppLauncher2::AddClientSpecificHeadersForOptionsResponseL( + RPointerArray<CSIPHeaderBase>& aHeaders ) + { + CSIPExtensionHeader* extHeader = + CSIPExtensionHeader::NewL( _L8("ExtraHeader"), + _L8("resolvedClient2")); + CleanupStack::PushL( extHeader ); + TBool found(EFalse); + for ( TInt i = 0;i < aHeaders.Count() && !found;i++ ) + { + if ( aHeaders[i]->IsExtensionHeader() ) + { + //It is plug-ins responsibility to check that the new extension + //header is not yet exsisiting in aHeaders array. + + if ( (static_cast <CSIPExtensionHeader*> (aHeaders[i]) )->Value() + == extHeader->Value() &&(static_cast <CSIPExtensionHeader*> + (aHeaders[i]) )->Name() == extHeader->Name() ) + { + found = ETrue; + CleanupStack::Pop( extHeader ); + delete extHeader; + } + } + } + if ( !found ) + { + aHeaders.AppendL( extHeader ); + CleanupStack::Pop( extHeader ); + } + } +
+
\ No newline at end of file