diff -r 000000000000 -r f5a58ecadc66 servicediscoveryandcontrol/pnp/test/upnp/Server/Flow/inc/httpudpflow.h --- /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 +#include +#include +#include +#include +#include +#include + +#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