/***************************************************************************
 *   Copyright (C) 2004 by EVER Sp. z o.o.                                 *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#ifndef CCOMM_H
#define CCOMM_H

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#define COMM_SUCCESS		( 0)
#define COMM_FAILURE		(-1)

#define COMMFAIL( var )	(bool)((var==COMM_SUCCESS)?0:1)

/* 
 * Status bits enumerator
 */
typedef enum _ecomm_status_
{
	CTS,
	DSR,
	RING,
	RLSD
} ecomm_status;

typedef enum _ecomm_lines_
{
	S_RTS	= TIOCM_RTS,
	S_CTS	= TIOCM_CTS,
	S_DTR	= TIOCM_DTR,
	S_DSR	= TIOCM_DSR,
	S_RNG	= TIOCM_RNG,
	S_CD	= TIOCM_CD
} ecomm_lines;

class CComm {
private:
	int	fd;					// file descriptor
	int	lasterror;			// last errno
	struct termios	oldtio,
						newtio;	// terminal structures
	char	*device;				// device name to open
	speed_t	baudrate;
	bool bIsInitialized;		// initialization flag
	bool bIsLocked;			// lock status flag
	bool bIsSimpleSig;		// simple signalling mode flag

public:
	/* class constructor/destructor */
	CComm();
	~CComm();
	
	int init(char *devpath, speed_t speed) {
		if (devpath!=NULL) {
			if (device!=NULL)	
				free(device);
			device=strdup(devpath);
		}
		if (speed!=0)
			baudrate=speed;
	};
	int open();
	int open_simplesignalling();
	int close();
	/* status lines checking/setting functions */
	int getStatus();
	int getStatus(int *pflags);
	int setStatus(int flags);
	int status_check(ecomm_status eFlags);
	int set_line(ecomm_lines eline);
	int clr_line(ecomm_lines eline);
	/* communication functions */
	int send(unsigned char data);
	int send(unsigned char *pdata, int len);
	int send2b(unsigned int *pdata);
	int send2b(unsigned int *pdata, int len2b);
	int receive(unsigned char *pdata);
	int receive(unsigned char *pdata, int len);
	/* receive specified number of bytes and convert it to 16 bits data */ 
	int receive2b(unsigned int *pdata, int len2b);
	/* receive specified number of bytes and convert it to 16 bits data reversing bytes */ 
	int receive2brev(unsigned int *pdata, int len2b);
	/* CRC versions of two function above */
	int receive2b(unsigned int *pdata, int len2b, unsigned long *pcrc);
	int receive2brev(unsigned int *pdata, int len2b, unsigned long *pcrc);

	int receive() {
		unsigned char rdata=0;
		if (receive(&rdata)!=COMM_FAILURE)
			return (int)rdata;
		else
			return COMM_FAILURE;
	};
	void flush(bool i, bool o) {
		if (bIsInitialized) {
			if (i) tcflush(fd, TCIFLUSH);
			if (o) tcflush(fd, TCOFLUSH);
		}
	};
	int purgeOutput() {
	};
	int lock_port();
	int unlock_port();
	bool isInitialized() {
		return bIsInitialized;
	};
};

#endif
