/**@file*/

#ifndef TCPConnection_h_DEFINExD
#define TCPConnection_h_DEFINED

#include <ant.h>
#include <IPAddress.h>
#include <OPENR/OSyslog.h>

/** Stati delle connessioni TCP.*/
enum ConnectionState {
  
  CONNECTION_INVALID=0,    /**< Connessione non valida*/
  CONNECTION_CONNECTING=1, /**< Connessione in connessione*/
  CONNECTION_CONNECTED=2,  /**< Connessione connessa*/
  CONNECTION_WAITING=3,    /**< Connessione in attesa di spedire*/
  CONNECTION_LISTENING=4,  /**< Connessione in attesa di riecevere*/
  CONNECTION_SENDING=5,    /**< Connessione in spedizione*/
  CONNECTION_RECEIVING=6,  /**< Connessione in ricezione*/
  CONNECTION_CLOSING=7,    /**< Connessione in fase di chiusura*/
  CONNECTION_CLOSED=8      /**< Connessione chiusa*/
};

/**Connessione base TCP. Classe base che definisce una connessione TCP
   priva di buffer, utile per essere ereditata da connessioni piu'
   specifiche. Non si occupa della gestione dei metodi di CONNECT e
   LISTEN in quanto, per motivi sia di efficienza, sia di
   incompatibilita' tecnica di gestione (necessita' di utilizzare
   Extra-entry point) vengono gestiti da TelepatiTcp.*/
class TCPConnection {
 public:
  /**Costruttore di Default. Imposta una connessione non valida.*/
  TCPConnection() { state= CONNECTION_INVALID; }; 
  /**Costruttore base. Inizializza i valori del putatore allo stack
     TCP/IP dell'Aibo e la imposta come CLOSED. @param ipStack
     riferimento allo stack TCP/IP dell'Aibo*/
  TCPConnection(antStackRef ipStack) {ipstackRef=ipStack; state = CONNECTION_CLOSED; };
  /**Distruttore di Default*/
  virtual ~TCPConnection() {};
  
  /**Restituisce un riferimento all'Endpoint. Fornisce l'Endpoint
     (concetto OPEN-R simile alle Socket di Unix) della
     connessione.@return endpoint della connessione*/
  inline antModuleRef& getEndpoint() {return endpoint;};

  /**Imposta lo stato della connessione. @param st nuovo stato della
     connessione. @see ConnectionState*/
  inline void setState(ConnectionState st) {state = st;};
  /**Restituisce lo stato corrente della connessione. @return stato
     corrente. @see ConnectionState*/
  inline ConnectionState getState() { return state;};

  /**Imposta la porta della connessione TCP. @param prt porta di
     comunicazione TCP*/
  inline void setPort(Port prt) {port=prt;};
  /**Ritorna la porta TCP di comunicazione. @return porta di
     comunicazione*/
  inline Port getPort() {return port;};

  /**Inizializza la connessione. Ha il compito di inizializzare il
     buffer di comunicazione e di creare ed inizializzare l'Endpoint
     della connessione. Da implementare. */
  virtual OStatus initConnection() = 0;
  /**Ferma la connessione. Chiude la connessione, dopo la chiamata a
     questo metodo la connessione non sara' piu' utilizzabile, per
     riutilizzarla dovra' essere reinizializzata. Da implementare.*/
  virtual OStatus stop() = 0;
  
 protected:
  /** Riferimento all'Endpoint della connessione*/
  antModuleRef endpoint;     
  /** Riferimento allo stack TCP/IP dell'Aibo*/
  antStackRef ipstackRef;    
  
  /** Stato della connessione @see ConnectionState*/
  ConnectionState state;     
  /** Porta TCP di comunicazione*/
  Port port;  
};

/**Connessione TCP di Ricezione. Rappresenta una connessione di
   ricezione TCP utilizzata da TelepatiTcp. Aggiunge a TCPConnection
   la gestione del buffer di ricezione e implementa i metodi "pure
   virtual" initConnection() e stop().*/
class TCPRecvConnection : public TCPConnection { 
 public:
  /** Costruttore di Default. La connessione sara' INVALID.*/
  TCPRecvConnection() {}; 
  /**Costruttore base. Costruisce una connessione TCP di ricezione, ma
     non inizializza i buffer. @param ipStack riferimento allo stack
     TCP/IP dell'Aibo. @param bs dimensione del buffer di ricezione in
     byte.*/
  TCPRecvConnection(antStackRef ipStack, int bs);

  /** Distruttore di Default*/
  ~TCPRecvConnection(); 

  /**Inizializza la connessione. Inizializza il buffer di ricezione e
     l'endpoint della connessione. @return oSUCCESS in caso si
     successo; oFAIL altrimenti*/
  OStatus initConnection();
  /**Ferma la ricezione. Chiude la connessione, dopo la chiamata a
     questo metodo la connessione non sara' piu' utilizzabile. @return
     oSUCCESS in caso si successo; oFAIL altrimenti*/
  OStatus stop();
  
  /**Restituisce il buffer di ricezione. Ritorna un riferimento al
     buffer di ricezione della connessione. @return puntatore al
     buffer di ricezione*/
  inline byte* getRecvData() { return recvData;};
  /**Restituisce la dimensione massima del pacchetto ricevibile. Il
     valore restituito non si e' la dimensione del buffer di
     ricezione, che viene specificato nel costruttore, ma un valore
     con solo significato informativo.@return dimensione massima
     pacchetto*/
  inline int getRecvSize() { return recvSize;}
  /**Imposta la dimensione massima del buffer di ricezione. Il valore
     passato come parametro non si e' la dimensione del buffer di
     ricezione, che viene specificato nel costruttore, ma un valore
     con solo significato informativo. @param size nuova dimensione
     del buffer di ricezione.*/
  inline void setRecvSize(int size) { recvSize=size;}

 private:
    
  /* Buffer di ricezione*/
  antSharedBuffer recvBuffer; 
  /* Puntatore ai dati contenunti nel buffer di ricezione*/
  byte* recvData;         
  /* Dimensione buffer di Ricezine*/
  int recvSize;           
  
  /* Inizializza il buffer. @return oSUCCESS in caso si successo;
     oFAIL altrimenti*/	  
  OStatus initBuffer();       
  /* Crea l'Endpoint- @return oSUCCESS in caso si successo; oFAIL
     altrimenti*/		  
  OStatus initTcpEndpoint();  
  
};


/**Connessione TCP di spedizione. Rappresenta una connessione di
   spedizione TCP utilizzata da Telepati. Aggiunge a TCPConnection la
   gestione del buffer di ricezione e implementa i metodi "pure
   virtual" initConnection() e stop().*/
class TCPSendConnection : public TCPConnection {
 public:
  /** Costruttore di Default. La connessione sara' INVALID*/
  TCPSendConnection() {};  
  /**Costruttore. Costruisce una connessione TCP di spedizione, ma non
     inizializza ne il buffer di spedizione ne l'endpoint. @param
     ipStack riferimento allo stack TCP/IP dell'Aibo. @param bs
     dimensione del buffer di ricezione in byte.*/
  TCPSendConnection(antStackRef ipStack, int bs);

  /** Distruttore di Default*/
  ~TCPSendConnection(); 

  /**Inizializza la connessione. Inizializza il buffer di ricezione e
     l'endpoint della connessione. @return oSUCCESS in caso si
     successo; oFAIL altrimenti*/
  OStatus initConnection();
  /**Ferma la connessione. Chiude la connessione, dopo la chiamata a
     questo metodo la connessione non sara' piu' utilizzabile. @return
     oSUCCESS in caso si successo; oFAIL altrimenti*/
  OStatus stop();

  /**Ritorna il buffer di spedizione. Ritorna un puntatore al buffer
     di spedizione della connessione. @return puntatore al buffer di
     spedizione.*/
  inline byte* getSendData() {return sendData;};
  /**Restituisce la dimensione dei dati da spedire. Il valore
     restituito non si e' la dimensione del buffer di spedizione, che
     viene specificato nel costruttore, ma un valore con solo
     significato informativo. @return dimensione pacchetto da
     spedire*/
  inline int getSendSize() { return sendSize;}
  /**Imposta la dimensione dei dati da spedire. Il valore passato come
     parametro non si e' la dimensione del buffer di spedizione, che
     viene specificato nel costruttore, ma un valore con solo
     significato informativo. @param size dimensione dei dati da
     spedire.*/
  inline void setSendSize(int size) { sendSize=size;}
 private:
  
  /* Buffer di spedizione*/
  antSharedBuffer sendBuffer; 
  /* Puntatore ai dati contenunti nel buffer di spedizione*/
  byte* sendData;          
  /* Dimensione del buffer*/
  int bufferSize;            

  /* Dimensione dei dati da spedire*/
  int sendSize;             

  /* Inizializza il buffer. @return oSUCCESS in caso si successo;
     oFAIL altrimenti*/	
  OStatus initBuffer();       
  /* Crea l'Endpoint. @return oSUCCESS in caso si successo; oFAIL
     altrimenti*/		
  OStatus initTcpEndpoint();  
};

#endif // TCPConnection_h_DEFINED
