servicediscoveryandcontrol/pnp/test/upnp/Server/Flow/inc/httpudpflow.h
changeset 0 f5a58ecadc66
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servicediscoveryandcontrol/pnp/test/upnp/Server/Flow/inc/httpudpflow.h	Tue Feb 02 01:12:20 2010 +0200
@@ -0,0 +1,310 @@
+// 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:
+// @file
+// @internalComponent
+// 
+//
+
+#ifndef __HTTPUDPFLOW_H_
+#define __HTTPUDPFLOW_H_
+
+//System Includes
+#include <comms-infras/ss_subconnflow.h>
+#include <comms-infras/ss_flowbinders.h>
+#include <comms-infras/ss_protflow.h>
+#include<in_sock.h>
+#include<es_sock.h>
+#include <rmemchunk.h>
+#include <rmemcell.h>
+
+#include "upnpflowbase.h"
+#include "rsockethandler.h"
+#include "csocketopener.h"
+#include "cupnpresponseparser.h"
+#include "cupnprequestcomposer.h"
+#include "cupnpresponsecomposer.h"
+#include "upnp_cf_msgs.h"
+#include "upnpctrlscprstates.h"
+#include "upnpstatemachine.h"
+#include "cupnptimer.h"
+
+NONSHARABLE_CLASS(CSearchTarget) : public CBase
+	{
+	public:
+
+	CSearchTarget ( Messages::TNodeCtxId& aChannelId )
+	: iOriginator ( aChannelId )
+	{
+	}
+
+	~CSearchTarget ()
+		{
+		iSearchTarget.Close ();
+		}
+
+	void AddTargetL ( RMemChunk& aSt )
+		{
+		iSearchTarget.CreateMaxL(aSt.Length());
+		aSt.CopyOut(iSearchTarget);
+		aSt.Free();
+		}
+
+	TInt Match ( const TDesC8& aSt ) const
+		{
+		_LIT8 ( KSsdpAll, "ssdp:all" );
+		
+		if ( iSearchTarget.CompareF ( KSsdpAll ) == 0 || aSt.CompareF ( KSsdpAll ) == 0 )
+			{
+				return ETrue;
+			}
+		
+		TInt requestedUriIndex = 0;
+		TInt registeredUriIndex = 0;
+		
+		TInt registeredVersion = UPnPStateMachine::CUPnPUtils::ExtractVersionNumber ( iSearchTarget, registeredUriIndex );
+		TInt requestedVersion = UPnPStateMachine::CUPnPUtils::ExtractVersionNumber ( aSt, requestedUriIndex );
+		
+		TPtrC8 registeredUri = iSearchTarget.Left(registeredUriIndex - 1);
+		TPtrC8 requestedUri = aSt.Left(requestedUriIndex - 1);
+		
+		if ( (registeredUri.CompareF(requestedUri) == 0) && (requestedVersion <= registeredVersion))
+			{
+				return ETrue;
+			}
+		return KErrNotFound;
+		}
+
+	const Messages::TNodeCtxId& Originator () const
+		{
+		return iOriginator;
+		}
+	const TDesC8& SearchTarget() const
+		{
+		return iSearchTarget;
+		}
+	private:
+	RBuf8					iSearchTarget;
+	Messages::TNodeCtxId	iOriginator;
+	};
+
+typedef RArray < CSearchTarget* > CSearchTargetArray;
+class CUPnPProtocolIntfBase;
+
+NONSHARABLE_CLASS ( CSendElement ) : public CBase
+	{
+	public:
+	enum TSendType
+		{
+		EMSearchRequest =0,
+		ENotifyAliveRequest,
+		ENotifyByeRequest,
+		EMSearchResponse
+		};
+	CSendElement ( TSendType aType, CMessage& aMessage, const TAppProtAddr& aAddr )
+	: iMessage ( &aMessage ),
+	iType ( aType )
+	{
+	iSockAddr.SetAddress ( aAddr.iAddr );
+	iSockAddr.SetPort ( aAddr.iPort );
+	}
+
+	~CSendElement ()
+	{
+	delete iMessage;
+	}
+
+	CMessage* Message ()
+	{
+	return iMessage;
+	}
+	TSendType Type () const
+	{
+	return iType;
+	}
+
+
+	public:
+	CMessage* 	iMessage;
+	TSendType 	iType;
+	TInetAddr	iSockAddr;
+	};
+
+
+typedef RArray < CSendElement* > CSendElements;
+
+NONSHARABLE_CLASS ( CHttpUdpFlow ) : public CUPnPFlowBase,
+									 public MSocketHandlerObserver,
+									 public MComposerObserver,
+						 			 public MParserObserver,
+						 			 public MUPnPTimerObserver
+	{
+	friend class CUPnPFlowFactory;
+
+	public:
+	static CHttpUdpFlow* NewL ( CSubConnectionFlowFactoryBase& aFactory,
+								CUPnPProtocolIntfBase* aProtocolIntf,
+						  		const Messages::TNodeId& aSubConnId );
+	~CHttpUdpFlow ();
+
+	private:
+
+	CHttpUdpFlow ( CSubConnectionFlowFactoryBase& aFactory,
+					CUPnPProtocolIntfBase* aProtocolIntf,
+					const TNodeId& aSubConnId );
+
+	void ConstructL ();
+
+	protected:
+	// From CSubConnectionFlowBase
+	virtual void ReceivedL ( const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage );
+
+
+	// From MSocketHandlerObserver
+	virtual void OpenComplete ( RInternalSocket& aSocket );
+	inline virtual void ConnectComplete ();
+	inline virtual void AcceptComplete ( RInternalSocket& aSocket );
+	inline virtual void SendComplete ( TInt aLength );
+	virtual void SendToComplete ( TInt aLength );
+	inline virtual void RecvComplete ( RMBufChain& aData );
+	virtual void RecvFromComplete ( RMBufChain& aData, const TSockAddr& aAddr );
+//	virtual void IoctlComplete ();
+	inline virtual void Error ( TOperation aOperation, TInt aError  );
+
+	// From MComposerObserver
+	virtual void MessageDataReadyL ( RBuf8& aData );
+	virtual void ComposingConcluded ();
+	virtual void ComposerError ( TInt aError );
+
+	// From MUPnPTimerObserver
+	virtual void TimeOut ();
+	
+	// From MParserObserver
+	virtual void GotHeaders ();
+	inline virtual void GotBodyData ();
+	inline virtual void DataParsed();
+	virtual void ParsingComplete ( RMemChunk& aExcessData );
+	virtual void ParserError ( TInt aError );
+
+	// ------------------------------------
+	// The below functions should be moved to a common class. There are some in
+	// HTTP server/flow as well
+	TInt GetHeaderValue ( const CResponse& aResponse, TInt aFieldIndex, THTTPHdrVal& aFieldVal, const TStringTable& aTable );
+	TInt GetParamValue ( const CResponse& aResponse, TInt aFieldIndex, TInt aParamIndex, THTTPHdrVal& aParamVal, const TStringTable& aTable );
+	TInt IsHeaderPresent ( const CResponse& aResponse, TInt aFieldIndex, const TStringTable& aTable );
+	TInt IsValidCacheControlHeader ( const CResponse& aResponse );
+	void SetHeaderValueL ( RHTTPHeaders& aHdr, TInt aFieldIndex, const TDesC8& aFieldVal, const TStringTable& aTable );
+	void SetMaxAgeHeaderValueL ( TInt aMaxAgeVal, RHTTPHeaders aHeaders );
+	TBool IsContentLengthZero ( const CResponse& aResponse );
+
+	// ------------------------------------
+
+	TInt ValidateSearchResponse ();
+	void StartRecv ();
+	void NotifyClientsL ();
+	void ReadResponseValues ( TInt& aMaxAge, RStringF& aLocation, RStringF& aUsn, RStringF& aST );
+	void HandleSearchRequestL ( TNodeCtxId aChannelId, TUpnpMessage::TUPnPSearchRequest& aMessage );
+	void HandleStopSearch ( TNodeCtxId aChannelId );
+
+	void HandleSearchResponseL ( TUpnpMessage::TUPnPSearchResponse& aMessage );
+	void HandlePublishAliveRequestL ( TUpnpMessage::TUPnPPublishAliveRequest& aMessage );
+	void HandlePublishByeRequestL ( TUpnpMessage::TUPnPPublishByeRequest& aMessage );
+	CRequest& CreatePublishRequestLC ();
+
+	void SendIfOneElement ();
+	void HandleSendElement ();
+	void IncrementSendCount();
+	void StartSendTimer();
+	inline TInt IsMSearchOrAliveRequest(); 
+	
+	void CreateSendTimerL();
+	void CreateSocketL ();
+	CSendElement::TSendType RemoveFirstSendElement ();
+
+	TInt FindSearchTarget ( TNodeCtxId& aId );
+
+	TBool IsSocketCreated () const
+		{
+		return iSocketCreated;
+		}
+private:
+	RInternalSocket			iSocket;
+	RSocketHandler			iSocketHandler;
+	CSocketOpener* 			iSocketOpener;
+	CSearchTargetArray		iSearchTargetArray;
+	CUpnpResponseParser* 	iResponseParser;
+	CUpnpRequestComposer* 	iRequestComposer;
+	CUpnpResponseComposer* 	iResponseComposer;
+
+	CHeaderCodec*			iCodec;
+	CResponse*				iUPnPResponse; // Used for parsing the search response
+	CSendElements			iSendElements;
+	TBool					iSocketCreated;
+	
+	RMBufChain				iBackupData;
+	TInt 					iSendCount;
+
+	TNodeCtxId				iLastLeavingClient;
+	TBool					iIsLeaving;
+	TBool					iSendFlag;
+	TBool					iIsComposeCompleted;
+	
+	RStringPool				iStringPool;
+	
+	CUPnPTimer*			    iSendTimer;
+	
+	};
+
+
+void CHttpUdpFlow::ConnectComplete ()
+	{
+	// We don't handle this
+	}
+
+void CHttpUdpFlow::AcceptComplete ( RInternalSocket& /* aSocket */ )
+	{
+	// We don't handle this
+	}
+
+void CHttpUdpFlow::SendComplete ( TInt /* aLength */ )
+	{
+	}
+
+void CHttpUdpFlow::RecvComplete ( RMBufChain& /* aData */ )
+	{
+	// We don't handle this
+	}
+
+void CHttpUdpFlow::Error ( TOperation /*aOperation*/, TInt /*aError*/  )
+	{
+
+	}
+
+void CHttpUdpFlow::GotBodyData ()
+	{
+	ASSERT (0);
+	}
+
+void CHttpUdpFlow::DataParsed()
+	{
+	// We shouldn't come here. Corrupt message
+	StartRecv ();
+	}
+
+TInt CHttpUdpFlow::IsMSearchOrAliveRequest()
+	{
+	return ((iSendElements[0]->iType == CSendElement::EMSearchRequest) || (iSendElements[0]->iType == CSendElement::ENotifyAliveRequest));
+	}
+
+
+#endif // __HTTPUDPFLOW_H