upnpavcontroller/upnpavcontrollerserver/src/upnpdevicerepository.cpp
branchnew development branch with rendering state machine and other goodies
changeset 38 5360b7ddc251
parent 32 3785f754ee62
--- a/upnpavcontroller/upnpavcontrollerserver/src/upnpdevicerepository.cpp	Fri Sep 17 08:31:21 2010 +0300
+++ b/upnpavcontroller/upnpavcontrollerserver/src/upnpdevicerepository.cpp	Mon Nov 01 12:37:49 2010 +0200
@@ -1,613 +1,751 @@
-/*
-* Copyright (c) 2005-2006 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:      storage for devices with extended information
-*
-*/
-
-
-
-
-
-
-// INCLUDE FILES
-#include "upnpdevicerepository.h"
-
-#include "upnpavdeviceextended.h"
-
-#include <upnpservice.h>
-#include <upnpdevice.h>
-#include <upnpavcontrolpoint.h>
-
-// CONSTANTS
-_LIT8( KSearch,                     "Search" );
-_LIT8( KVolume,                     "Volume" );
-_LIT8( KCreateObject,               "CreateObject" );
-_LIT8( KPause,                      "Pause");
-_LIT8( KSetVolume,                  "SetVolume");
-_LIT8( KGetVolume,                  "GetVolume");
-_LIT8( KGetMute,                    "GetMute");
-_LIT8( KSetMute,                    "SetMute");
-_LIT8( KMediaServer,                "MediaServer" );
-_LIT8( KFriendlyName,               "friendlyName" );
-_LIT8( KAVTransportService,         "AVTransport" );
-_LIT8( KRenderingControlService,    "RenderingControl" );
-_LIT8( KSetNextUri,                 "SetNextAVTransportURI" );
-_LIT8( KDestroyObject,              "DestroyObject" );
-_LIT8( KDlnaDoc,                    "dlna:X_DLNADOC" );
-_LIT8( KDlnaCap,                    "dlna:X_DLNACAP" );
-_LIT8( KAudioUpload,                "audio-upload" );
-_LIT8( KImageUpload,                "image-upload" );
-_LIT8( KVideoUpload,                "av-upload" );
-_LIT8( KCreateChildContainer,       "create-child-container" );
-_LIT8( KDMS,                        "DMS" );
-_LIT8( KDMP,                        "DMP" );
-_LIT8( KDMR,                        "DMR" );
-
-const TInt KFirstSubscription = 1;
-
-_LIT( KComponentLogfile, "upnpavcontrollerserver.txt");
-#include "upnplog.h"
-
-// ============================ MEMBER FUNCTIONS ============================
-
-// --------------------------------------------------------------------------
-// CUPnPDeviceRepository::NewL
-// See upnpdevicerepository.h
-// --------------------------------------------------------------------------
-CUPnPDeviceRepository* CUPnPDeviceRepository::NewL
-    (
-    CUpnpAVControlPoint& aControlPoint
-    )
-    {
-    CUPnPDeviceRepository* rep= new(ELeave)
-        CUPnPDeviceRepository( aControlPoint );
-    CleanupStack::PushL( rep );
-    rep->ConstructL();
-    CleanupStack::Pop();
-    return rep;
-    }
-
-// --------------------------------------------------------------------------
-// CUPnPDeviceRepository::~CUPnPDeviceRepository
-// See upnpdevicerepository.h
-// --------------------------------------------------------------------------
-CUPnPDeviceRepository::~CUPnPDeviceRepository()
-    {     
-    iDevices.ResetAndDestroy();
-    iDevices.Close();
-    }
-    
-// --------------------------------------------------------------------------
-// CUPnPDeviceRepository::CUPnPDeviceRepository
-// See upnpdevicerepository.h
-// --------------------------------------------------------------------------
-CUPnPDeviceRepository::CUPnPDeviceRepository
-    (
-    CUpnpAVControlPoint& aControlPoint
-    ):
-    iControlPoint( aControlPoint ),
-    iIsWlanActive( ETrue )    
-    {
-    }
-    
-// --------------------------------------------------------------------------
-// CUPnPDeviceRepository::ConstructL
-// See upnpdevicerepository.h
-// --------------------------------------------------------------------------
-void CUPnPDeviceRepository::ConstructL()
-    {
-    __LOG( "CUPnPDeviceRepository::ConstructL" );
-    }
-
-// --------------------------------------------------------------------------
-// CUPnPDeviceRepository::AddDeviceL
-// See upnpdevicerepository.h
-// --------------------------------------------------------------------------
-void CUPnPDeviceRepository::AddDeviceL( CUpnpDevice& aDevice )
-    {
-    __LOG( "CUPnPDeviceRepository::AddDeviceL" );
-        
-    CUpnpAVDeviceExtended* dev = CUpnpAVDeviceExtended::NewL();
-    CleanupStack::PushL( dev );
-    
-    // Check if it's a dlna device
-    TPtrC8 ptr = aDevice.GetProperty( KDlnaDoc );
-    if( ptr.Length() > 0 )
-        {
-        __LOG( "Dlna compatible device!" );
-        // It's a dlna device
-        dev->SetDlnaCompatible( ETrue );
-        
-        if( ptr.FindC( KDMS ) != KErrNotFound )
-            {
-            dev->SetDLNADeviceType( CUpnpAVDeviceExtended::EDMS );
-            }
-        else if( ptr.FindC( KDMR ) != KErrNotFound )
-            {
-            dev->SetDLNADeviceType( CUpnpAVDeviceExtended::EDMR );
-            }
-        else if( ptr.FindC( KDMP ) != KErrNotFound )
-            {
-            dev->SetDLNADeviceType( CUpnpAVDeviceExtended::EDMP );
-            }        
-        
-        // Check dlna capabilities
-        ptr.Set( aDevice.GetProperty( KDlnaCap ) );
-        if( ptr.Find( KAudioUpload ) != KErrNotFound )        
-            {
-            __LOG( "Audio upload supported!" );
-            dev->SetAudioUpload( ETrue );
-            }
-        if( ptr.Find( KImageUpload ) != KErrNotFound )
-            {
-            __LOG( "Image upload supported!" );
-            dev->SetImageUpload( ETrue );
-            }
-        if( ptr.Find( KVideoUpload ) != KErrNotFound )
-            {
-            __LOG( "Video upload supported!" );
-            dev->SetVideoUpload( ETrue );
-            }
-        if( ptr.Find( KCreateChildContainer ) != KErrNotFound )
-            {
-            __LOG( "Create child container supported!" );
-            dev->SetCreateChildContainer( ETrue );
-            }        
-        }   
-        
-    if( aDevice.DeviceType().Find( KMediaServer ) != KErrNotFound )
-        {
-        dev->SetDeviceType( CUpnpAVDevice::EMediaServer );
-        }
-    else
-        {
-        dev->SetDeviceType( CUpnpAVDevice::EMediaRenderer );
-        }
-
-    dev->SetFriendlyNameL( aDevice.DescriptionProperty( KFriendlyName ) );
-
-    dev->SetUuidL( aDevice.Uuid() );   
-    
-    dev->SetLocal( aDevice.Local() );
-    
-    ParseDeviceServicesL( aDevice, *dev );
-    CleanupStack::Pop( dev );
-    iDevices.AppendL( dev );
-    }
-    
-// --------------------------------------------------------------------------
-// CUPnPDeviceRepository::AddProtocolInfoL
-// See upnpdevicerepository.h
-// --------------------------------------------------------------------------
-CUpnpAVDeviceExtended& CUPnPDeviceRepository::AddProtocolInfoL(
-    const TDesC8& aUuid, const TDesC8& aSource, const TDesC8& aSink )
-    {
-    __LOG( "CUPnPDeviceRepository::AddProtocolInfoL" );
-    
-    // Find the device
-    TInt count = iDevices.Count();
-    CUpnpAVDeviceExtended* dev = NULL;
-    for( TInt i = 0; i < count; i++ )
-        {
-        if( iDevices[ i ]->Uuid() == aUuid )
-            {
-            dev = iDevices[ i ];
-            i = count;
-            }
-        }
-    if( dev )
-        {
-        if( dev->DeviceType() == CUpnpAVDevice::EMediaServer )
-            {
-            dev->SetSourceProtocolInfoL( aSource );
-            dev->SetSinkProtocolInfoL( aSink );
-            dev->SetCapabilitiesBySupportedMimeTypesL( aSource );
-            }
-        else
-            {
-            dev->SetSourceProtocolInfoL( aSource );
-            dev->SetSinkProtocolInfoL( aSink );
-            dev->SetCapabilitiesBySupportedMimeTypesL( aSink );    
-            }
-        dev->SetPInfoReceived( ETrue );        
-        }
-    else
-        {
-        User::Leave( KErrNotFound );
-        }    
-    return *dev;
-    }
-
-// --------------------------------------------------------------------------
-// CUPnPDeviceRepository::Remove
-// See upnpdevicerepository.h
-// --------------------------------------------------------------------------
-void CUPnPDeviceRepository::Remove( const TDesC8& aUuid )
-    {
-    __LOG( "CUPnPDeviceRepository::Remove" );
-    
-    TInt count = iDevices.Count();
-    for( TInt i = 0; i < count; i++ )
-        {
-        if( iDevices[ i ]->Uuid() == aUuid )
-            {
-            delete iDevices[ i ];
-            iDevices.Remove( i );
-            i = count;
-            }
-        }
-    
-    }
-
-// --------------------------------------------------------------------------
-// CUPnPDeviceRepository::FindDeviceL
-// See upnpdevicerepository.h
-// --------------------------------------------------------------------------
-CUpnpAVDeviceExtended& CUPnPDeviceRepository::FindDeviceL(
-    const TDesC8& aUuid )
-    {
-    __LOG( "CUPnPDeviceRepository::FindDeviceL" );
-    
-    CUpnpAVDeviceExtended* tmp = NULL;
-    TInt count = iDevices.Count();
-    for( TInt i = 0; i < count; i++ )
-        {
-        if( iDevices[ i ]->Uuid() == aUuid )
-            {
-            tmp = iDevices[ i ];
-            i = count;
-            }
-        }
-    if( !tmp )
-        {
-        __LOG( "FindDeviceL - not found" );
-        
-        User::Leave( KErrNotFound );
-        }
-    return *tmp;    
-    }
-
-// --------------------------------------------------------------------------
-// CUPnPDeviceRepository::DeviceList
-// See upnpdevicerepository.h
-// --------------------------------------------------------------------------
-const RPointerArray<CUpnpAVDeviceExtended>&
-    CUPnPDeviceRepository::DeviceList() const
-    {
-    __LOG( "CUPnPDeviceRepository::DeviceList" );
-    
-    return iDevices;
-    }
-   
-// --------------------------------------------------------------------------
-// CUPnPDeviceRepository::SubscribeDeviceL
-// See upnpdevicerepository.h
-// --------------------------------------------------------------------------
-void CUPnPDeviceRepository::SubscribeDeviceL( const TDesC8& aUuid )
-    {
-    __LOG( "CUPnPDeviceRepository::SubscribeDeviceL" );
-    __LOG8( aUuid );
-    
-    // Find the device and increase subscription count/check if we have
-    // subscribed already
-    TInt count = iDevices.Count();
-    TInt subscriptionCount = KErrNotFound;
-    TInt index;
-    for( index = 0; index < count; index++ )
-        {
-        if( aUuid.Compare( iDevices[ index ]->Uuid() ) == 0 )
-            {
-            subscriptionCount = iDevices[ index ]->IncreaseSubscriptionCount();
-            index = count;
-            }
-        }
-    if( subscriptionCount == KFirstSubscription )
-        {
-        __LOG( "SubscribeDeviceL - First subscription" ); 
-        
-        // Start subsciption for AVTransport and RenderingControl services
-        // Find the device
-        const RPointerArray<CUpnpDevice>& devList =
-            iControlPoint.DeviceList();
-        count = devList.Count();
-        for( index = 0; index < count; index++ )
-            {
-            if( aUuid.Compare( devList[ index ]->Uuid() ) == 0 )
-                {
-                break;
-                }
-            }
-
-        // Find the AVTransport service and subscribe
-        RPointerArray<CUpnpService>& servList =
-            devList[ index ]->ServiceList();
-        count = servList.Count();
-        CUpnpService* tempService = NULL;
-        for( index = 0; index < count; index++ )
-            {
-            if( servList[ index ]->ServiceType().Find(
-                KAVTransportService ) >= 0 )
-                {
-                tempService = servList[ index ];
-                index = count;
-                }
-            }
-        if( tempService && iIsWlanActive )
-            {
-            // AVTransport service found for the device, subscribe
-            __LOG( "SubscribeDeviceL - Subscribe for AVTransport" ); 
-            iControlPoint.SubscribeL( tempService ); 
-            }
-        else
-            {     
-            // Service not found, can't subscribe
-            __LOG( "SubscribeDeviceL - AVTransport service not found" );
-            }
-            
-        tempService = NULL;
-        for( index = 0; index < count; index++ )
-            {
-            if( servList[ index ]->ServiceType().Find(
-                KRenderingControlService ) >= 0 )
-                {
-                tempService = servList[ index ];
-                index = count;
-                }
-            }
-        if( tempService && iIsWlanActive )
-            {
-            // RenderingControl service found for the device, subscribe
-            __LOG( "SubscribeDeviceL - Subscribe for RenderingControl" ); 
-            iControlPoint.SubscribeL( tempService ); 
-            }
-        else
-            {     
-            // Service not found, can't subscribe
-            __LOG( "SubscribeDeviceL - RenderingControl service not found" );
-            }                    
-        }
-    else if( subscriptionCount == KErrNotFound ) 
-        {
-        __LOG( "SubscribeDeviceL - device not found" );
-        }
-    else
-        {
-        // Subscribed already, do nothing
-        __LOG( "SubscribeDeviceL - Subscription done already, ignoring!" ); 
-        }        
-    }
-    
-// --------------------------------------------------------------------------
-// CUPnPDeviceRepository::UnSubscribeDeviceL
-// See upnpdevicerepository.h
-// --------------------------------------------------------------------------
-void CUPnPDeviceRepository::UnSubscribeDeviceL( const TDesC8& aUuid )
-    {
-    __LOG( "CUPnPDeviceRepository::UnSubscribeDeviceL" );
-    __LOG8( aUuid );
-    
-    // Find the device and decrease subscription count/check if it's needed
-    // to unsubscribe
-    TInt count = iDevices.Count();
-    TInt subscriptionCount = KErrNotFound;
-    TInt index;
-    for( index = 0; index < count; index++ )
-        {
-        if( aUuid.Compare( iDevices[ index ]->Uuid() ) == 0 )
-            {
-            subscriptionCount = 
-                iDevices[ index ]->DecreaseSubscriptionCount();
-            index = count;
-            }
-        }    
-    
-    if( subscriptionCount == 0 )
-        {   
-        // Start unsubsciption for AVTransport and RenderingControl services
-        // Find the device
-        const RPointerArray<CUpnpDevice>& devList =
-            iControlPoint.DeviceList();
-        count = devList.Count();
-        for( index = 0; index < count; index++ )
-            {
-            if( aUuid.Compare( devList[ index ]->Uuid() ) == 0 )
-                {
-                break;
-                }
-            }
-
-        // Find the AVTransport service and unsubscribe
-        RPointerArray<CUpnpService>& servList =
-            devList[ index ]->ServiceList();
-        count = servList.Count();
-        CUpnpService* tempService = NULL;
-        for( index = 0; index < count; index++ )
-            {
-            if( servList[ index ]->ServiceType().Find(
-                KAVTransportService ) >= 0 )
-                {
-                tempService = servList[ index ];
-                index = count;
-                }
-            }
-        if( tempService && iIsWlanActive )
-            {
-            // AVTransport service found for the device, unsubscribe
-            __LOG( "UnSubscribeDeviceL - UnSubscribe AVTransport" ); 
-            iControlPoint.UnsubscribeL( tempService ); 
-            }
-        else
-            {     
-            // Service not found, can't unsubscribe
-            __LOG( "UnSubscribeDeviceL - AVTransport service not found" );
-            }
-            
-        tempService = NULL;
-        for( index = 0; index < count; index++ )
-            {
-            if( servList[ index ]->ServiceType().Find(
-                KRenderingControlService ) >= 0 )
-                {
-                tempService = servList[ index ];
-                index = count;
-                }
-            }
-        if( tempService && iIsWlanActive )
-            {
-            // RenderingControl service found for the device, subscribe
-            __LOG( "UnSubscribeDeviceL - UnSubscribe RenderingControl" ); 
-            iControlPoint.UnsubscribeL( tempService ); 
-            }
-        else
-            {     
-            // Service not found, can't subscribe
-            __LOG( "UnSubscribeDeviceL - RenderingControl service not\
-found" );
-            }                    
-        }
-    else if( subscriptionCount == KErrNotFound ) 
-        {
-        __LOG( "UnSubscribeDeviceL - device not found" );
-        }
-    else
-        {
-        // No need to unsubscibe
-        }           
-    }
-
-void CUPnPDeviceRepository::ConnectionLost()
-    {
-    __LOG( "CUPnPDeviceRepository::ConnectionLost" );
-    iIsWlanActive = EFalse;
-    iDevices.ResetAndDestroy();
-    }
-
-TBool CUPnPDeviceRepository::IsWlanActive()
-    {
-    __LOG1( "CUPnPDeviceRepository::IsWlanActive, %d", (TInt)iIsWlanActive );
-    return iIsWlanActive;
-    }
-
-// --------------------------------------------------------------------------
-// CUPnPDeviceRepository::ParseDeviceServicesL
-// See upnpdevicerepository.h
-// --------------------------------------------------------------------------
-void CUPnPDeviceRepository::ParseDeviceServicesL( CUpnpDevice& aSource,
-    CUpnpAVDeviceExtended& aTarget )
-    {
-    __LOG( "CUPnPDeviceRepository::ParseDeviceServicesL" );
-    
-    TBool createObjectSupported = EFalse;
-    TBool getMuteSupported = EFalse;
-    TBool setMuteSupported = EFalse;
-    TBool getVolumeSupported = EFalse;
-    TBool setVolumeSupported = EFalse;
-
-    RPointerArray<CUpnpService>services = aSource.ServiceList();
-
-    TInt i;
-    TInt count = services.Count(); 
-    for( i = 0; i < count; i++ )
-        {
-        // Get max volume if it exists
-        CUpnpStateVariable* volumeState = 
-                services[ i ]->StateVariable( KVolume );
-
-        // If volume info found, save it to the device
-        if( volumeState )
-            {
-            TInt maxVolume = volumeState->MaxValue();
-            // If max volume not defined, it is set to 100
-            if( maxVolume == KErrNotFound )
-                {
-                maxVolume = 100;
-                }
-            aTarget.SetMaxVolume( maxVolume );
-            }
-
-        // Get the actions
-        RPointerArray<CUpnpAction> actions;
-        services[ i ]->GetActionList( actions );
-
-        // Go through the action elements
-        TInt j;
-        TInt count2 = actions.Count();
-        for( j = 0; j < count2; j++ )
-            {
-            TDesC8& actionName = actions[ j ]->Name();
-
-            if( actionName != KNullDesC8 )
-                {
-                if( actionName.Find( KCreateObject ) >= 0 )
-                    {
-                    createObjectSupported = ETrue;
-                    }
-                if( actionName.Compare( KSearch ) == 0 )
-                    {
-                    aTarget.SetSearchCapability( ETrue );
-                    }
-                if( actionName.Find( KPause ) >= 0 )
-                    {
-                    aTarget.SetPauseCapability( ETrue );
-                    }
-                if( actionName.Find( KGetVolume ) >= 0 )
-                    {
-                    getVolumeSupported = ETrue;
-                    }
-                if( actionName.Find( KSetVolume ) >= 0 )
-                    {
-                    setVolumeSupported = ETrue;
-                    }
-                if( actionName.Find( KGetMute ) >= 0 )
-                    {
-                    getMuteSupported = ETrue;
-                    }
-                if( actionName.Find( KSetMute ) >= 0 )
-                    {
-                    setMuteSupported = ETrue;
-                    }
-                if( actionName.Find( KSetNextUri ) >= 0 )
-                    {
-                    aTarget.SetNextAVTransportUri( ETrue );
-                    }
-                if( actionName.Find( KDestroyObject ) >= 0 )
-                    {
-                    aTarget.SetDestroyObject( ETrue );
-                    }                    
-                }
-            }
-        }
-
-    // Set copy support
-    if( createObjectSupported )
-        {
-        aTarget.SetCopyCapability( ETrue );
-        }
-
-    // Set volume support
-    if( getVolumeSupported &&
-        setVolumeSupported )
-        {
-        aTarget.SetVolumeCapability( ETrue );
-        }
-
-    // Set mute support
-    if( getMuteSupported &&
-        setMuteSupported )
-        {
-        aTarget.SetMuteCapability( ETrue );
-        }
-    }        
-
-// end of file
+/*
+* Copyright (c) 2005-2006 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:      storage for devices with extended information
+*
+*/
+
+
+
+
+
+
+// INCLUDE FILES
+#include "upnpdevicerepository.h"
+
+#include "upnpavdeviceextended.h"
+#include "upnpavcontrolpoint.h"
+
+#include <upnpservice.h>
+#include <upnpdevice.h>
+#include <upnpicon.h>
+#include "upnpavcontrollerglobals.h"    // For KRel_Time
+
+// CONSTANTS
+_LIT8( KSearch,                     "Search" );
+_LIT8( KVolume,                     "Volume" );
+_LIT8( KCreateObject,               "CreateObject" );
+_LIT8( KPause,                      "Pause");
+_LIT8( KSetVolume,                  "SetVolume");
+_LIT8( KGetVolume,                  "GetVolume");
+_LIT8( KGetMute,                    "GetMute");
+_LIT8( KSetMute,                    "SetMute");
+_LIT8( KMediaServer,                "MediaServer" );
+_LIT8( KFriendlyName,               "friendlyName" );
+_LIT8( KModelName,                  "modelName" );
+_LIT8( KAVTransportService,         "AVTransport" );
+_LIT8( KRenderingControlService,    "RenderingControl" );
+_LIT8( KSetNextUri,                 "SetNextAVTransportURI" );
+_LIT8( KPrepareForConnection,       "PrepareForConnection" );
+_LIT8( KDestroyObject,              "DestroyObject" );
+_LIT8( KDlnaDoc,                    "dlna:X_DLNADOC" );
+_LIT8( KDlnaCap,                    "dlna:X_DLNACAP" );
+_LIT8( KAudioUpload,                "audio-upload" );
+_LIT8( KImageUpload,                "image-upload" );
+_LIT8( KVideoUpload,                "av-upload" );
+_LIT8( KCreateChildContainer,       "create-child-container" );
+_LIT8( KDMS,                        "DMS" );
+_LIT8( KDMP,                        "DMP" );
+_LIT8( KDMR,                        "DMR" );
+_LIT8( KJpg,                        "jpg" );
+_LIT8( KJpeg,                       "jpeg" );
+_LIT8( KPng,                        "png" );
+// Prefer 48x48 color icons and then greater size color icons
+const TInt KPreferredIconSize = 48;
+
+// Seek mode argument type string
+_LIT8( KArgumentTypeSeekMode, "A_ARG_TYPE_SeekMode" );
+
+const TInt KFirstSubscription = 1;
+
+_LIT( KComponentLogfile, "upnpavcontrollerserver.txt");
+#include "upnplog.h"
+
+// ============================ MEMBER FUNCTIONS ============================
+
+// --------------------------------------------------------------------------
+// CUPnPDeviceRepository::NewL
+// See upnpdevicerepository.h
+// --------------------------------------------------------------------------
+CUPnPDeviceRepository* CUPnPDeviceRepository::NewL
+    (
+    CUpnpAVControlPoint& aControlPoint
+    )
+    {
+    CUPnPDeviceRepository* rep= new(ELeave)
+        CUPnPDeviceRepository( aControlPoint );
+    CleanupStack::PushL( rep );
+    rep->ConstructL();
+    CleanupStack::Pop();
+    return rep;
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPDeviceRepository::~CUPnPDeviceRepository
+// See upnpdevicerepository.h
+// --------------------------------------------------------------------------
+CUPnPDeviceRepository::~CUPnPDeviceRepository()
+    {     
+    iDevices.ResetAndDestroy();
+    iDevices.Close();
+    }
+    
+// --------------------------------------------------------------------------
+// CUPnPDeviceRepository::CUPnPDeviceRepository
+// See upnpdevicerepository.h
+// --------------------------------------------------------------------------
+CUPnPDeviceRepository::CUPnPDeviceRepository
+    (
+    CUpnpAVControlPoint& aControlPoint
+    ):
+    iControlPoint( aControlPoint ),
+    iIsWlanActive( ETrue )    
+    {
+    }
+    
+// --------------------------------------------------------------------------
+// CUPnPDeviceRepository::ConstructL
+// See upnpdevicerepository.h
+// --------------------------------------------------------------------------
+void CUPnPDeviceRepository::ConstructL()
+    {
+    __LOG( "CUPnPDeviceRepository::ConstructL" );
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPDeviceRepository::AddDeviceL
+// See upnpdevicerepository.h
+// --------------------------------------------------------------------------
+CUpnpAVDeviceExtended& CUPnPDeviceRepository::AddDeviceL( CUpnpDevice& aDevice )
+    {
+    __LOG( "CUPnPDeviceRepository::AddDeviceL" );
+        
+    CUpnpAVDeviceExtended* dev = CUpnpAVDeviceExtended::NewL();
+    CleanupStack::PushL( dev );
+    
+    // Check if it's a dlna device
+    TPtrC8 ptr = aDevice.GetProperty( KDlnaDoc );
+    if( ptr.Length() > 0 )
+        {
+        __LOG( "Dlna compatible device!" );
+        // It's a dlna device
+        dev->SetDlnaCompatible( ETrue );
+        
+        if( ptr.FindC( KDMS ) != KErrNotFound )
+            {
+            dev->SetDLNADeviceType( CUpnpAVDeviceExtended::EDMS );
+            }
+        else if( ptr.FindC( KDMR ) != KErrNotFound )
+            {
+            dev->SetDLNADeviceType( CUpnpAVDeviceExtended::EDMR );
+            }
+        else if( ptr.FindC( KDMP ) != KErrNotFound )
+            {
+            dev->SetDLNADeviceType( CUpnpAVDeviceExtended::EDMP );
+            }        
+        
+        // Check dlna capabilities
+        ptr.Set( aDevice.GetProperty( KDlnaCap ) );
+        if( ptr.Find( KAudioUpload ) != KErrNotFound )        
+            {
+            __LOG( "Audio upload supported!" );
+            dev->SetAudioUpload( ETrue );
+            }
+        if( ptr.Find( KImageUpload ) != KErrNotFound )
+            {
+            __LOG( "Image upload supported!" );
+            dev->SetImageUpload( ETrue );
+            }
+        if( ptr.Find( KVideoUpload ) != KErrNotFound )
+            {
+            __LOG( "Video upload supported!" );
+            dev->SetVideoUpload( ETrue );
+            }
+        if( ptr.Find( KCreateChildContainer ) != KErrNotFound )
+            {
+            __LOG( "Create child container supported!" );
+            dev->SetCreateChildContainer( ETrue );
+            }        
+        }   
+        
+    if( aDevice.DeviceType().Find( KMediaServer ) != KErrNotFound )
+        {
+        dev->SetDeviceType( CUpnpAVDevice::EMediaServer );
+        }
+    else
+        {
+        dev->SetDeviceType( CUpnpAVDevice::EMediaRenderer );
+        }
+
+    dev->SetFriendlyNameL( aDevice.DescriptionProperty( KFriendlyName ) );
+
+    dev->SetModelNameL( aDevice.DescriptionProperty( KModelName ) );
+    
+    dev->SetUuidL( aDevice.Uuid() );   
+    
+    dev->SetLocal( aDevice.Local() );
+
+    ParseDeviceServicesL( aDevice, *dev );
+
+    SelectDeviceIconL( aDevice, *dev );
+
+    CleanupStack::Pop( dev );
+    iDevices.AppendL( dev );
+    return *dev;
+    }
+    
+// --------------------------------------------------------------------------
+// CUPnPDeviceRepository::AddProtocolInfoL
+// See upnpdevicerepository.h
+// --------------------------------------------------------------------------
+CUpnpAVDeviceExtended& CUPnPDeviceRepository::AddProtocolInfoL(
+    const TDesC8& aUuid, const TDesC8& aSource, const TDesC8& aSink )
+    {
+    __LOG( "CUPnPDeviceRepository::AddProtocolInfoL" );
+    
+    // Find the device
+    TInt count = iDevices.Count();
+    CUpnpAVDeviceExtended* dev = NULL;
+    for( TInt i = 0; i < count; i++ )
+        {
+        if( iDevices[ i ]->Uuid() == aUuid )
+            {
+            dev = iDevices[ i ];
+            i = count;
+            }
+        }
+    if( dev )
+        {
+        if( dev->DeviceType() == CUpnpAVDevice::EMediaServer )
+            {
+            dev->SetSourceProtocolInfoL( aSource );
+            dev->SetSinkProtocolInfoL( aSink );
+            dev->SetCapabilitiesBySupportedMimeTypesL( aSource );
+            }
+        else
+            {
+            dev->SetSourceProtocolInfoL( aSource );
+            dev->SetSinkProtocolInfoL( aSink );
+            dev->SetCapabilitiesBySupportedMimeTypesL( aSink );    
+            }
+        dev->SetPInfoReceived( ETrue );        
+        }
+    else
+        {
+        User::Leave( KErrNotFound );
+        }    
+    return *dev;
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPDeviceRepository::Remove
+// See upnpdevicerepository.h
+// --------------------------------------------------------------------------
+void CUPnPDeviceRepository::Remove( const TDesC8& aUuid )
+    {
+    __LOG( "CUPnPDeviceRepository::Remove" );
+    
+    TInt count = iDevices.Count();
+    for( TInt i = 0; i < count; i++ )
+        {
+        if( iDevices[ i ]->Uuid() == aUuid )
+            {
+            delete iDevices[ i ];
+            iDevices.Remove( i );
+            i = count;
+            }
+        }
+    
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPDeviceRepository::FindDeviceL
+// See upnpdevicerepository.h
+// --------------------------------------------------------------------------
+CUpnpAVDeviceExtended& CUPnPDeviceRepository::FindDeviceL(
+    const TDesC8& aUuid )
+    {
+    __LOG( "CUPnPDeviceRepository::FindDeviceL" );
+    
+    CUpnpAVDeviceExtended* tmp = NULL;
+    TInt count = iDevices.Count();
+    for( TInt i = 0; i < count; i++ )
+        {
+        if( iDevices[ i ]->Uuid() == aUuid )
+            {
+            tmp = iDevices[ i ];
+            i = count;
+            }
+        }
+    if( !tmp )
+        {
+        __LOG( "FindDeviceL - not found" );
+        
+        User::Leave( KErrNotFound );
+        }
+    return *tmp;    
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPDeviceRepository::DeviceList
+// See upnpdevicerepository.h
+// --------------------------------------------------------------------------
+const RPointerArray<CUpnpAVDeviceExtended>&
+    CUPnPDeviceRepository::DeviceList() const
+    {
+    __LOG( "CUPnPDeviceRepository::DeviceList" );
+    
+    return iDevices;
+    }
+   
+// --------------------------------------------------------------------------
+// CUPnPDeviceRepository::SubscribeDeviceL
+// See upnpdevicerepository.h
+// --------------------------------------------------------------------------
+void CUPnPDeviceRepository::SubscribeDeviceL( const TDesC8& aUuid )
+    {
+    __LOG( "CUPnPDeviceRepository::SubscribeDeviceL" );
+    __LOG8( aUuid );
+    
+    // Find the device and increase subscription count/check if we have
+    // subscribed already
+    TInt count = iDevices.Count();
+    TInt subscriptionCount = KErrNotFound;
+    TInt index;
+    for( index = 0; index < count; index++ )
+        {
+        if( aUuid.Compare( iDevices[ index ]->Uuid() ) == 0 )
+            {
+            subscriptionCount = iDevices[ index ]->IncreaseSubscriptionCount();
+            index = count;
+            }
+        }
+    if( subscriptionCount == KFirstSubscription )
+        {
+        __LOG( "SubscribeDeviceL - First subscription" ); 
+        
+        // Start subsciption for AVTransport and RenderingControl services
+        // Find the device
+        const RPointerArray<CUpnpDevice>& devList =
+            iControlPoint.DeviceList();
+        count = devList.Count();
+        for( index = 0; index < count; index++ )
+            {
+            if( aUuid.Compare( devList[ index ]->Uuid() ) == 0 )
+                {
+                break;
+                }
+            }
+
+        // Find the AVTransport service and subscribe
+        RPointerArray<CUpnpService>& servList =
+            devList[ index ]->ServiceList();
+        count = servList.Count();
+        CUpnpService* tempService = NULL;
+        for( index = 0; index < count; index++ )
+            {
+            if( servList[ index ]->ServiceType().Find(
+                KAVTransportService ) >= 0 )
+                {
+                tempService = servList[ index ];
+                index = count;
+                }
+            }
+        if( tempService && iIsWlanActive )
+            {
+            // AVTransport service found for the device, subscribe
+            __LOG( "SubscribeDeviceL - Subscribe for AVTransport" ); 
+            iControlPoint.SubscribeL( tempService ); 
+            }
+        else
+            {     
+            // Service not found, can't subscribe
+            __LOG( "SubscribeDeviceL - AVTransport service not found" );
+            }
+            
+        tempService = NULL;
+        for( index = 0; index < count; index++ )
+            {
+            if( servList[ index ]->ServiceType().Find(
+                KRenderingControlService ) >= 0 )
+                {
+                tempService = servList[ index ];
+                index = count;
+                }
+            }
+        if( tempService && iIsWlanActive )
+            {
+            // RenderingControl service found for the device, subscribe
+            __LOG( "SubscribeDeviceL - Subscribe for RenderingControl" ); 
+            iControlPoint.SubscribeL( tempService ); 
+            }
+        else
+            {     
+            // Service not found, can't subscribe
+            __LOG( "SubscribeDeviceL - RenderingControl service not found" );
+            }                    
+        }
+    else if( subscriptionCount == KErrNotFound ) 
+        {
+        __LOG( "SubscribeDeviceL - device not found" );
+        }
+    else
+        {
+        // Subscribed already, do nothing
+        __LOG( "SubscribeDeviceL - Subscription done already, ignoring!" ); 
+        }        
+    }
+    
+// --------------------------------------------------------------------------
+// CUPnPDeviceRepository::UnSubscribeDeviceL
+// See upnpdevicerepository.h
+// --------------------------------------------------------------------------
+void CUPnPDeviceRepository::UnSubscribeDeviceL( const TDesC8& aUuid )
+    {
+    __LOG( "CUPnPDeviceRepository::UnSubscribeDeviceL" );
+    __LOG8( aUuid );
+    
+    // Find the device and decrease subscription count/check if it's needed
+    // to unsubscribe
+    TInt count = iDevices.Count();
+    TInt subscriptionCount = KErrNotFound;
+    TInt index;
+    for( index = 0; index < count; index++ )
+        {
+        if( aUuid.Compare( iDevices[ index ]->Uuid() ) == 0 )
+            {
+            subscriptionCount = 
+                iDevices[ index ]->DecreaseSubscriptionCount();
+            index = count;
+            }
+        }    
+    
+    if( subscriptionCount == 0 )
+        {   
+        // Start unsubsciption for AVTransport and RenderingControl services
+        // Find the device
+        const RPointerArray<CUpnpDevice>& devList =
+            iControlPoint.DeviceList();
+        count = devList.Count();
+        for( index = 0; index < count; index++ )
+            {
+            if( aUuid.Compare( devList[ index ]->Uuid() ) == 0 )
+                {
+                break;
+                }
+            }
+
+        // Find the AVTransport service and unsubscribe
+        RPointerArray<CUpnpService>& servList =
+            devList[ index ]->ServiceList();
+        count = servList.Count();
+        CUpnpService* tempService = NULL;
+        for( index = 0; index < count; index++ )
+            {
+            if( servList[ index ]->ServiceType().Find(
+                KAVTransportService ) >= 0 )
+                {
+                tempService = servList[ index ];
+                index = count;
+                }
+            }
+        if( tempService && iIsWlanActive )
+            {
+            // AVTransport service found for the device, unsubscribe
+            __LOG( "UnSubscribeDeviceL - UnSubscribe AVTransport" ); 
+            iControlPoint.UnsubscribeL( tempService ); 
+            }
+        else
+            {     
+            // Service not found, can't unsubscribe
+            __LOG( "UnSubscribeDeviceL - AVTransport service not found" );
+            }
+            
+        tempService = NULL;
+        for( index = 0; index < count; index++ )
+            {
+            if( servList[ index ]->ServiceType().Find(
+                KRenderingControlService ) >= 0 )
+                {
+                tempService = servList[ index ];
+                index = count;
+                }
+            }
+        if( tempService && iIsWlanActive )
+            {
+            // RenderingControl service found for the device, subscribe
+            __LOG( "UnSubscribeDeviceL - UnSubscribe RenderingControl" ); 
+            iControlPoint.UnsubscribeL( tempService ); 
+            }
+        else
+            {     
+            // Service not found, can't subscribe
+            __LOG( "UnSubscribeDeviceL - RenderingControl service not\
+found" );
+            }                    
+        }
+    else if( subscriptionCount == KErrNotFound ) 
+        {
+        __LOG( "UnSubscribeDeviceL - device not found" );
+        }
+    else
+        {
+        // No need to unsubscibe
+        }           
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPDeviceRepository::ConnectionLost
+// See upnpdevicerepository.h
+// --------------------------------------------------------------------------
+void CUPnPDeviceRepository::ConnectionLost()
+    {
+    __LOG( "CUPnPDeviceRepository::ConnectionLost" );
+    iIsWlanActive = EFalse;
+    iDevices.ResetAndDestroy();
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPDeviceRepository::IsWlanActive
+// See upnpdevicerepository.h
+// --------------------------------------------------------------------------
+TBool CUPnPDeviceRepository::IsWlanActive()
+    {
+    __LOG1( "CUPnPDeviceRepository::IsWlanActive, %d", (TInt)iIsWlanActive );
+    return iIsWlanActive;
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPDeviceRepository::SetMaxVolume
+// See upnpdevicerepository.h
+// --------------------------------------------------------------------------
+void CUPnPDeviceRepository::SetMaxVolume(CUpnpStateVariable* aVolumeState,
+        CUpnpAVDeviceExtended& aTarget)
+    {
+    if( aVolumeState )
+        {
+        // If volume info found, save it to the device
+        TInt maxVolume = aVolumeState->MaxValue();
+        // If max volume not defined, it is set to 100
+        if( maxVolume == KErrNotFound )
+            {
+            maxVolume = 100;
+            }
+        aTarget.SetMaxVolume( maxVolume );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPDeviceRepository::SetSeekCapabilityL
+// See upnpdevicerepository.h
+// --------------------------------------------------------------------------
+void CUPnPDeviceRepository::SetSeekCapabilityL(CUpnpStateVariable* seekModeStateVariable,
+        CUpnpAVDeviceExtended& aTarget)
+    {
+    if ( seekModeStateVariable ) 
+        {
+        CDesC8Array* allowedSeekModes = 
+            seekModeStateVariable->AllowedValuesLC();
+        if ( allowedSeekModes ) 
+            {
+            for ( TInt i=0 ; i < allowedSeekModes->Count() ; i++ ) 
+                {
+                if ( 0 == allowedSeekModes->
+                            operator[](i).CompareC( KRel_Time() ) )
+                    {
+                    aTarget.SetSeekCapability( CUpnpAVDevice::ERelTime );
+                    break;
+                    }
+                }               
+            }
+        CleanupStack::PopAndDestroy( allowedSeekModes );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPDeviceRepository::ParseDeviceServicesL
+// See upnpdevicerepository.h
+// --------------------------------------------------------------------------
+void CUPnPDeviceRepository::ParseDeviceServicesL( CUpnpDevice& aSource,
+    CUpnpAVDeviceExtended& aTarget )
+    {
+    __LOG( "CUPnPDeviceRepository::ParseDeviceServicesL" );
+    
+    TBool createObjectSupported = EFalse;
+    TBool getMuteSupported = EFalse;
+    TBool setMuteSupported = EFalse;
+    TBool getVolumeSupported = EFalse;
+    TBool setVolumeSupported = EFalse;
+
+    RPointerArray<CUpnpService>& services = aSource.ServiceList();
+
+    TInt i;
+    TInt count = services.Count(); 
+    for( i = 0; i < count; i++ )
+        {
+       CUpnpStateVariable* volumeState = 
+                services[ i ]->StateVariable( KVolume );
+
+       SetMaxVolume(volumeState, aTarget);
+
+        CUpnpStateVariable* seekModeStateVariable = 
+            services[i]->StateVariable( KArgumentTypeSeekMode() );
+        
+        SetSeekCapabilityL(seekModeStateVariable, aTarget);
+
+        // Get the actions
+        RPointerArray<CUpnpAction> actions;
+        // 'actions' cannot be closed, it is the same instance that is inside 'service'
+        services[ i ]->GetActionList( actions );
+
+        // Go through the action elements
+        TInt j;
+        TInt count2 = actions.Count();
+        for( j = 0; j < count2; j++ )
+            {
+            TDesC8& actionName = actions[ j ]->Name();
+
+            if( actionName != KNullDesC8 )
+                {
+                if( actionName.Find( KCreateObject ) >= 0 )
+                    {
+                    createObjectSupported = ETrue;
+                    }
+                if( actionName.Compare( KSearch ) == 0 )
+                    {
+                    aTarget.SetSearchCapability( ETrue );
+                    }
+                if( actionName.Find( KPause ) >= 0 )
+                    {
+                    aTarget.SetPauseCapability( ETrue );
+                    }
+                if( actionName.Find( KGetVolume ) >= 0 )
+                    {
+                    getVolumeSupported = ETrue;
+                    }
+                if( actionName.Find( KSetVolume ) >= 0 )
+                    {
+                    setVolumeSupported = ETrue;
+                    }
+                if( actionName.Find( KGetMute ) >= 0 )
+                    {
+                    getMuteSupported = ETrue;
+                    }
+                if( actionName.Find( KSetMute ) >= 0 )
+                    {
+                    setMuteSupported = ETrue;
+                    }
+                if( actionName.Find( KSetNextUri ) >= 0 )
+                    {
+                    aTarget.SetNextAVTransportUri( ETrue );
+                    }
+                if( actionName.Find( KDestroyObject ) >= 0 )
+                    {
+                    aTarget.SetDestroyObject( ETrue );
+                    }
+                if( actionName.Find( KPrepareForConnection ) >= 0 )
+                    {
+                    aTarget.SetPrepareForConnection( ETrue );
+                    }
+                }
+            }
+        }
+
+    // Set copy support
+    if( createObjectSupported )
+        {
+        aTarget.SetCopyCapability( ETrue );
+        }
+
+    // Set volume support
+    if( getVolumeSupported &&
+        setVolumeSupported )
+        {
+        aTarget.SetVolumeCapability( ETrue );
+        }
+
+    // Set mute support
+    if( getMuteSupported &&
+        setMuteSupported )
+        {
+        aTarget.SetMuteCapability( ETrue );
+        }
+        
+     }
+
+// --------------------------------------------------------------------------
+// CUPnPDeviceRepository::SelectDeviceIconL
+// See upnpdevicerepository.h
+// --------------------------------------------------------------------------
+void CUPnPDeviceRepository::SelectDeviceIconL( CUpnpDevice& aSource,
+    CUpnpAVDeviceExtended& aTarget )
+    {
+    // Icon selection rules:
+    // 1. Select any if none selected
+    // 2. Select the most colorful
+    // 3. Select greater until preferred size reached
+    // 4. Select the closest greater size after preferred size has passed
+    TPtrC8 deviceName( aTarget.FriendlyName() );
+    __LOG8_1( "CUPnPDeviceRepository::SelectDeviceIconL - Device: %S", &deviceName );
+    RPointerArray< CUpnpIcon >& icons( aSource.Icons() );
+    TInt iconCount( icons.Count() );
+    CUpnpIcon* selectedIcon = NULL;
+    TInt selectedDepth( 0 );
+    TInt selectedWd( 0 );
+    TInt selectedHd( 0 );
+    TInt selectedWhdSquare( 0 );
+    for ( TInt i( 0 ); i < iconCount; ++i )
+        {
+        CUpnpIcon* icon = icons[ i ];
+        TPtrC8 iconMimeType( icon->MimeType() );
+        __LOG8_1( "CUPnPDeviceRepository::SelectDeviceIconL - Found: %S", &iconMimeType );
+        __LOG3( "CUPnPDeviceRepository::SelectDeviceIconL - Width: %d Height: %d Depth: %d",
+                icon->Width(), icon->Height(), icon->Depth() );
+        if ( iconMimeType.FindF( KJpg ) != KErrNotFound ||
+             iconMimeType.FindF( KJpeg ) != KErrNotFound ||
+             iconMimeType.FindF( KPng ) != KErrNotFound )
+            {
+            TInt depth( icon->Depth() );
+            TInt wd( icon->Width() - KPreferredIconSize ); // Width diff to preferred size
+            TInt hd( icon->Height() - KPreferredIconSize ); // Height diff to preferred size
+            TInt whdSquare( wd * wd + hd * hd ); // Diffs combined
+            if ( !selectedIcon || // Rule 1
+                 ( depth >= selectedDepth && // Rule 2
+                   ( ( selectedWd < 0 && selectedWd < 0 && ( wd > selectedWd || hd > selectedHd ) ) || // Rule 3
+                     ( whdSquare < selectedWhdSquare && ( wd >= 0 || hd >= 0 ) ) ) // Rule 4
+                   )
+                 )
+                {
+                selectedIcon = icon;
+                selectedDepth = depth;
+                selectedWd = wd;
+                selectedHd = hd;
+                selectedWhdSquare = whdSquare;
+                }
+            }
+        }
+    if ( selectedIcon )
+        {
+        TPtrC8 iconMimeType( selectedIcon->MimeType() );
+        __LOG8_1( "CUPnPDeviceRepository::SelectDeviceIconL - Selected: %S", &iconMimeType );
+        __LOG3( "CUPnPDeviceRepository::SelectDeviceIconL - Width: %d Height: %d Depth: %d",
+                selectedIcon->Width(), selectedIcon->Height(), selectedIcon->Depth() );
+        aTarget.SetIconUrlL( aSource.Address(), aSource.UrlBase(), selectedIcon->Url() );
+        }
+    else
+        {
+        __LOG( "CUPnPDeviceRepository::SelectDeviceIconL - None selected" );
+        }
+    }
+
+// end of file