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.
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.
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 );
}
}