--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/upnp/upnpstack/upnputils/src/upnpdevicelibrary.cpp Tue Feb 02 01:12:20 2010 +0200
@@ -0,0 +1,763 @@
+/** @file
+* Copyright (c) 2005-2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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:
+*
+* Description: CUpnpDeviceLibrary
+*
+*/
+
+
+// INCLUDE FILES
+#include "upnpdevicelibrary.h"
+#include "upnpssdpmessage.h"
+#define KLogFile _L("DLNAWebServer.txt")
+#include "upnpcustomlog.h"
+
+static const TInt KIntervalBetweenByeAndAlive = 1;
+static const TInt KIntervalBeforeFirstAlive = 1;
+// prevents treating SSDP alive messages sent by local device
+// as an external device messages in case of quick local device restarting
+// heuristic value
+static const TInt KLocalDeviceHysteresisWindow = 20;
+// used for IPC communication 2 phase request
+// heuristic value
+static const TInt KIpcCommunicationTimeout = 2;
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CUpnpDeviceLibrary::CUpnpDeviceLibrary
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CUpnpDeviceLibrary::CUpnpDeviceLibrary( MUpnpDeviceLibraryObserver& aObserver,
+ TInt aHandle )
+ : iObserver(aObserver),
+ iHandle( aHandle )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpDeviceLibrary::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CUpnpDeviceLibrary::ConstructL()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpDeviceLibrary::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CUpnpDeviceLibrary* CUpnpDeviceLibrary::NewL(
+ MUpnpDeviceLibraryObserver& aObserver,
+ TInt aHandle )
+ {
+ CUpnpDeviceLibrary* self = new (ELeave) CUpnpDeviceLibrary( aObserver, aHandle );
+
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+// -----------------------------------------------------------------------------
+// CUpnpDeviceLibrary::~CUpnpDeviceLibrary
+// Destructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CUpnpDeviceLibrary::~CUpnpDeviceLibrary()
+ {
+ LOGSH( iHandle, "Devicelibrary ~CUpnpDeviceLibrary");
+
+ iElementArray.ResetAndDestroy();
+ iElementArray.Close();
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpDeviceLibrary::PrepareShutdown
+// Prepare devices for shutdown.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CUpnpDeviceLibrary::PrepareShutdown()
+ {
+ LOGSH( iHandle, "Devicelibrary PrepareShutdown" );
+
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpDeviceLibrary::AddInfoL
+// Add device info.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CUpnpDeviceLibrary::AddInfoL( const TUpnpAddLocalDevice* aIndex,
+ const TDesC8& aBuffer,
+ const TInetAddr& aLocalAddr )
+ {
+ LOGSH( iHandle, "Devicelibrary AddInfoL" );
+ if ( !aIndex )
+ {
+ return;
+ }
+
+ TPtrC8 uuid = aBuffer.Left(aIndex->iUuidLength);
+ TInt index = Find( uuid );
+
+ if ( index != KErrNotFound )
+ {
+ CUpnpDeviceLibraryElement* elem = iElementArray[index];
+
+ if ( elem->Local() )
+ {
+ CUpnpTimeoutElement::TRenew state = elem->Renew();
+ elem->AddInfoL( aIndex, aBuffer, aLocalAddr );
+ elem->SetRenew( CUpnpTimeoutElement::ERenew );
+ elem->SetTimeout( KIntervalBeforeFirstAlive );
+ elem->SetUpdateId( iUpdateId );
+
+ if ( state == CUpnpTimeoutElement::ERemove )
+ {
+ elem->SetAlive( ETrue );
+ elem->SetUpdateId( ++iUpdateId );
+ iObserver.DeviceListChangedL();
+ }
+ }
+ else
+ {
+ InvalidateNonLocalDevice( *elem );
+ AppendLocalDeviceL( aIndex, aBuffer, aLocalAddr );
+ iObserver.DeviceListChangedL();
+ }
+ }
+ else
+ {
+ AppendLocalDeviceL( aIndex, aBuffer, aLocalAddr );
+ iObserver.DeviceListChangedL();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpDeviceLibrary::InvalidateNonLocalDevice
+// -----------------------------------------------------------------------------
+//
+void CUpnpDeviceLibrary::InvalidateNonLocalDevice( CUpnpDeviceLibraryElement& aElem )
+ {
+ aElem.SetAlive( EFalse );
+ aElem.SetUpdateId( ++iUpdateId );
+ aElem.SetTimeout( KIpcCommunicationTimeout );
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpDeviceLibrary::AppendLocalDeviceL
+// -----------------------------------------------------------------------------
+//
+void CUpnpDeviceLibrary::AppendLocalDeviceL( const TUpnpAddLocalDevice* aIndex,
+ const TDesC8& aBuffer,
+ const TInetAddr& aLocalAddr )
+ {
+ CUpnpDeviceLibraryElement* element = CUpnpDeviceLibraryElement::NewL(*this);
+ CleanupStack::PushL( element );
+ element->AddInfoL( aIndex, aBuffer, aLocalAddr );
+ element->SetRenew( CUpnpTimeoutElement::ERenew );
+ element->SetTimeout( KIntervalBeforeFirstAlive );
+ element->SetLocal( ETrue );
+ element->SetUpdateId( ++iUpdateId );
+ iElementArray.AppendL( element );
+ CleanupStack::Pop( element );
+ }
+// -----------------------------------------------------------------------------
+// CUpnpDeviceLibrary::AddInfoL
+// Add device info.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CUpnpDeviceLibrary::AddInfoL( const TUpnpAddLocalDevice* aIndex,
+ const TDesC8& aBuffer )
+ {
+ LOGSH( iHandle, "Devicelibrary AddInfoL");
+
+ if ( !aIndex )
+ {
+ return;
+ }
+
+ TPtrC8 uuid = aBuffer.Left(aIndex->iUuidLength);
+
+ TInt index = Find( uuid );
+
+ if ( index != KErrNotFound )
+ {
+ CUpnpDeviceLibraryElement* elem = iElementArray[index];
+
+ CUpnpTimeoutElement::TRenew state = elem->Renew();
+
+ elem->AddInfoL( aIndex, aBuffer );
+ elem->SetRenew( CUpnpTimeoutElement::ERenew );
+ elem->SetTimeout( 1 );
+ elem->SetUpdateId( iUpdateId );
+
+ if (state == CUpnpTimeoutElement::ERemove)
+ {
+ iUpdateId++;
+ elem->SetAlive( ETrue );
+ elem->SetUpdateId( iUpdateId );
+ iObserver.DeviceListChangedL();
+ }
+ }
+ else
+ {
+ iUpdateId++;
+
+ CUpnpDeviceLibraryElement* element = CUpnpDeviceLibraryElement::NewL(*this);
+ CleanupStack::PushL( element );
+ element->AddInfoL( aIndex, aBuffer );
+ element->SetRenew( CUpnpTimeoutElement::ERenew );
+ element->SetTimeout( 1 );
+ element->SetLocal( EFalse );
+ element->SetUpdateId( iUpdateId );
+ iElementArray.AppendL( element );
+ CleanupStack::Pop( element );
+
+ iObserver.DeviceListChangedL();
+ }
+ }
+// -----------------------------------------------------------------------------
+// CUpnpDeviceLibrary::AddInfoL
+// Add device info.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CUpnpDeviceLibrary::AddInfoL( CUpnpSsdpMessage* aMessage )
+ {
+ LOGSH( iHandle, "Devicelibrary AddInfoL");
+ if ( aMessage )
+ {
+ if ( aMessage->IsSsdpAlive() )
+ {
+ if( AddDeviceL(aMessage) )
+ {
+ iObserver.DeviceListChangedL();
+ }
+ }
+ else
+ {
+ RemoveDeviceL( aMessage );
+ iObserver.DeviceListChangedL();
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpDeviceLibrary::Find
+// Find device given by UUID.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CUpnpDeviceLibrary::Find( const TDesC8& aUuid )
+ {
+ LOGSH( iHandle, "Devicelibrary Find");
+
+ for ( TInt i=0; i<iElementArray.Count(); i++ )
+ {
+ if ( aUuid.FindC( iElementArray[i]->UUID() ) == 0
+ && aUuid.Length() == iElementArray[i]->UUID().Length() )
+ {
+ return i;
+ }
+ }
+ return KErrNotFound;
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpDeviceLibrary::RemoveL
+// Remove device by given UID. Used for local devices only.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CUpnpDeviceLibrary::RemoveL( const TDesC8& aUuid )
+ {
+ LOGSH( iHandle, "Devicelibrary RemoveL");
+
+ TInt result = Find( aUuid );
+
+ if ( result != KErrNotFound )
+ {
+ CUpnpDeviceLibraryElement* elem = iElementArray[result];
+
+ iObserver.AdvertiseDeviceL( EFalse, *elem );
+ iObserver.AdvertiseDeviceL( EFalse, *elem );
+
+ elem->AdvertisingFinished();
+
+ elem->SetRenew( CUpnpTimeoutElement::ERemove );
+ elem->SetTimeout( KLocalDeviceHysteresisWindow );
+ elem->SetUpdateId( ++iUpdateId );
+ elem->SetAlive( EFalse );
+
+ iObserver.DeviceListChangedL();
+ }
+ }
+// -----------------------------------------------------------------------------
+// CUpnpDeviceLibrary::RemoveSilentL
+// Remove device by given UID. Used for local devices only.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CUpnpDeviceLibrary::RemoveSilentL( const TDesC8& aUuid )
+ {
+ //LOGS( iHandle, "Devicelibrary RemoveSilentL");
+
+ LOGS("CUpnpDeviceLibrary::RemoveSilentL( const TDesC8& aUuid )");
+ TInt result = Find( aUuid );
+
+ if ( result != KErrNotFound )
+ {
+ CUpnpDeviceLibraryElement* elem = iElementArray[result];
+
+
+ elem->SetRenew( CUpnpTimeoutElement::ERemove );
+ elem->SetTimeout( KLocalDeviceHysteresisWindow );
+ elem->SetUpdateId( ++iUpdateId );
+ elem->SetAlive( EFalse );
+
+ iObserver.DeviceListChangedL();
+ }
+ LOGS("CUpnpDeviceLibrary::RemoveSilentL( const TDesC8& aUuid ) passed");
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpDeviceLibrary::TimeoutExpiredL
+// Timeout expired for advertisement.
+// -----------------------------------------------------------------------------
+//
+void CUpnpDeviceLibrary::TimeoutExpiredL( CUpnpTimeoutElement* anElement )
+ {
+ LOGSH( iHandle, "Devicelibrary TimeoutExpiredL");
+
+ if ( !anElement )
+ {
+ return;
+ }
+
+ CUpnpDeviceLibraryElement* elem =
+ static_cast<CUpnpDeviceLibraryElement*>(anElement);
+
+ switch ( elem->Renew() )
+ {
+ case CUpnpTimeoutElement::ERenew:
+ {
+ if ( !elem->Advertised() )
+ {
+ elem->Advertising();
+ // whatever happends we don't want to have leave here
+ TRAP_IGNORE( iObserver.AdvertiseDeviceL( EFalse, *elem ));
+ TRAP_IGNORE( iObserver.AdvertiseDeviceL( EFalse, *elem ));
+ elem->SetTimeout( KIntervalBetweenByeAndAlive );
+ }
+ else
+ {
+ // whatever happends we don't want to have leave here
+ TRAP_IGNORE( iObserver.AdvertiseDeviceL( ETrue, *elem ));
+ elem->SetTimeout( KDeviceTimeout );
+ }
+ }
+ break;
+
+ case CUpnpTimeoutElement::EOnce: // after cache control expires
+ {
+ // Set the timeout for the device to be removed
+ iUpdateId++;
+ elem->SetRenew( CUpnpTimeoutElement::ERemove );
+ if( elem->Local() )
+ {
+ elem->SetTimeout( KLocalDeviceHysteresisWindow );
+ }
+ else
+ {
+ elem->SetTimeout( KIpcCommunicationTimeout );
+ }
+ elem->SetUpdateId( iUpdateId );
+ elem->SetAlive( EFalse );
+ elem->SetExpired( ETrue );
+
+ iObserver.DeviceListChangedL();
+ }
+ break;
+
+ case CUpnpTimeoutElement::ERemove:
+ {
+ // Remove device from the element array
+ for ( TInt i=0; i<iElementArray.Count(); i++ )
+ {
+ if ( elem == iElementArray[i] )
+ {
+ iElementArray.Remove( i );
+ iElementArray.Compress();
+
+ delete elem;
+ break;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpDeviceLibrary::DeviceList
+// Return device list.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C RPointerArray<CUpnpDeviceLibraryElement>& CUpnpDeviceLibrary::DeviceList()
+ {
+ LOGSH( iHandle, "Devicelibrary DeviceList");
+
+ return iElementArray;
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpDeviceLibrary::GetUpdate
+// Get update.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CUpnpDeviceLibrary::GetUpdate( TInt& aUpdateId,
+ TUpnpDevice *&aDevices,
+ TUpnpService *&aServices,
+ TInt& aDeviceCount,
+ TInt& aServiceCount )
+ {
+ aDevices = NULL;
+ aServices = NULL;
+
+ TUpnpDevice* devices = NULL;
+ TUpnpService* services = NULL;
+
+ aDeviceCount = 0;
+ aServiceCount = 0;
+
+ for ( TInt i = 0; i < iElementArray.Count(); i++ )
+ {
+ CUpnpDeviceLibraryElement* elem = iElementArray[i];
+
+ if (elem->UpdateId() > aUpdateId)
+ {
+ TUpnpDevice* temp = new TUpnpDevice[aDeviceCount+1];
+ if ( !temp )
+ {
+ continue;
+ }
+
+ TPtr8 destPtr(reinterpret_cast<TUint8*>(temp),
+ 0,
+ sizeof(TUpnpDevice)*(aDeviceCount+1));
+ TPtr8 srcPtr(reinterpret_cast<TUint8*>(devices),
+ sizeof(TUpnpDevice)*aDeviceCount,
+ sizeof(TUpnpDevice)*aDeviceCount);
+
+ destPtr.Copy(srcPtr);
+
+ if (devices)
+ {
+ delete[] devices;
+ devices = NULL;
+ }
+
+ devices = temp;
+
+ TUpnpDevice devtemp;
+ destPtr.Set(reinterpret_cast<TUint8*>(&devices[aDeviceCount]),
+ 0,
+ sizeof(TUpnpDevice));
+ srcPtr.Set(reinterpret_cast<TUint8*>(&devtemp),
+ sizeof(TUpnpDevice),
+ sizeof(TUpnpDevice));
+ destPtr.Copy(srcPtr);
+
+ devices[aDeviceCount].Set(elem);
+
+ TInt servs = elem->ServiceList().Count();
+
+ TUpnpService* tempServ = new TUpnpService[aServiceCount+servs];
+ if ( !tempServ )
+ {
+ delete [] temp;
+ temp = NULL;
+ devices = NULL;
+ continue;
+ }
+
+ destPtr.Set(reinterpret_cast<TUint8*>(tempServ),
+ 0,
+ sizeof(TUpnpService)*(aServiceCount+servs));
+ srcPtr.Set(reinterpret_cast<TUint8*>(services),
+ sizeof(TUpnpService)*aServiceCount,
+ sizeof(TUpnpService)*aServiceCount);
+
+ destPtr.Copy(srcPtr);
+
+ if (services)
+ {
+ delete[] services;
+ services = NULL;
+ }
+
+ services = tempServ;
+
+ for (TInt j=0; j<servs; j++)
+ {
+ TUpnpService service;
+ destPtr.Set(reinterpret_cast<TUint8*>(&services[aServiceCount]),
+ 0,
+ sizeof(TUpnpService));
+ srcPtr.Set(reinterpret_cast<TUint8*>(&service),
+ sizeof(TUpnpService),
+ sizeof(TUpnpService));
+ destPtr.Copy(srcPtr);
+
+ services[aServiceCount].iServiceType.Zero();
+ services[aServiceCount].iServiceType.Append(
+ elem->ServiceList()[j] );
+
+ aServiceCount++;
+ }
+
+ aDeviceCount++;
+ }
+ }
+
+ aUpdateId = iUpdateId;
+
+ aDevices = devices;
+ aServices = services;
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpDeviceLibrary::RemoveAllDevicesL
+// Removes all remote devices from device library.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CUpnpDeviceLibrary::RemoveAllDevicesL()
+ {
+ for (TInt i = 0; i < iElementArray.Count(); i++)
+ {
+ CUpnpDeviceLibraryElement* elem = iElementArray[i];
+ if ( elem->Alive() )
+ {
+ iUpdateId++;
+ elem->SetAlive(EFalse);
+ elem->SetUpdateId( iUpdateId );
+ if( elem->Renew() == CUpnpTimeoutElement::EOnce )
+ {
+ elem->SetRenew( CUpnpTimeoutElement::ERemove );
+ elem->SetTimeout( KIpcCommunicationTimeout );
+ }
+ }
+ }
+ iObserver.DeviceListChangedL();
+ }
+
+// -----------------------------------------------------------------------------
+// TUpnpDevice::Set
+// Set device.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void TUpnpDevice::Set(CUpnpDeviceLibraryElement* aElem)
+ {
+ LOGS("Devicelibrary Set");
+
+ if ( !aElem )
+ {
+ return;
+ }
+
+ iDescriptionURL = aElem->DescriptionUrl().Left( iDescriptionURL.MaxLength() );
+ iUUID = aElem->UUID().Left( iUUID.MaxLength() );
+ iDeviceType = aElem->DeviceType().Left( iDeviceType.MaxLength() );
+ iDomain = aElem->Domain().Left( iDomain.MaxLength() );
+
+ iServiceCount = aElem->ServiceList().Count();
+ iLocal = aElem->Local();
+ iRemote = EFalse;
+ iAlive = aElem->Alive();
+ iExpired = aElem->Expired();
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpDeviceLibrary::AddDeviceL
+// Add a device.
+// -----------------------------------------------------------------------------
+//
+TBool CUpnpDeviceLibrary::AddDeviceL(CUpnpSsdpMessage *aMessage)
+ {
+ TBool update = EFalse;
+
+ LOGSH( iHandle, "Devicelibrary AddDeviceL");
+
+ if ( !aMessage )
+ {
+ return update;
+ }
+
+ TPtr8 uuidPtr = aMessage->Uuid();
+ TInt index = Find( uuidPtr );
+
+ if (index != KErrNotFound)
+ {
+ CUpnpDeviceLibraryElement* elem = iElementArray[index];
+ if ( !elem->Local() )
+ {
+ if( elem->Renew() == CUpnpTimeoutElement::ERemove )
+ {
+ iElementArray.Remove( index );
+ iElementArray.Compress();
+
+ delete elem;
+
+ CUpnpDeviceLibraryElement* element = CUpnpDeviceLibraryElement::NewL(*this);
+ CleanupStack::PushL(element);
+
+ update = element->AddInfoL(aMessage, iUpdateId);
+
+ element->SetRenew(CUpnpTimeoutElement::EOnce);
+ element->SetTimeout(aMessage->CacheControl());
+ element->SetLocal(EFalse);
+ iElementArray.Append(element);
+
+ CleanupStack::Pop(); // element
+ }
+
+ else
+ {
+ if(elem->Filter())
+ {
+ //Alive message from
+ if(elem->AddInfoL(aMessage, iUpdateId))
+ {
+ update=ETrue;
+ }
+ elem->SetTimeout(aMessage->CacheControl());
+ }
+ else
+ {
+ iElementArray.Remove( index );
+ iElementArray.Compress();
+
+ delete elem;
+
+ CUpnpDeviceLibraryElement* element = CUpnpDeviceLibraryElement::NewL(*this);
+ CleanupStack::PushL(element);
+
+ update = element->AddInfoL(aMessage, iUpdateId);
+
+ element->SetRenew(CUpnpTimeoutElement::EOnce);
+ element->SetTimeout(aMessage->CacheControl());
+ element->SetLocal(EFalse);
+ iElementArray.Append(element);
+
+ CleanupStack::Pop(); // element
+ }
+ }
+ }
+ }
+ else
+ {
+ CUpnpDeviceLibraryElement* element = CUpnpDeviceLibraryElement::NewL(*this);
+ CleanupStack::PushL(element);
+
+ update = element->AddInfoL(aMessage, iUpdateId);
+
+ element->SetRenew(CUpnpTimeoutElement::EOnce);
+ element->SetTimeout(aMessage->CacheControl());
+ element->SetLocal(EFalse);
+ iElementArray.Append(element);
+
+ CleanupStack::Pop(); // element
+ }
+ return update;
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpDeviceLibrary::RemoveDevice
+// Remove a device.
+// -----------------------------------------------------------------------------
+//
+void CUpnpDeviceLibrary::RemoveDeviceL( CUpnpSsdpMessage *aMessage )
+ {
+ LOGSH( iHandle, "Devicelibrary RemoveDevice" );
+
+ if ( !aMessage )
+ {
+ return;
+ }
+
+ TPtr8 uuidPtr = aMessage->Uuid();
+ TInt index = Find( uuidPtr );
+
+ if ( index != KErrNotFound )
+ {
+ CUpnpDeviceLibraryElement* elem = iElementArray[index];
+ if ( !elem->Local() )
+ {
+ if ( elem->Alive() )
+ {
+ iUpdateId++;
+ elem->SetAlive(EFalse);
+ elem->SetUpdateId( iUpdateId );
+ if( elem->Renew() == CUpnpTimeoutElement::EOnce )
+ {
+ elem->SetRenew( CUpnpTimeoutElement::ERemove );
+ elem->SetTimeout( KIpcCommunicationTimeout );
+ }
+ }
+ iObserver.DeviceListChangedL();
+ }
+ }
+ else
+ {
+ CUpnpDeviceLibraryElement* element = CUpnpDeviceLibraryElement::NewL( *this );
+ CleanupStack::PushL( element );
+
+ element->AddInfoL( aMessage, iUpdateId );
+
+ iUpdateId++;
+ element->SetAlive( EFalse );
+ element->SetUpdateId( iUpdateId );
+ element->SetRenew( CUpnpTimeoutElement::ERemove );
+ element->SetTimeout( KIpcCommunicationTimeout );
+ element->SetLocal( EFalse );
+ iElementArray.AppendL( element );
+
+ CleanupStack::Pop( element );
+
+ iObserver.DeviceListChangedL();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpDeviceLibrary::StopFilteringDeviceL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CUpnpDeviceLibrary::StopFilteringDeviceL( const TDesC8& aUuid )
+ {
+ LOGSH( iHandle, "Devicelibrary RemoveDevice" );
+
+ TInt index = Find( aUuid );
+
+ if ( index != KErrNotFound )
+ {
+ CUpnpDeviceLibraryElement* elem = iElementArray[index];
+ elem->SetFilter(EFalse);
+ }
+ }
+
+// End of File