--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/servicediscoveryandcontrol/pnp/test/upnp/Server/ServicePoint/src/upnpservicedeftscprstates.cpp Tue Feb 02 01:12:20 2010 +0200
@@ -0,0 +1,362 @@
+// Copyright (c) 2008-2009 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:
+//
+
+//System Includes
+#include <comms-infras/ss_log.h>
+#include <comms-infras/ss_logext.h>
+
+#include <http/thttptable.h>
+#include <inetprottextutils.h>
+#include <upnpdescriptionschema.h>
+#include <rmemchunk.h>
+#include <rmemcell.h>
+//Local Includes
+#include "upnpservicedeftscprstates.h"
+#include "upnp_cf_msgs.h"
+#include "upnpstatemachine.h"
+#include "upnpserverconstants.h"
+#include "upnplog.h"
+using namespace UPnPServiceDefaultStates;
+using namespace ESock;
+
+
+//-=========================================================
+//
+//States
+//
+//-=========================================================
+
+//-=========================================================
+//
+//Transitions
+//
+//-=========================================================
+DEFINE_SMELEMENT ( TStoreUdpServer, NetStateMachine::MStateTransition, TContext )
+void TStoreUdpServer::DoL ( )
+ {
+ TCFFactory::TPeerFoundOrCreated &msg = message_cast<TCFFactory::TPeerFoundOrCreated> ( iContext.iMessage );
+ iContext.Node ( ).SetUdpServerFlow ( msg.iNodeId );
+ }
+
+
+DEFINE_SMELEMENT ( TStoreUdpClient, NetStateMachine::MStateTransition, TContext )
+void TStoreUdpClient::DoL ( )
+ {
+ TCFFactory::TPeerFoundOrCreated &msg = message_cast<TCFFactory::TPeerFoundOrCreated> ( iContext.iMessage );
+ iContext.Node ( ).SetUdpClientFlow ( msg.iNodeId );
+ }
+
+DEFINE_SMELEMENT ( TBuildPublishAndRootDeviceInfo, NetStateMachine::MStateTransition, TContext )
+void TBuildPublishAndRootDeviceInfo::DoL ( )
+ {
+ if ( iContext.Node ( ).PublishInfo ( ) )
+ {
+ return;
+ }
+
+ TUpnpMessage::TRegisterRootDevice& msg = message_cast< TUpnpMessage::TRegisterRootDevice > ( iContext.iMessage );
+ CUPnPDevice* device = static_cast <CUPnPDevice*> ( msg.iPtr );
+
+ CStringPoolManager& stringPoolMgr = iContext.Node ().ConnectionProvider ().StringPoolManager ();
+ RStringPool& sp = stringPoolMgr.StringPool ( );
+ const TStringTable& upnpTable = stringPoolMgr.GetUPnPTable();
+ CUPnPPublishInfoElement* publishInfo = CUPnPPublishInfoElement::NewL ( );
+ CleanupStack::PushL ( publishInfo );
+
+ publishInfo->SetKeyL( iContext.Node ().ConnectionProvider ().RootDeviceLocation () );
+ publishInfo->SetSearchTargetL( KRootDevice ( ) ); //upnp:rootdevice
+ publishInfo->SetCacheControlL( KCacheControl );
+
+ const TDesC8& udnPtr = device->Property( sp.String ( UPNPDESCRIPTIONXMLTAGS::EUdn, upnpTable ) );
+ const TDesC8& deviceTypePtr = device->Property( sp.String(UPNPDESCRIPTIONXMLTAGS::EDeviceType,upnpTable ) );
+
+ publishInfo->SetUuidL ( udnPtr );
+
+ // Set Usn to udn + devicetype
+ TInt len = udnPtr.Length ( ) + KSeperator.iTypeLength + deviceTypePtr.Length ( );
+ RBuf8 tempBuf;
+ tempBuf.CreateMaxL ( len );
+ CleanupClosePushL ( tempBuf );
+
+ tempBuf.Copy ( udnPtr );
+ tempBuf.Append ( KSeperator ( ) );
+ tempBuf.Append ( deviceTypePtr );
+ publishInfo->SetUsnL( tempBuf );
+
+ iContext.Node ( ).SetPublishInfoL ( publishInfo );
+ // store deviceType in SCPr node for reference in M-Search Response Activity
+ iContext.Node ( ).SetRootDeviceUrnL ( deviceTypePtr );
+
+ CleanupStack::PopAndDestroy ( &tempBuf );
+ CleanupStack::Pop ( publishInfo );
+ }
+
+
+DEFINE_SMELEMENT ( TSendPublishRequest, NetStateMachine::MStateTransition, TContext )
+void TSendPublishRequest::DoL ( )
+ {
+ CUPnPPublishInfoElement* publishInfo = iContext.Node ( ).PublishInfo ( );
+
+ // Publish once for upnp:rootdevice::uuid:device-UUID
+ DoPublishL ( publishInfo->SearchTarget ( ), iContext.Node ( ).RootDeviceUsn ( ), publishInfo->CacheControl ( ) );
+
+ // Publish once for uuid:device-UUID
+ DoPublishL ( publishInfo->Uuid ( ), publishInfo->Uuid ( ), publishInfo->CacheControl ( ) );
+
+ // Publish once for uuid:device-UUID::urn:domain-name-device:deviceType:v
+ DoPublishL ( iContext.Node ( ).RootDeviceUrn ( ), publishInfo->Usn ( ), publishInfo->CacheControl ( ) );
+
+ iContext.Node ( ).SetRootDevicePublished ( ETrue );
+ }
+
+void TSendPublishRequest::DoPublishL ( const TDesC8& aSearchTarget, const TDesC8& aUsn, TInt aMaxAge )
+ {
+ RMemoryAllocator allocator = iContext.Node ( ).ConnectionProvider().MemoryAllocator();
+
+ RMemChunk locationBuf;
+ locationBuf.CreateL ( iContext.Node ().ConnectionProvider ().RootDeviceLocation (), allocator );
+
+ RMemChunk stBuf;
+ stBuf.CreateL ( aSearchTarget, allocator );
+ TCleanupItem item ( &UPnPStateMachine::CUPnPUtils::CleanupMBufChain, &stBuf );
+ CleanupStack::PushL ( item );
+
+ RMemChunk usnBuf;
+ usnBuf.CreateL ( aUsn, allocator );
+
+ TSsdpInfo ssdpInfo ( aMaxAge, locationBuf, usnBuf, stBuf );
+
+ TUpnpMessage::TUPnPPublishAliveRequest publishMsg ( ssdpInfo );
+ RClientInterface::OpenPostMessageClose ( iContext.NodeId (), iContext.Node ().UdpClientFlow (), publishMsg );
+
+ CleanupStack::Pop ( ); // item
+ }
+
+
+DEFINE_SMELEMENT ( TRegisterRootDeviceWithMuServer, NetStateMachine::MStateTransition, TContext )
+void TRegisterRootDeviceWithMuServer::DoL ( )
+ {
+ CUPnPPublishInfoElement* publishInfo = iContext.Node ( ).PublishInfo ( );
+
+ // Register once for upnp:rootdevice
+ RegisterForMSearchL ( publishInfo->SearchTarget ( ) );
+
+ // Register once for uuid:device-UUID
+ RegisterForMSearchL ( publishInfo->Uuid ( ) );
+
+ // Register once for uuid:device-UUID::urn:domain-name-device:deviceType:v
+ RegisterForMSearchL ( iContext.Node ( ).RootDeviceUrn ( ) );
+ }
+
+void TRegisterRootDeviceWithMuServer::RegisterForMSearchL ( const TDesC8& aSearchTarget )
+ {
+ RMemoryAllocator allocator(iContext.Node ( ).ConnectionProvider().MemoryManager());
+ RMemChunk stBuf;
+ stBuf.CreateL ( aSearchTarget, allocator );
+
+ TSsdpInfo ssdpInfo ( stBuf );
+
+ TUpnpMessage::TUPnPPublishRegistration msg ( ssdpInfo );
+ RClientInterface::OpenPostMessageClose ( TNodeCtxId ( MeshMachine::KActivityNull, iContext.NodeId () ), iContext.Node ().UdpServerFlow (), msg );
+ }
+
+
+DEFINE_SMELEMENT ( TStartMuClient, NetStateMachine::MStateTransition, TContext )
+void TStartMuClient::DoL ( )
+ {
+ iContext.iNodeActivity->PostRequestTo ( iContext.Node ().UdpClientFlow (), TCFDataClient::TStart ().CRef () );
+ }
+
+DEFINE_SMELEMENT ( TStartMuServer, NetStateMachine::MStateTransition, TContext )
+void TStartMuServer::DoL ( )
+ {
+ iContext.iNodeActivity->PostRequestTo ( iContext.Node ().UdpServerFlow (), TCFDataClient::TStart ().CRef () );
+ }
+
+DEFINE_SMELEMENT ( TSendRootDeviceRegistered, NetStateMachine::MStateTransition, TContext )
+void TSendRootDeviceRegistered::DoL ( )
+ {
+ TUpnpMessage::TRootDeviceRegistered msg ( iContext.iNodeActivity->Error( ) );
+ RClientInterface::OpenPostMessageClose ( iContext.NodeId (), iContext.Node ().ControlProvider ()->RecipientId (), msg );
+ }
+
+
+DEFINE_SMELEMENT ( TSendSearchResponse, NetStateMachine::MStateTransition, TContext )
+void TSendSearchResponse::DoL ( )
+ {
+ if ( !iContext.Node ( ).RootDevicePublished ( ) )
+ {
+ return;
+ }
+
+ TUpnpMessage::TUPnPSearchRequest& reqMsg = message_cast< TUpnpMessage::TUPnPSearchRequest > ( iContext.iMessage );
+
+ RMemCell* mBuf = reqMsg.iSsdpInfo.iSearchTarget.First ( );
+ TPtr8 stPtr ( mBuf->Ptr( ), mBuf->Length( ), mBuf->Length( ) );
+
+ CUPnPPublishInfoElement* publishInfo = iContext.Node ( ).PublishInfo ( );
+
+ if ( stPtr.CompareF ( publishInfo->SearchTarget ( ) ) == 0 )
+ {
+ // Search Response for upnp:rootdevice::uuid:device-UUID
+ SendSearchResponseL ( publishInfo->SearchTarget ( ), iContext.Node ( ).RootDeviceUsn ( ), publishInfo->CacheControl ( ) );
+ }
+ else if ( stPtr.CompareF ( publishInfo->Uuid ( ) ) == 0 )
+ {
+ // Search Response for uuid:device-UUID
+ SendSearchResponseL ( publishInfo->Uuid ( ), publishInfo->Uuid ( ), publishInfo->CacheControl ( ) );
+ }
+ else
+ {
+ // Search Response for uuid:device-UUID::urn:domain-name-device:deviceType:v
+ SendSearchResponseL ( stPtr, publishInfo->Usn ( ), publishInfo->CacheControl ( ) );
+ }
+ reqMsg.iSsdpInfo.iSearchTarget.Free ( );
+ }
+
+void TSendSearchResponse::SendSearchResponseL ( const TDesC8& aSearchTarget, const TDesC8& aUsn, TInt aMaxAge )
+ {
+ TUpnpMessage::TUPnPSearchRequest& reqMsg = message_cast< TUpnpMessage::TUPnPSearchRequest > ( iContext.iMessage );
+ TAppProtAddr remoteUnicastAddr = reqMsg.iSsdpInfo.iAddr;
+ RMemoryAllocator allocator = iContext.Node ( ).ConnectionProvider().MemoryAllocator();
+
+ RMemChunk locationBuf;
+ locationBuf.CreateL ( iContext.Node ().ConnectionProvider ().RootDeviceLocation (), allocator );
+ TCleanupItem item ( &UPnPStateMachine::CUPnPUtils::CleanupMBufChain, &locationBuf );
+ CleanupStack::PushL ( item );
+
+ RMemChunk stBuf;
+ stBuf.CreateL ( aSearchTarget, allocator );
+ TCleanupItem item1 ( &UPnPStateMachine::CUPnPUtils::CleanupMBufChain, &stBuf );
+ CleanupStack::PushL ( item1 );
+
+ RMemChunk usnBuf;
+ usnBuf.CreateL ( aUsn, allocator );
+
+ TSsdpInfo ssdpInfo ( aMaxAge,
+ locationBuf,
+ usnBuf,
+ stBuf,
+ remoteUnicastAddr );
+
+ TUpnpMessage::TUPnPSearchResponse msg ( ssdpInfo );
+ RClientInterface::OpenPostMessageClose ( iContext.NodeId (), iContext.Node ().UdpClientFlow (), msg );
+
+ CleanupStack::Pop ( ); // item
+ CleanupStack::Pop ( ); // item1
+ }
+
+
+DEFINE_SMELEMENT ( TProcessDataClientStop, NetStateMachine::MStateTransition, TContext )
+void TProcessDataClientStop::DoL ( )
+ {
+ CUPnPPublishInfoElement* publishInfo = iContext.Node ( ).PublishInfo ( );
+
+ if ( publishInfo && iContext.Node ( ).RootDevicePublished ( ) )
+ {
+ // for upnp:rootdevice::uuid:device-UUID
+ SendByeRequestL ( publishInfo->SearchTarget ( ), iContext.Node ( ).RootDeviceUsn ( ) );
+
+ // for uuid:device-UUID
+ SendByeRequestL ( publishInfo->Uuid ( ), publishInfo->Uuid ( ) );
+
+ // for uuid:device-UUID::urn:domain-name-device:deviceType:v
+ SendByeRequestL ( iContext.Node ( ).RootDeviceUrn ( ), publishInfo->Usn ( ) );
+
+ iContext.Node ( ).SetRootDevicePublished ( EFalse );
+ }
+
+ // StopDataClients
+ iContext.Node().PostToClients<TDefaultClientMatchPolicy> ( TNodeCtxId ( iContext.ActivityId (), iContext.NodeId () ),
+ TCFDataClient::TStop ( KErrNone ).CRef (), TClientType ( TCFClientType::EData, TCFClientType::EStarted ) );
+ iContext.iNodeActivity->SetPostedTo( TNodeId::NullId ( ) );
+
+ return;
+ }
+
+void TProcessDataClientStop::SendByeRequestL ( const TDesC8& aSearchTarget, const TDesC8& aUsn )
+ {
+ RMemoryAllocator allocator = iContext.Node ( ).ConnectionProvider().MemoryAllocator();
+
+ RMemChunk stBuf;
+ stBuf.CreateL ( aSearchTarget, allocator );
+ TCleanupItem item ( &UPnPStateMachine::CUPnPUtils::CleanupMBufChain, &stBuf );
+ CleanupStack::PushL ( item );
+
+ RMemChunk usnBuf;
+ usnBuf.CreateL ( aUsn, allocator );
+
+ TSsdpInfo ssdpInfo ( usnBuf, stBuf );
+ TUpnpMessage::TUPnPPublishByeRequest msg ( ssdpInfo );
+ RClientInterface::OpenPostMessageClose ( iContext.NodeId (), iContext.Node ().UdpClientFlow (), msg );
+
+ CleanupStack::Pop ( ); // item
+ }
+
+DEFINE_SMELEMENT ( TLeaveRequest, NetStateMachine::MStateTransition, TContext )
+void TLeaveRequest::DoL ( )
+ {
+ TUint ccCount = iContext.Node ().CountClients<TDefaultClientMatchPolicy> ( TClientType ( TCFClientType::ECtrl ) );
+
+ // -- If control client goes zero and the node is not having any pending activities
+ // then process the data client stop,
+ // mark the default SCPR node for deletion and close it.
+ if ( ccCount == 0 )
+ {
+ iContext.Node ( ).SetClosing ( );
+ }
+ }
+
+DEFINE_SMELEMENT ( TNoTagOrDataClientIdle, NetStateMachine::MStateFork, TContext )
+TInt TNoTagOrDataClientIdle::TransitionTag ( )
+ {
+ return iContext.Node ( ).IsClosing ( ) ? CoreNetStates::KDataClientIdle : MeshMachine::KNoTag;
+ }
+
+
+DEFINE_SMELEMENT ( TRequestOrIgnoreTag, NetStateMachine::MStateFork, TContext )
+TInt TRequestOrIgnoreTag::TransitionTag ( )
+ {
+ if ( iContext.Node ( ).IsClosing ( ) )
+ {
+ return CoreStates::KIgnore;
+ }
+
+ TUpnpMessage::TUPnPRequestInfo& requestInfoMsg = message_cast<TUpnpMessage::TUPnPRequestInfo> ( iContext.iMessage );
+ CTransaction* transaction = static_cast<CTransaction*> ( requestInfoMsg.iPtr );
+ const RStringF& header = transaction->Request( )->Handle( ).Method ( );
+
+ __ASSERT_DEBUG ( header == transaction->Request( )->StringPool ( ).StringF ( HTTP::EGET, THTTPTable::Table() ), User::Invariant () );
+
+ const TDesC8& uriPath = transaction->Request()->URI()->Uri().Extract ( EUriPath);
+ _LIT8 ( KRootPath, "/" );
+ if ( uriPath.Compare ( KRootPath ) == 0 )
+ {
+ return UPnPStateMachine::KDescribeRequest;
+ }
+ else
+ {
+ return UPnPStateMachine::KIconRequest;
+ }
+ }
+
+
+DEFINE_SMELEMENT ( TNoTagOrIgnoreTag, NetStateMachine::MStateFork, TContext )
+TInt TNoTagOrIgnoreTag::TransitionTag ( )
+ {
+ return iContext.Node ( ).IsClosing ( ) ? CoreStates::KIgnore : MeshMachine::KNoTag;
+ }
+
+