upnp/upnpstack/messagehandler/src/upnpmessagehandlerengine.cpp
changeset 0 f5a58ecadc66
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/upnp/upnpstack/messagehandler/src/upnpmessagehandlerengine.cpp	Tue Feb 02 01:12:20 2010 +0200
@@ -0,0 +1,519 @@
+/** @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:  Message handler engine
+ *
+ */
+
+// INCLUDE FILES
+#include <commdb.h>
+#include <commdbconnpref.h>
+#include "upnpcons.h"
+#include "upnpmessagehandlerengine.h"
+#include "upnpssdpserver.h"
+
+#ifdef RD_UPNP_REMOTE_ACCESS
+#include "upnpipfiltering.h"
+#include "upnpipfilteringdnsquery.h"
+#endif
+
+#include "upnpssdphandlerup.h"
+#include "upnpssdphandlerbase.h"
+#include "upnpssdphandlerdown.h"
+#include "upnpconnectionmanagerproxy.h"
+
+#define KLogFile _L("UpnpMessageHandler.txt")
+#include "upnpcustomlog.h"
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+// -----------------------------------------------------------------------------
+// CUpnpMessageHandlerEngine::NewLC
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CUpnpMessageHandlerEngine* CUpnpMessageHandlerEngine::NewL(
+    MMessageHandlerEngineObserver& aObserver )
+    {
+    // call the default constructor
+    CUpnpMessageHandlerEngine* self = new (ELeave) CUpnpMessageHandlerEngine( aObserver );
+
+    // call the default L constructor when in cleanup stack
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+
+    // returns new instance
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpMessageHandlerEngine::CUpnpMessageHandlerEngine
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CUpnpMessageHandlerEngine::CUpnpMessageHandlerEngine(
+    MMessageHandlerEngineObserver& aObserver ) :
+    iObserver(aObserver)
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpMessageHandlerEngine::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CUpnpMessageHandlerEngine::ConstructL()
+    {
+    LOG_FUNC_NAME;
+
+    // create a socket server connection
+    User::LeaveIfError( iSocketServ.Connect() );
+
+    CreateSessionIdPropertyL();
+
+    iSsdpHandlerUp = CUpnpSsdpHandlerUp::NewL( *this );
+    iSsdpHandlerDown = CUpnpSsdpHandlerDown::NewL( *this );
+    iCurrentSsdpHandler = iSsdpHandlerUp;
+
+    // device library stores information about remote and local devices
+    iDeviceLibrary = CUpnpDeviceLibrary::NewL( *this, 0 );
+
+    iConnectionManagerProxy = CUpnpConnectionManagerProxy::NewL( iSocketServ );
+    iConnectionManagerProxy->SubscribeForNetworkEventsL( this );
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpMessageHandlerEngine::CreateSessionIdPropertyL
+// Create session id property and signal id semaphore
+// -----------------------------------------------------------------------------
+//
+void CUpnpMessageHandlerEngine::CreateSessionIdPropertyL()
+    {
+    // create RProperty used as session id counter
+    TInt err = RProperty::Define( KUPnPUtilsCat, EUPnPUtilsCounter,
+        RProperty::EInt );
+    if ( err != KErrAlreadyExists )
+        {
+        User::LeaveIfError( err );
+        }
+
+    // there are four global widely-used semaphores in the system
+    // first two semaphores are for getting a running session id
+    // first semaphore is an access semaphore
+    // if it's signaled, we can have access to id semaphore
+    // id semaphore holds the current session id
+    //
+    // the second place where these semaphores are used is CUpnpHttpMessage::NewSessionIdL()
+    // 
+    // basically, we want to tell the CUpnpHttpMessage class that the
+    // EUPnPUtilsCounter RProperty is defined and ready to use
+
+    TInt result =
+            iAccessSemaphore.OpenGlobal( KSessionIdAccessSemaphoreName() );
+    if ( result == KErrNotFound )
+        {
+        result = iAccessSemaphore.CreateGlobal(
+            KSessionIdAccessSemaphoreName(), 0 );
+            
+        if ( result != KErrNone )
+            {
+            LOGS( "MESSAGEHANDLER *** Session id access semaphore creation failed" );
+            }
+        }
+    else if ( result != KErrNone )
+        {
+        LOGS( "MESSAGEHANDLER *** Session id access semaphore creation failed" );
+        }
+    User::LeaveIfError( result );
+
+    iAccessSemaphore.Signal();
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpMessageHandlerEngine::~CUpnpMessageHandlerEngine
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CUpnpMessageHandlerEngine::~CUpnpMessageHandlerEngine()
+    {
+    __ASSERT_DEBUG( iCurrentSsdpHandler == iSsdpHandlerUp
+            || iCurrentSsdpHandler == iSsdpHandlerDown,
+            User::Panic( KMessageHandler, EMessageHandlerBadState ) );
+    delete iDeviceLibrary;
+
+    delete iSsdpHandlerUp;
+    delete iSsdpHandlerDown;
+
+    delete iConnectionManagerProxy;
+
+#ifdef RD_UPNP_REMOTE_ACCESS    
+    /*************   IPFiltering    *****************/
+    delete iIPFilterRepository;
+    /************************************************/
+#endif
+
+    // close socket server connection
+    iSocketServ.Close();
+    iAccessSemaphore.Close();
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpMessageHandlerEngine::AdvertiseDeviceL
+// Advertise device
+// -----------------------------------------------------------------------------
+//
+void CUpnpMessageHandlerEngine::AdvertiseDeviceL( TInt aLive,
+    CUpnpDeviceLibraryElement& aElement )
+    {
+    iCurrentSsdpHandler->AdvertiseDeviceL( aLive, aElement );
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpMessageHandlerEngine::DeviceListChangedL
+// Inform observer that device list changed.
+// -----------------------------------------------------------------------------
+//
+void CUpnpMessageHandlerEngine::DeviceListChangedL()
+    {
+    LOG_FUNC_NAME;
+
+    //Check waiting
+    if ( iCurrentSsdpHandler == iSsdpHandlerUp )
+        {        
+        iObserver.DeviceListUpdateL();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpMessageHandlerEngine::DeviceList
+// Get device list.
+// -----------------------------------------------------------------------------
+//
+RPointerArray<CUpnpDeviceLibraryElement>& CUpnpMessageHandlerEngine::DeviceList()
+    {
+    LOG_FUNC_NAME;
+    // return device list
+    return iDeviceLibrary->DeviceList();
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpMessageHandlerEngine::AddLocalDeviceL
+// Add local device to device library.
+// -----------------------------------------------------------------------------
+//
+TInt CUpnpMessageHandlerEngine::AddLocalDeviceL(
+    TUpnpAddLocalDevice &aDevice, TDesC8& aBuffer )
+    {
+    LOG_FUNC_NAME;
+    
+    iDeviceLibrary->AddInfoL( &aDevice, aBuffer, iConnectionManagerProxy->LocalAddress() );
+
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpMessageHandlerEngine::AddLocalControlPointL
+// -----------------------------------------------------------------------------
+//
+TInt CUpnpMessageHandlerEngine::AddLocalControlPoint()
+    {
+    return iSsdpHandlerUp->AddLocalControlPoint();
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpMessageHandlerEngine::RemoveLocalControlPointL
+// -----------------------------------------------------------------------------
+//
+TInt CUpnpMessageHandlerEngine::RemoveLocalControlPoint()
+    {
+    return iSsdpHandlerUp->RemoveLocalControlPoint();
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpMessageHandlerEngine::StopFilteringDeviceL
+// -----------------------------------------------------------------------------
+//
+void CUpnpMessageHandlerEngine::StopFilteringDeviceL( const TDesC8& aUuid )
+    {
+    iDeviceLibrary->StopFilteringDeviceL( aUuid );
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpMessageHandlerEngine::DeviceLibrary
+// Get device library.
+// -----------------------------------------------------------------------------
+//
+CUpnpDeviceLibrary* CUpnpMessageHandlerEngine::DeviceLibrary()
+    {
+    LOG_FUNC_NAME;
+    return iDeviceLibrary;
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpMessageHandlerEngine::SsdpEventL
+// Callback function for received ssdp messages.
+// -----------------------------------------------------------------------------
+//
+void CUpnpMessageHandlerEngine::SsdpEventL( CUpnpSsdpMessage *aMessage )
+    {
+    LOG_FUNC_NAME;
+
+    // ignore messages with M-SEARCH there are serverd by SSDP Server internally
+    if ( aMessage->IsSsdpMSearch() )
+        {
+        return;
+        }
+    // forward message to device library
+    iDeviceLibrary->AddInfoL( aMessage );
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpMessageHandlerEngine::SsdpSearchL
+// Do ssdp searches.
+// -----------------------------------------------------------------------------
+//
+void CUpnpMessageHandlerEngine::SsdpSearchL( TDesC8& aSearchString,
+    TDesC8& aMX )
+    {
+    LOG_FUNC_NAME;
+    iCurrentSsdpHandler->SsdpSearchL( aSearchString, aMX );
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpMessageHandlerEngine::ActiveIap
+// Returns the iap id (which is got in function above).
+// -----------------------------------------------------------------------------
+//
+TInt CUpnpMessageHandlerEngine::ActiveIap() const
+    {
+    LOG_FUNC_NAME;
+    return iConnectionManagerProxy->ActiveIap();
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpMessageHandlerEngine::RemoveLocalDevice
+// Removes local device from device library.
+// -----------------------------------------------------------------------------
+//
+void CUpnpMessageHandlerEngine::RemoveLocalDeviceL( const TDesC8 &aUuid,
+    TBool aSilent )
+    {
+    LOG_FUNC_NAME;
+
+    // forward the request to device library
+    if ( iCurrentSsdpHandler == iSsdpHandlerUp)
+        {
+        if ( !aSilent )
+            {
+            iDeviceLibrary->RemoveL( aUuid );
+            }
+        else
+            {
+            iDeviceLibrary->RemoveSilentL( aUuid );
+            }
+        }
+
+    LOGS( "CUpnpMessageHandlerEngine::RemoveLocalDevice passed");
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpMessageHandlerEngine::StartSsdp
+// Start SSPD.
+// -----------------------------------------------------------------------------
+//
+TInt CUpnpMessageHandlerEngine::StartSsdpL()
+    {
+    LOG_FUNC_NAME;
+    if ( !iCurrentSsdpHandler->IsStarted() )
+        {
+        LOGS( "MESSAGEHANDLER *** Connecting to same access point...");        
+
+        iCurrentSsdpHandler->StartL( iSocketServ );
+
+#ifdef RD_UPNP_REMOTE_ACCESS    
+        /**********IPFiltering*******************/
+        iIPFilterRepository = CUpnpIPFiltering::NewL( iSocketServ,
+                ActiveIap(),
+                iObserver );
+        /****************************************/
+#endif
+
+        return KErrNone;
+        }
+    else
+        {
+        // Ensure all two servers are started
+        iCurrentSsdpHandler->StartL( iSocketServ );
+        return KErrNone;
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CUpnpMessageHandlerEngine::InterfaceDown
+// -----------------------------------------------------------------------------
+//
+void CUpnpMessageHandlerEngine::InterfaceDown()
+    {
+    LOG_FUNC_NAME;
+       
+    iSsdpHandlerUp->Stop();
+    iCurrentSsdpHandler = iSsdpHandlerDown;
+    }
+
+#ifdef RD_UPNP_REMOTE_ACCESS
+// -----------------------------------------------------------------------------
+// CUpnpServiceInfo::AddAddressL
+// -----------------------------------------------------------------------------
+//
+void CUpnpMessageHandlerEngine::AddAddressL( const TInetAddr& aAddress )
+    {
+    User::LeaveIfError( iIPFilterRepository->AddAddressL( aAddress ) );
+    iObserver.IPListChange();
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpServiceInfo::AddAddressL
+// -----------------------------------------------------------------------------
+//
+void CUpnpMessageHandlerEngine::AddAddressL( const RMessage2& aMessage,
+        const TDesC8& aRemoteName )
+    {
+    CUpnpIPFilteringDNSQuery* query = CUpnpIPFilteringDNSQuery::NewLC( aMessage,
+            aRemoteName );
+    iIPFilterRepository->AddAddressL( query );
+    CleanupStack::Pop( query );
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpServiceInfo::RemoveAddressL
+// -----------------------------------------------------------------------------
+//
+void CUpnpMessageHandlerEngine::RemoveAddressL( const TInetAddr& aAddress )
+    {
+    if ( iIPFilterRepository->RemoveAddressL( aAddress ) >=0 )
+        {
+        iObserver.IPListChange();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpServiceInfo::RemoveAddressL
+// -----------------------------------------------------------------------------
+//
+void CUpnpMessageHandlerEngine::RemoveAddressL( const RMessage2& aMessage,
+        const TDesC8& aRemoteName )
+    {
+    CUpnpIPFilteringDNSQuery* query = CUpnpIPFilteringDNSQuery::NewLC( aMessage,
+            aRemoteName );
+    iIPFilterRepository->RemoveAddressL( query );
+    CleanupStack::Pop( query );
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpServiceInfo::RemoveAll
+// -----------------------------------------------------------------------------
+//
+void CUpnpMessageHandlerEngine::RemoveAll()
+    {
+    if ( iIPFilterRepository->RemoveAll() >=0 )
+        {
+        iObserver.IPListChange();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpServiceInfo::IsIPAllowed
+// -----------------------------------------------------------------------------
+//
+TBool CUpnpMessageHandlerEngine::IsIPAllowed( const TInetAddr& aAddress ) const
+    {
+    return iIPFilterRepository->IsAllowed( aAddress );
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpServiceInfo::IPFilteringStatus
+// -----------------------------------------------------------------------------
+//
+void CUpnpMessageHandlerEngine::IPFilteringStatus( TInt& aListSize ) const
+    {
+    aListSize = iIPFilterRepository->GetIPFilterList().Size();
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpServiceInfo::GetIPFilterList
+// -----------------------------------------------------------------------------
+//
+const TDesC8& CUpnpMessageHandlerEngine::GetIPFilterList()
+    {
+    return iIPFilterRepository->GetIPFilterList();
+    }
+#endif
+
+// -----------------------------------------------------------------------------
+// CUpnpMessageHandlerEngine::NetworkEventWlanLost
+// -----------------------------------------------------------------------------
+//
+void CUpnpMessageHandlerEngine::NetworkEvent( CUpnpNetworkEventBase* aEvent )
+    {
+    LOG_FUNC_NAME;
+
+    if ( aEvent->SubscriberError() < KErrNone && aEvent->Type() == EUnknownEvent )
+        {
+        LOGS( "MESSAGEHANDLER *** NetworkEvent error" );
+        return;
+        }
+
+    switch ( aEvent->Type() )
+        {
+        case EWlanLostEvent:
+            {
+            InterfaceDown();
+  
+            TDblQueIter<CSession2>& sessionIter = iObserver.Sessions();
+        
+            sessionIter.SetToFirst();
+            CUpnpMessageHandlerSession *session = 
+                    reinterpret_cast<CUpnpMessageHandlerSession*>( sessionIter++ );
+            while ( session )
+                {
+                session->CancelPendingRequests();
+                session = reinterpret_cast<CUpnpMessageHandlerSession*>( sessionIter++ );
+                }
+            }
+            break;
+
+        case EAddressChangeEvent:
+            {
+            CUpnpNetworkEventAddressChange* networkEvent = 
+                                static_cast< CUpnpNetworkEventAddressChange* >( aEvent );
+  
+            TInetAddr addr = networkEvent->Address();
+
+            TRAPD( error, iCurrentSsdpHandler->AddressChangeL( addr ) );
+            TRAP( error, iDeviceLibrary->RemoveAllDevicesL() );
+
+            if ( error )
+                {
+                // only case this should happen
+                ASSERT( error == KErrNoMemory );
+                }
+            }
+            break;
+        }
+    }
+
+// End of File