servicediscoveryandcontrol/pnp/test/upnp/Server/ControlPoint/src/upnpstatemachine.cpp
changeset 0 f5a58ecadc66
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servicediscoveryandcontrol/pnp/test/upnp/Server/ControlPoint/src/upnpstatemachine.cpp	Tue Feb 02 01:12:20 2010 +0200
@@ -0,0 +1,320 @@
+// 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 <ss_glob.h>
+#include <http/thttptable.h>
+#include <comms-infras/ss_log.h>
+#include <comms-infras/ss_logext.h>
+#include <upnp/tupnptable.h>
+
+#include <httperr.h>
+#include <inetprottextutils.h>
+#include <rmemchunk.h>
+
+//Local Includes
+#include "upnpctrlscprstates.h"
+#include "upnpstatemachine.h"
+
+#include "upnp_cf_msgs.h"
+#include "upnpctrlscpractivities.h"
+#include "upnpserverconstants.h"
+#include "upnplog.h"
+
+using namespace ESock;
+using namespace CorePanics;
+using namespace UPnPControlSCprStates;
+using namespace UPnPStateMachine;
+using namespace PRActivities;
+using namespace UPnPSearchStates;
+using namespace UPnPRegisterNotifyStates;
+using namespace CoreActivities;
+
+__FLOG_STMT(_LIT8(KComponent,"UPnPCtrlScprSts");)
+//===========================UPnP SCPR states and activities==========================   	   
+
+DEFINE_SMELEMENT ( TFindOrCreateUdpClientFlow, NetStateMachine::MStateTransition, UPnPStateMachine::TContext )	
+void TFindOrCreateUdpClientFlow::DoL ( )
+	{
+	THttpUdpFlowQuery flowQuery ( iContext.NodeId (), EHttpUdpFlow, iContext.Node ().BaseConnectionProvider ().MemoryManager() );
+	const TUid requestedUid = { CUPnPFlowFactory::iUid };	
+	TNodeId factoryContainer = SockManGlobals::Get( )->GetPlaneFC( TCFPlayerRole ( TCFPlayerRole::EDataPlane ) );
+		
+	iContext.iNodeActivity->PostRequestTo ( factoryContainer, TCFFactory::TFindOrCreatePeer ( TCFPlayerRole::EDataPlane, requestedUid, &flowQuery ).CRef () );
+	}
+
+DEFINE_SMELEMENT ( TFindOrCreateUdpServerFlow, NetStateMachine::MStateTransition, UPnPStateMachine::TContext )	
+void TFindOrCreateUdpServerFlow::DoL ( )
+	{	
+	THttpUdpFlowQuery flowQuery ( iContext.NodeId (), EHttpMUdpFlow );
+	const TUid requestedUid = { CUPnPFlowFactory::iUid };		
+	TNodeId factoryContainer = SockManGlobals::Get( )->GetPlaneFC( TCFPlayerRole ( TCFPlayerRole::EDataPlane ) );
+		
+	iContext.iNodeActivity->PostRequestTo ( factoryContainer, TCFFactory::TFindOrCreatePeer ( TCFPlayerRole::EDataPlane, requestedUid, &flowQuery ).CRef () );
+	}
+
+	
+DEFINE_SMELEMENT ( THandleControlChannelDataClientIdle, NetStateMachine::MStateTransition, UPnPStateMachine::TContext )
+void THandleControlChannelDataClientIdle::DoL ( )
+	{
+	//This transition may only be triggered by a peer message from a data client
+	ASSERT ( iContext.iPeer );
+	ASSERT ( iContext.iPeer->Type() == TCFClientType::EData );
+	
+   	iContext.iPeer->PostMessage( TNodeCtxId ( ( iContext.iNodeActivity )? iContext.iNodeActivity->ActivityId( ) : MeshMachine::KActivityNull, iContext.NodeId () ),
+   								 TEChild::TDestroy ().CRef () );
+   	iContext.iNode.RemoveClient ( iContext.iPeer->RecipientId() );
+    }	
+    
+DEFINE_SMELEMENT ( TStoreBindToOriginator, NetStateMachine::MStateTransition, UPnPStateMachine::TContext )
+void TStoreBindToOriginator::DoL ()
+	{
+	ABindingActivity* bindingActivity = reinterpret_cast<ABindingActivity*>(iContext.iNodeActivity->FetchExtInterface(ABindingActivity::KInterfaceId));
+    ASSERT(bindingActivity);
+    bindingActivity->StoreOriginator(iContext.iSender);
+	}
+	
+DEFINE_SMELEMENT ( TAwaitingSetParamRequest, NetStateMachine::MState, UPnPStateMachine::TContext )
+TBool TAwaitingSetParamRequest::Accept ( )
+	{
+	LOG(ESockLogExternal::Printf(KSubsysCtrlScprSts, KComponent, _L8("TAwaitingSetParamRequest::Accept")));
+	TUint16 senderActivityId = address_cast<TNodeCtxId> ( iContext.iSender ).NodeCtx ();
+#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+	if ( senderActivityId == ECFActivityParamRequest && 
+		iContext.iMessage.IsMessage<TCFScpr::TSetParamsRequest> () )
+#else
+	if ( senderActivityId == ECFActivityParamRequest && 
+		iContext.iMessage.IsMessage<TCFScpr::TParamsRequest> () )
+#endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW		
+		{
+		LOG(ESockLogExternal::Printf(KSubsysCtrlScprSts, KComponent, _L8("TAwaitingSetParamRequest::Accept - Message=TCFMessage::TSubConnParamsRequest")));
+		return ETrue;
+		}
+	return EFalse;
+	}	   	   	
+	
+DEFINE_SMELEMENT ( TStartServerFlow, NetStateMachine::MStateTransition, UPnPStateMachine::TContext )
+void TStartServerFlow::DoL ( )
+	{
+	TCFFactory::TPeerFoundOrCreated& msg = message_cast< TCFFactory::TPeerFoundOrCreated > ( iContext.iMessage );
+	iContext.iNodeActivity->PostRequestTo ( msg.iNodeId, TCFDataClient::TStart ().CRef () );
+	}
+
+		
+DEFINE_SMELEMENT ( TRequestLocalHost, NetStateMachine::MStateTransition, UPnPStateMachine::TContext )
+void TRequestLocalHost::DoL ( )
+	{
+	iContext.iNodeActivity->PostRequestTo( iContext.Node ().ControlProvider()->RecipientId(), TUpnpMessage::TRequestLocalHost ().CRef () );
+	}
+	
+DEFINE_SMELEMENT ( TSendIgnoreResponse, NetStateMachine::MStateTransition, UPnPStateMachine::TContext )	
+void TSendIgnoreResponse::DoL ( )
+	{
+	TUpnpMessage::TUPnPRequestInfo& requestMsg = message_cast< TUpnpMessage::TUPnPRequestInfo > ( iContext.iMessage );
+	
+	RClientInterface::OpenPostMessageClose ( iContext.NodeId (), iContext.iSender,
+		TUpnpMessage::TUPnPResponseInfo ( static_cast<CTransaction*> ( requestMsg.iPtr ),
+		HTTPStatus::EInternalServerError, NULL ).CRef () );
+	}
+	
+DEFINE_SMELEMENT ( TDiscardSearchRequestData, NetStateMachine::MStateTransition, UPnPStateMachine::TContext )
+void TDiscardSearchRequestData::DoL ( )
+	{
+	TUpnpMessage::TUPnPSearchRequest& reqMsg = message_cast< TUpnpMessage::TUPnPSearchRequest > ( iContext.iMessage );
+	reqMsg.iSsdpInfo.iSearchTarget.Free ( );
+	}
+
+
+DEFINE_SMELEMENT ( TDestroyDataClients, NetStateMachine::MStateTransition, UPnPStateMachine::TContext )
+void TDestroyDataClients::DoL ( )
+	{
+	//Send Destroy to data clients and remove client information
+	RNodeInterface* dc;
+	TClientIter<TDefaultClientMatchPolicy> iter =  iContext.iNode.GetClientIter<TDefaultClientMatchPolicy> ( TClientType ( TCFClientType::EData ) );
+	TUint dcCount = 0;
+	while ( ( dc = iter++ ) != NULL )
+		{
+		dc->PostMessage ( iContext.NodeId (), TEChild::TDestroy ().CRef () );
+		++dcCount;
+		}
+	
+	for ( TInt i = 0; i < dcCount; i++ )
+		{
+		RNodeInterface* dc =  iContext.iNode.GetFirstClient<TDefaultClientMatchPolicy> ( TClientType ( TCFClientType::EData ) );
+    	iContext.Node ( ).RemoveClient ( dc->RecipientId( ) );
+		}
+	}
+
+
+DEFINE_SMELEMENT ( TStopDataClients, NetStateMachine::MStateTransition, UPnPStateMachine::TContext )
+void TStopDataClients::DoL ( )
+	{
+	TClientIter<TDefaultClientMatchPolicy> iter = iContext.iNode.GetClientIter<TDefaultClientMatchPolicy> ( TClientType ( TCFClientType::EData ) );
+	RNodeInterface* dc;
+	while ( ( dc = iter++ ) != NULL )
+		{
+		if ( dc->Flags( ) != TClientType::ELeaving )
+			{
+			dc->PostMessage ( TNodeCtxId ( iContext.ActivityId (), iContext.NodeId () ), TCFDataClient::TStop ( KErrNone ).CRef () );
+			}
+		}	
+	iContext.iNodeActivity->SetPostedTo ( TNodeId::NullId ( ) );
+	}
+	
+DEFINE_SMELEMENT ( TAwaitingToStopDataClients, NetStateMachine::MState, UPnPStateMachine::TContext )
+TBool TAwaitingToStopDataClients::Accept ( )
+	{
+	if ( iContext.iMessage.IsMessage<TCFDataClient::TStopped>() )
+		{
+		RClientInterface::OpenPostMessageClose ( iContext.NodeId (), iContext.iSender, TEChild::TDestroy ().CRef () );
+		iContext.iNode.RemoveClient ( address_cast<TNodeId> ( iContext.iSender ) );
+		if ( iContext.iNode.CountClients<TDefaultClientMatchPolicy> ( TClientType ( TCFClientType::EData ) ) == 0 )
+			{
+			//Last one - accept
+			return ETrue;
+			}
+		return EFalse;
+		}
+   	return EFalse;
+	}
+
+
+DEFINE_SMELEMENT ( TRequestOrIgnoreTag, NetStateMachine::MStateFork, UPnPStateMachine::TContext )
+TInt TRequestOrIgnoreTag::TransitionTag ( )
+	{
+	TUpnpMessage::TUPnPRequestInfo& requestInfoMsg = message_cast<TUpnpMessage::TUPnPRequestInfo> ( iContext.iMessage );
+	CTransaction* transaction = static_cast<CTransaction*> ( requestInfoMsg.iPtr );
+	
+	CRequest* request = transaction->Request( );
+	RRequest rRequest = request->Handle( );
+	const RStringF& header =  rRequest.Method ( );
+	
+	if ( header == request->StringPool ( ).StringF ( UPnP::ENotify, TUPnPTable::Table() ) )
+		{		
+		CUPnPControlSubConnectionProvider& node = static_cast<CUPnPControlSubConnectionProvider&> ( iContext.Node ( ) );						
+		if ( node.IsClosing ( ) )
+			{
+			return CoreStates::KIgnore;
+			}
+		
+		return KNotifyRequest;
+		}
+	else
+		{
+		CUPnPServiceSubConnectionProvider& node1 = static_cast<CUPnPServiceSubConnectionProvider&> ( iContext.Node ( ) );
+		if ( node1.IsClosing ( ) )
+			{
+			return CoreStates::KIgnore;
+			}
+		else
+			{
+			if ( header == request->StringPool ( ).StringF ( HTTP::EGET, THTTPTable::Table() ) )
+				{
+				return KDescribeRequest;	
+				}
+			else if ( header == request->StringPool ( ).StringF ( UPnP::ESubscribe, TUPnPTable::Table() ) )
+				{
+				return KSubscribeRequest;
+				}
+			else if ( header == request->StringPool ( ).StringF ( UPnP::EUnsubscribe, TUPnPTable::Table() ) )
+				{
+				return KUnsubscribeRequest;
+				}
+			}
+		}
+	return MeshMachine::KNoTag;	
+	}
+	
+TInt CUPnPUtils::ExtractVersionNumber ( const TDesC8& aSearchTarget, TInt& aUriIndex )
+	{	
+	TLex8 parser ( aSearchTarget );
+	
+	TChar ch = ':';
+	// skip 4 KColon's so that u reach version number
+	for ( TInt i = 0; i < 4; i++ )
+		{			
+		while ( !parser.Eos ( ) && parser.Peek ( ) != ch )
+			parser.Inc ( );		
+		parser.Inc ( );
+		}		
+	parser.Mark();
+		
+	while ( !parser.Eos ( ) && parser.Peek ( ) != ch )
+		parser.Inc ( );
+	
+	aUriIndex = parser.MarkedOffset(); 
+	
+	TPtrC8 version = parser.MarkedToken ( );
+	
+	TInt versionNumber = 0;
+	InetProtTextUtils::ConvertDescriptorToInt ( version, versionNumber );
+	return versionNumber;
+	}
+
+void CUPnPUtils::CleanupMBufChain ( TAny* aAny )
+	{
+	RMemChunk* chain = ( RMemChunk* ) aAny;
+	chain->Free( );
+	}	
+
+void CUPnPUtils::FindAndSendIconDataL ( CTransaction* aTransaction, TInt& aStatus, RMemoryAllocator& aAllocator  )
+	{
+	HBufC* uriPath =  aTransaction->Request()->URI()->Uri().GetFileNameL ( EUriFileNamePath);
+	TPtr ptr ( uriPath->Des () );
+	TInt fileNameStart = ptr.LocateReverse ( TChar ('\\') ) + 1;
+	TInt fileNameLength = ptr.Length () - fileNameStart;
+	TPtrC filePtr = ptr.Mid ( fileNameStart, fileNameLength );
+	
+	RFs fs;
+	User::LeaveIfError ( fs.Connect () );
+    CleanupClosePushL ( fs );
+    
+	_LIT ( KIconResFileNamePath, "\\resource\\upnp\\icons\\" );
+	TFindFile fileFinder ( fs );
+	
+	CDir* dir= NULL;	
+	TInt ret = fileFinder.FindWildByDir ( filePtr, KIconResFileNamePath, dir );
+	if ( ret == KErrNone )
+		{
+		CleanupStack::PushL ( dir );
+				
+		RFile fileHandle;
+		fileHandle.Open ( fs, fileFinder.File (), EFileShareReadersOnly );
+		CleanupClosePushL ( fileHandle );
+		TInt fileSize = 0;
+		fileHandle.Size ( fileSize );
+
+		HBufC8* buf = HBufC8::NewLC ( fileSize );
+		TPtr8 fileData = buf->Des ();
+		
+		User::LeaveIfError ( fileHandle.Read ( fileData, fileSize ) );
+		
+		RMemChunk dataChian;
+		dataChian.CreateL ( fileData, aAllocator );
+		aTransaction->AddBodyPart ( dataChian );
+		aStatus = HTTPStatus::EOk;
+		
+		CleanupStack::PopAndDestroy ( 3 ); // buf, fileHandle , dir
+		}
+	else
+		{
+		aStatus = HTTPStatus::ENotFound;
+		}
+	
+	CleanupStack::PopAndDestroy ( &fs );
+	}
+
+