
// Serial.h


#include <CtrlLib/CtrlLib.h>

using namespace Upp;




#ifndef __SERIAL_H__
#define __SERIAL_H__

#ifdef PLATFORM_WIN32

#define FC_DTRDSR       0x01
#define FC_RTSCTS       0x02
#define FC_XONXOFF      0x04
#define ASCII_BEL       0x07
#define ASCII_BS        0x08
#define ASCII_LF        0x0A
#define ASCII_CR        0x0D
#define ASCII_XON       0x11
#define ASCII_XOFF      0x13


class SerialPort
{

public:
	SerialPort();
	virtual ~SerialPort();

	bool Open( int nPort = 2, int nBaud = 9600 );
	bool Close( void );

	int ReadData( void *, int );
	int SendData( const char *, int );
	int ReadDataWaiting( void );

	bool IsOpened( void ){ return( m_bOpened ); }

protected:
	bool WriteCommByte( unsigned char );

	HANDLE m_hIDComDev;
	OVERLAPPED m_OverlappedRead, m_OverlappedWrite;
	bool m_bOpened;

};

#else

#include <Core/Core.h>
#include <termios.h>


class SerialPort
{
public:
	typedef SerialPort CLASSNAME;

	class SerialException : public Upp::Exc
	{
	public:
		typedef SerialException CLASSNAME;

		/**
		 * @brief     Constructeur d'une Exception (1er niveau : a l'origine)
		 *
		 * @param[in] msg : description de l'erreur
		 */
		SerialException(const Upp::String& msg) :
			Upp::Exc(msg)
			{
			}
		
		SerialException(const Upp::String& msg, const Upp::Exc& cause)
		: Exc( msg + "\n Caused by >   " + cause )
		{
		}

		virtual ~SerialException() throw()
		{
		}
	};
	
	public:
		typedef enum {
			 BDS_115200 = B115200
			,BDS_57600 = B57600
			,BDS_38400 = B38400
			,BDS_19200 = B19200
			,BDS_9600 = B9600
			,BDS_4800 = B4800
			,BDS_2400 = B2400
			,BDS_1200 = B1200
			,BDS_600 = B600
			,BDS_300 = B300
			,BDS_110 = B110
		} SerialPortSpeeds;
		
		// Creation ET ouverture du port serie
		SerialPort();
		
		bool Open(int nPort = 2, int nBaud = 9600 );
		bool Open(const char * const device, const SerialPortSpeeds sp );
		bool Close();
		
		bool IsOpened(){return m_fileDesc!=-1;}
		
		// destruction ET fermeture du pôrt serie
		virtual ~SerialPort();
		
		
		typedef enum {
			  WRITE_OK = 0
			, WRITE_ERROR = -1
		} WriteReturnValues;

		///< envoie des octets
		WriteReturnValues write( int nbBytesToWrite, const char* const buf );
		
		
		typedef enum {
			  READ_OK=0
			, READ_TIMEDOUT = 1
			, READ_ERROR = -1
		} ReadReturnValues;
		
		int ReadData( void *pbuf, int num){read((char*)pbuf,num);return num;}
		
		// lecture d'octets
		ReadReturnValues read(char* buf, int& nbBytesToRead, int timeOutms=-1);
		
		// Debug method
		static Upp::String BufToString(const char * const buf, const int nbBytes, const char * const prefixString);

	private:
		int    m_fileDesc;
		Upp::String m_deviceName;
};

#endif
#endif
