diff -r 000000000000 -r f5a58ecadc66 upnp/upnpstack/dlnawebserver/inc/upnptcpsession.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/upnp/upnpstack/dlnawebserver/inc/upnptcpsession.h Tue Feb 02 01:12:20 2010 +0200 @@ -0,0 +1,532 @@ +/** @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: Class that is derived by CUpnpHttpSession. Implements TCP-level +* functionalities +* +*/ + + +#ifndef C_CUPNPTCPSESSION_H +#define C_CUPNPTCPSESSION_H + +// INCLUDES +#include +#include "upnphttpmessage.h" +#include "upnplist.h" +#include "upnpnotifytimer.h" +#include "upnpsocketshutdown.h" + +// FORWARD DECLARATIONS + +class CUpnpHttpBuffer; +class CUpnpHttpServer; +class CUpnpSocketShutdown; +class RSocket; +class CUpnpTcpSessionWriter; +class CUpnpHttpFileTransferReader; +class CUpnpHttpFileTransferWriter; +class CUpnpTcpSessionReader; +class CUpnpHttpFileAccess; + +// CONSTANTS +static const TInt KErrorTimeout = 3000000; +//when reading from a file +static const TInt KServeFileSizeDefault = 10000; +// Based on 7.2.9.4 (DLNA 1.5 rev 0.90) +// We need wait until 30second for response +static const TInt KSessionTimeout = 35000000; + +static const TInt KConnectTimeout = 7000000; + +//default buffer size for reading from socket +static const TInt KRcvBufSizeDefault = 10000; +//default size for fiel content reading from a socket, must be a power of 2 +static const TInt KFileTransferReaderBufSizeDefault = 16384; +//timeout value for awaiting 100 continue +static const TInt K100ContinueTimeout = 5000000; + +// CLASS DECLARATION + +/** +* @brief CUpnpTcpSession is a class handling TCP functionality of the session. +* Class is responsible for managing connection and its timeout as well as +* for reading from and writing to socket. Those two last are directly +* handled by CUpnpTcpSessionReader and CUpnpTcpSessionWriter but CUpnpTcpSession +* supervises those processes. +* @lib DLNAWebServer.lib +* @since Series60 2.6 +*/ +NONSHARABLE_CLASS (CUpnpTcpSession) : public CBase, public MUpnpNotifyTimerObserver + { + friend class CUpnpSocketShutdown; +public: // Constructors and destructor + + /** + * Constructor for building CUpnpTcpSession. + * This constructor is used when connection is iniatiated from network. + * Second-phase construction is made by TcpConstructL(). + * @param aSocket Pointer to new Socket. + * @param aPriority Priority of this session + * @return A new CUpnpTcpServer instance. + **/ + CUpnpTcpSession( RSocket& aSocket, TThreadPriority aPriority ); + + /** + * Virtual destructor. + **/ + virtual ~CUpnpTcpSession(); + + +public: // Session functionality + + void ShutdownStop(); + + /** + * Starts to receive messages to this session + * @since Series60 3.2 + * @return None. + **/ + void InitialReceiveL(); + + /** + * Receive messages to this session + * @since Series60 3.2 + * @return None. + **/ + void ReceiveL(); + + /** + * Writes data thru this session's socket + * @since Series60 2.6 + * @param aBuffer Data to write. + * @return None. + **/ + void WriteL( const TDesC8& aBuffer ); + + /** + * Checks is session is connected. + * @since Series60 2.6 + * @return ETrue, if session is connected; EFalse othewise. + **/ + TBool IsConnected(); + + /** + * Returns the address that session is connected to. + * @since Series60 2.6 + * @return Address of remote endpoint of session's socket. + **/ + TInetAddr& RemoteHost(); + + /** + * Starts the timeoutTimer for session. If timer expires, no reply has + * been sent to remote host. + * @since Series60 2.6 + * @param aSessionErrorReplyNeeded ETrue, if in timeout there should be + * sent HTTP error 408 Server timeout. + **/ + void StartTimeoutTimer( TBool aSessionErrorReplyNeeded ); + + /** + * Starts the timeoutTimer for session. Session is deleted after 0.5ms by default. + * @since Series60 2.6 + **/ + void StartDisconnectingTimer(TInt aTime = 500); + + /** + * Starts disconnect session. + * @since Series60 3.2 + **/ + + void StartDisconnect( TBool aDisconnectNotification = EFalse ); + + /** + * Function that is used to send notification to client and disconnect + * the session. + * @since Series60 2.6 + **/ + void ServerBusyL(); + + /** + * Returns the SessionId of this session. + * @since Series60 3.1 + * @return SessionId. + **/ + TInt Id(); + +public: // Callback functions for reader and writer + + /** + * Handles possible error that can occure in the session as well as + * in reader and writer active objects. + * @since Series60 3.0 + * @param aError error code + **/ + void HandleErrorL( TInt aError ); + + /** + * Callback function for reader object. When the reader gets some + * data, it forwards it to the session with this callback. + * @since Series60 3.0 + * @param aBuffer buffer with received data. + **/ + void ReceivingCompletedL( TDesC8& aBuffer ); + + /** + * Callback function for writer object. When the request writing is + * completed then writer calls this function to notify session about it. + * @since Series60 3.0 + **/ + void WritingCompletedL(); + + /** + * Callback function for writer object. When the request writing is + * not completed due to an error, a new attempt to write is being made... + * @since Series60 3.2 + **/ + void WaitRetryError(TInt aError, TBool aStartTimer = EFalse); + /** + * Second phase constructor for building CUpnpTcpSession. + * This constructor is used when connection is iniatiated from network. + * @param aSocket Pointer to new Socket which is already connected + * to remote host. + * @return None + **/ + void TcpConstructL( RSocket aSocket, TInt aReadBufferSize, TInt aFileReadBufferSize ); + + + /** + * Cancels TcpReader + * @return None. + **/ + void CancelTcpReader(); + + +public: // virtual callback functions + + /** + * Callback function. Called when data has been received. + * @since Series60 2.6 + * @param aBuffer Data that has been received thru session. + **/ + virtual void BufferReceivedL( TDesC8& aBuffer ) = 0; + + /** + * Callback function. Deletes given session. + * @since Series60 2.6 + * @param aSession Session to delete. + **/ + virtual void DeleteThisSessionL( CUpnpTcpSession* aSession ) = 0; + + /** + * Checks if FileServe Exists. + * @since Series60 2.6 + * @return ETrue, if fileServe exists; EFalse otherwise. + **/ + virtual TBool FileServeExists() = 0; + + /** + * Callback function. Notifies upper layers that session has been disconnected. + * @since Series60 2.6 + * @param aAddr Address of remote host. + **/ + virtual void NotifyDisconnectL( TInetAddr aAddr ) = 0; + virtual void NotifyTimeoutL() = 0; + + //file transfer reader callbacks + + /** + * Callback function. Notifies http session when upload finished + * @since Series60 3.2 + **/ + virtual void FileTransferReaderDoneL() = 0; + + /** + * Callback function. Notifies http session when error in upload + * @since Series60 3.2 + **/ + virtual void FileTransferReaderErrorL(TInt aError) = 0; + + /** + * Callback function. Notifies http session when download finished + * @since Series60 3.2 + **/ + virtual void FileTransferWriterDoneL() = 0; + + /** + * Callback function. Checks for outstanding downloads + * @since Series60 3.2 + **/ + virtual void FileTransferWriterHandleMoreL() = 0; + + /** + * Callback function. Notifies upper layers that SocketServer is busy. + * @since Series60 2.6 + * @param aAddr Address of remote host. + **/ + virtual void SocketServerBusyL( const TInetAddr& aAddr ) = 0; + + /** + * Callback function. Deletes fileserve of this session. + * @since Series60 2.6 + **/ + virtual void DeleteServeFileL() = 0; + + /** + * Returns a pointer to FileAccess object of this session. + * @since Series60 3.2 + * @return Pointer to FileAccess object. + **/ + virtual CUpnpHttpFileAccess* FileAccess()=0; + + /** + * Callback function. Returns the port number of parent HttpServer. + * @since Series60 2.6 + * @return Portnumber of http server. + **/ + virtual TInt ServerPort() = 0; + + /** + * Callback function. Checks if connection uses Connection: Close + * header, and if so, tries to parse message and send it to upper layers. + * @since Series60 2.6 + **/ + virtual void CheckConnectionCloseL() = 0; + + /** + * Callback function. Informs upper layers that HTTP POST has been started + * by sending HTTP error code 801 message to upper layers. + * @since Series60 2.6 + **/ + virtual void NotifyUpperLayersOnPostL() = 0; + + /** + * Callback function. Informs upper layers that HTTP POST has been finished + * @since Series60 2.6 + **/ + virtual void PostingFileCompleteL() = 0; + +public: // From MNotifyTimeObserver + + /** + * Callback function for timer expirations. + * @since Series60 2.6 + * @param aTimer Timer that has expired. + **/ + void TimerEventL( CUpnpNotifyTimer* aTimer ); + + /** + * Cancel timer + * @since Series60 3.2 + **/ + void TimerCancel(); + + /** + * Handles disconnect request + * @since Series60 3.2 + **/ + void DisconnectRequestL(); + + /** + * Starts closing the session, no more message to be sent to the client + * @since Series60 3.2 + **/ + void StartClosingSession(); + + /** + * Marked if a persistent connection + * @since Series60 3.2 + **/ + TBool IsPersistentConnection(); + + /** + * Returns pointer to CUpnpHttpFileTransferReader + * @since Series60 3.2 + * @return CUpnpHttpFileTransferReader* + **/ + CUpnpHttpFileTransferReader* FileTransferReader(); + + /** + * Returns pointer to CUpnpHttpFileTransferWriter + * @since Series60 3.2 + * @return CUpnpHttpFileTransferWriter* + **/ + CUpnpHttpFileTransferWriter* FileTransferWriter(); + + /** + * Checks if there are outstanding sending operations. + * @since Series60 3.2 + * @return TBool + **/ + TBool DownloadOngoing(); + + /** + * Checks if the session is being shutdown + * @since Series60 3.2 + * @return TBool + **/ + TBool ShuttingDown() ; + /** + * Returns current value of the timeout + * @since Series60 3.2 + * @return TInt + */ + + /** + * Closes the socket + * @since Series60 3.2 + */ + void CloseSocketL(); + + TInt TimeoutCurrentValue(); +private: // private enumerations + + /** + * State of session. + * - EnotConnected - Connection is not established yet. + * - EConnecting - TcpSession requested connection in asynchronous mode. + * - EConnected - Connection is established, TcpReader is started and TcpWriter + * can write to the socket. + * - EDisconnecting - Session is about to be disconnected but socket is not closed + * so TcpWriter can still write a response. + * - EServerBusy - Server is already occupied with processing requests so no other + * session can be established. + **/ + enum TUpnpTcpSessionState + { + ENotConnected, + EConnecting, + EConnected, + EDisconnecting, + EShuttingDownWriteWait, + EShuttingDownStop, + EShuttingDown, + EServerBusy + }; + +private: // New functions + + /** + * Sets session statel. + * @since Series60 2.6 + * @param aState new state of the session. + **/ + void SetState( TUpnpTcpSessionState aState ); + + /** + * Checks if there are outstanding writing operations. + * @since Series60 3.2 + * @return TBool + **/ + TBool OutstandingWritings(); + +protected: + + /** + * Contructs file transfer reader + * @since Series60 3.2 + **/ + void FileTransferReaderConstructL(); + + virtual void DestroyIt(CUpnpTcpSession* aSession ) = 0; + + + /** + * Contructs file transfer writer + * @since Series60 3.2 + **/ + void FileTransferWriterConstructL(TInt aWriteSize); + +protected: + + TInt iFileReadBufferSize; + // Session's socket, owned + RSocket iSocket; + + // Address of remote host, owned + TInetAddr iAddr; + + // iTcpReader, active object to control reads from the socket. + // Owned by CUpnpTcpSession object. + CUpnpTcpSessionReader* iTcpReader; + + // iFileTransferReader, active object to control reads from the socket. + // Owned by CUpnpTcpSession object. + CUpnpHttpFileTransferReader* iFTReader; + + // iFileTransferWriter, active object to control writes from the socket. + // Owned by CUpnpTcpSession object. + CUpnpHttpFileTransferWriter* iFTWriter; + + // iTcpWriter, active object to control writes to the socket. + // Owned by CUpnpTcpSession object. + CUpnpTcpSessionWriter* iTcpWriter; + + // Timer that is used to disconnect session when timeout expires, owned + CUpnpNotifyTimer* iTimeoutTimer; + + // Buffer that is used to receive messages. See CUpnpHttpBuffer. + CUpnpHttpBuffer* iReceivedMessage; + + // Session id of this session, owned + TInt iId; + + // State of session, owned + TUpnpTcpSessionState iState; + + // ETrue, if session is meant to be kept alive; EFalse otherwise, owned + TBool iSessionKeepAlive; + + // ETrue, if session needs 408 HTTP error on timeout, owned + TBool iSessionNeedsErrorReply; + + // Used with session disconnects. If ETrue, session send notification + // of disconnect to upper layers, owned + TBool iDisconnectNotification; + + //Flag set true if any pending requests are left in a pipeline awating to be proccessed + TBool iPendingPostRequests; + + // value that is used to check if downloaded content should be saved + // into a file. + TBool iSaveToFile; + + // The current value of timeout, changes dependent on a operation-connecting, sending,... + TInt iTimeoutCurrentValue; + + // Timeout that defines the session length + TInt iTimeoutSessionValue; + + // Flag indicating if POST message with header "Expect: 100-continue" + // was received and server should wait for download of body after + // sending permission to continue download. + TBool iContinuedMessageDownload; + + // Initial priority, priority set for message that initialize this session + TThreadPriority iInitialPriority; + + //flag for indicating a persistant connection + TBool iIsPersistent; + + // Implementation of the socket shutdown algorithm + CUpnpSocketShutdown *iSocketShutdown; + + // Retry counter during export action + TInt iExportRetryCounter; + + TInt iSessionError; + }; + +#endif // C_CUPNPTCPSESSION_H + +// End Of File