dvrengine/CommonRecordingEngine/inc/CCRSock.h
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 09:14:38 +0200
changeset 0 822a42b6c3f1
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "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 for wrapping RSocket and CActive*
*/




#ifndef CCRSOCK_H
#define CCRSOCK_H

// INCLUDES
#include <in_sock.h>
#include "videoserviceutilsLogger.h"

// CONSTANTS
const TInt KMaxDataSize( 8192 );

// MACROS
// None

// DATA TYPES
// None

// FORWARD DECLARATIONS
class CCRSock;
class MCRSockObserver; 

// CLASS DECLARATION

/**
*  Class for receiving data via socket.
*
*  This is solely owned by CCRSock and considered a helper class.
*  Because there may be send and receive operations outstanding
*  at the same time, one RSocket needs 2  CActive instances.
*  @lib CommonRecordingEngine.lib
*  @since Series 60 3.0
*/
class CCRSockReader : public CActive
    {

public: // Constructors and destructor

    /**
    * Two-phased constructor.
    * @param aSock is reference to socket object 
    *        that this class instance serves.
    * @since Series 60 3.0
    * @param aConnection a connection.
    * @param aSockServer a socket server.
    * @return CCRSockReader pointer to CCRSockReader class.
    */
    static CCRSockReader* NewL( CCRSock& aSock, 
                                RConnection& aConnection,
                                RSocketServ& aSockServer );
    /**
    * Destructor.
    */
    virtual ~CCRSockReader();
    
public: // New Methods

    /**
    * Method for starting reading.
    * @since Series 60 3.0
    * @param none
    * @return always succeeds
    */
    void IssueRead( void );
    
private: // Constructors and destructors
    
    /**
    * Default constructor
    */
    CCRSockReader( CCRSock& aSock,
                   RConnection& aConnection,
                   RSocketServ& aSockServer );
    /** 
    * 2nd phase constructor 
    */
    void ConstructL();

private: // Methods from base classes

    /** 
    * From CActive.
    * This is the work-horse of this class.
    * @since Series 60 3.0
    * @param none.
    * @return none.
    */
    void RunL();
    
    /** 
    * From CActive.
    * This cancels work in progress.
    * @since Series 60 3.0
    * @param none.
    * @return none.
    */     
    void DoCancel();
    
    /** 
    * From CActive.
    * This handles errors.
    * @since Series 60 3.0
    * @param none.
    * @return none an status of method.
    */     
    TInt RunError( TInt aError );
    
private: // Data
    
    /**
    * Socket.
    */
    CCRSock& iSock;

    /** 
    * connection to use.
    */
    RConnection& iConnection;
    
    /**
    * Socket server.
    */
    RSocketServ& iSockServer;

#if defined ( LIVE_TV_FILE_TRACE ) || defined ( LIVE_TV_RDEBUG_TRACE ) 
    TUint recvCount; 
    TUint recvBytes; 
#endif // LIVE_TV_FILE_TRACE || LIVE_TV_RDEBUG_TRACE
    };

/**
* Encapsulates a socket in easy-to-use way
*/
class CCRSock : public CActive
    {

public: // Data types

    /**
     * Enum for communicating what is going on with this socket 
     */
    enum TCRSockStatus
        {
        EInitNeeded = 1000,
        EIdle,       /**< Nothing in progress */
        EResolving,   /**< Finding out addr to connect to */
        EConnecting,  /**< Addr found but no connection yet */
        ESending,     /**< Request to send has been issued but not yet completed */
        EListening,   /**< Request to wait for incoming connection is not yet compl. */     
        EFailed       /**< Something went wrong */
        };

public: // Constructors and destructor

    /**
    * Two-phased constructor.
    * @param aObserver is reference to object that 
    *        gets notified when something happens
    * @param aSockId is a number that this class instance
    *        will keep, do nothing with, and us the same 
    *        number when reporting statuses back to observer.
    *        motivation here is that same observer may have
    *        several instances of this class all reporting
    *        via same method. 
    * @param aProtoTCP ETrue for TCP socket, EFalse for UDP
    * @param aIssueRead ETrue to automatically receive data from
    *        socket and return to observer through DataReceived.
    *        EFalse to let user handle receiving data.
    * @return CCRSock pointer to CCRSock class
    */
    static CCRSock* NewL( MCRSockObserver& aObserver,
                          TInt aSockId,
                          RConnection& aConnection,
                          RSocketServ& aSockServer,
                          TBool aProtoTCP,
                          TBool aIssueRead );

    /**
    * Destructor.
    */
    virtual ~CCRSock();

public: // New methods

    /**
    * method for causing the socket to connect to remote addr.
    * @since Series 60 3.0
    * @param aAddr is the addr to connect to 
    * @param aPort is ip port number to connect to
    * @param aLocalPort specifies the local port to bind to. If 0 random
    *        port is selected
    * @return KErrNone is returned if connection is all right
    */
    TInt ConnectSock( const TDesC& aAddr,
                      TUint aPort,
                      TInt aLocalPort = 0 );

    /**
    * method for causing the socket to connect to remote addr without
    * doing DNS lookup. 
    * @since Series 60 3.0
    * @param aAddr is the addr to connect to 
    * @param aLocalPort specifies the local port to bind to. If 0 random
    *        port is selected       
    * @return KErrNone is returned if connection is all right
    */
    TInt ConnectSock( const TSockAddr& aAddr, 
                      TInt aLocalPort = 0);
                      
    /**
    * method for causing the socket to start listening at part.
    * @since Series 60 3.0
    * @param aPort is the port to listen to 
    * @return KErrNone is returned if connection is all right
    */
    TInt ListenPort( TUint aPort );
    
    /**
    * method for joining a multicast group
    * @since Series 60 3.0
    * @param aGruopAddr IPv6 address of the group to join
    * @return KErrNone on success
    */
    TInt JoinGroup( const TInetAddr& aGroupAddr );
    
    /**
    * method for sending data over the sock
    * @since Series 60 3.0
    * @param aData is the data that is sent over sock
    * @return none, succeeds always, if something goes wrong, it does it in async way
    */      
    void SendData( const TDesC8& aDataThatIsSentOverSocket );
        
    /**
    * Method for asking the status: what is going on 
    * @since Series 60 3.0
    * @param none.
    * @return socket status.
    */
    CCRSock::TCRSockStatus SockStatus( void ) const;

    /** 
    * Helper class may frobnicate our private parts:
    */
    friend class CCRSockReader;
    
    /** 
    * Method for getting the addr this socket is connected to in the other end
    * @since Series 60 3.0
    * @param none.
    * @return the addr
    */
    TInetAddr ConnectedAddr( void );

    /** 
    * Method for getting the addr this socket is connected to in the local end
    * @since Series 60 3.0
    * @param none.
    * @return the addr
    */
    TInetAddr LocalAddr( void );
    
    /** 
    * Method for setting the "where to send addr" and this is applicable for UDP socks
    * @param aAddr is the new addr.
    * @return none
    */
    void SetToAddr( const TInetAddr &aAddr );

    /**
    * Gets reference underlying Symbian socket implementation. To be used with caution.
    * @since Series 60 3.0
    * @param none.
    * @return reference to underlying ES_SOCK socket
    */
    RSocket& Socket();

private: // Constructors and destructors

    /**
    * default constructor
    */
    CCRSock( MCRSockObserver& aObserver,
             TInt aSockId,
             RConnection& aConnection,
             RSocketServ& aSockServer,
             TBool aProtoTCP,
             TBool aIssueRead );

    /** 
    * 2nd phase constructor 
    */
    void ConstructL();
       
private: // Methods from base classes

    /** 
    * From CActive.
    * This is the work-horse of this class.
    * @since Series 60 3.0
    * @param none.
    * @return none.
    */
    void RunL();
    
    /** 
    * From CActive.
    * This cancels work in progress.
    * @since Series 60 3.0
    * @param none.
    * @return none.
    */     
    void DoCancel();
    
    /** 
    * From CActive.
    * This handles errors.
    * @since Series 60 3.0
    * @param none.
    * @return none an status of method.
    */     
    TInt RunError( TInt aError );

private: // New methods

    /**
    * Handles send buffer.
    */
    void CopySendData( const TDesC8& aData );

    /**
    * Performs cleanup.
    */
    void CleanUp();
    
private: // Data types
    
    /**
    * This is used to read/write.
    */
    RSocket iSocket;
    
    /**
    * status for above socket.
    */
    TBool iIsiSocketOpen;
    
    /**
    * This is used to listen.
    * Not used when we use this class for outgoing connection.
    */
    RSocket iListenSocket;  
    
    /**
    * Status for above socket.
    */
    TBool iIsiListenSocketOpen;
    
    /**
    * This is used to find out addr by name.
    */
    RHostResolver iResolver;       
    /**
    * This is needed to get hold of RSocket.
    */
    RSocketServ& iSockServer;
    
    /**
    * This is where we connect to.
    */
    TNameEntry iHostAddress;
    
    /**
    * this is our internal status.
    */
    TCRSockStatus iSockStatus;
    
    /**
    * Our observer.
    */
    MCRSockObserver& iObserver;
    
    /**
    * Our own internal id.
    */
    const TInt iSockId;
    
    /**
    * This tells whether we're about to connect via udp or tcp.
    */
    TBool iProtoTCP;
    
    /**
    * This tells whether receiving data from socket is handled by CCRSockReader or used.
    */
    TBool iIssueRead;
    
    /**
    * This tells the port we're about to connect.
    */
    TUint iPort;
    
    /**
    * This tells the port we're binding locally.
    */
    TUint iLocalPort;
    
    /**
    * This is where we keep the data received.
    */
    HBufC8* iReceivedDataBuf;
    
    /**
    * Pointer to received data buffer.
    */
    TPtr8 iReceivedData;
    
    /**
    * This is where we keep the data being sent.
    */
    HBufC8* iSentDataBuf;

    /**
    * Pointer to send data buffer.
    */
    TPtr8 iSentData;  
    
    /**
    * This tells how much data we got.
    */
    TSockXfrLength iReceivedDataLen;
    
    /**
    * This tells how much data we sent.
    */
    TSockXfrLength iSentDataLen;        
    
    /** 
    * This tells where the packet was received from.
    */
    TInetAddr iFromAddr;
    
    /**
    * This tells if we've been listening or receiving in the past
    */
    TBool iWasListening;
    
    /**
    * This is instance of a helper class doing the reading part.
    */
    CCRSockReader *iReader;
    
    /**
    * This tells where to send UDP packets.
    */
    TInetAddr iToAddr;
    
    /**
    * Connection to use.
    */
    RConnection& iConnection;
        
#if defined ( LIVE_TV_FILE_TRACE ) || defined ( LIVE_TV_RDEBUG_TRACE ) 
    TUint sendCount; 
    TUint sendBytes; 
#endif // LIVE_TV_FILE_TRACE || LIVE_TV_RDEBUG_TRACE

    };

/**
* Class for live tv socket "client" e.g. the user of class CCRSock.
*/
class MCRSockObserver
    {

public:

    /**
    * This method is called after some data has been received from socket.
    * @since Series 60 3.0
    * @param aData is descriptor containing the data received. 
    *        ownership of data is not passed via this call. 
    * @return none.
    */
    virtual void DataReceived( TInt aSockId,
                               const TDesC8& aData ) = 0;

    /**
    * This method is called after status of socket changes.
    * @since Series 60 3.0
    * @param aSockId a socket id.
    * @param aStatus is sock status.
    * @param aError a error code.
    * @return none
    */
    virtual void SockStatusChange( TInt aSockId,
                                   CCRSock::TCRSockStatus aStatus,
                                   TInt aError ) = 0;
    };

#endif // CCRSOCK_H

// End of file