// Cambiado el 13/03/2020 para que funcione en Debian 10  64bits.

#include "define.h"
#include "port.h"

#include "unistd.h"
#include "string.h"

#include <time.h>


#if YesWindows
HANDLE hSerial;
DCB dcbSerialParams;
COMMTIMEOUTS time_out;
unsigned int MiBAUDIOS = CBR_115200;
#else
struct termios newtermios, terminal_settings;
int fdrs232;
unsigned int MiBAUDIOS = B115200;
#endif

char *MODEMDEVICE;


#if YesSDL
#include <SDL/SDL.h>
void DelayMs(unsigned int t)
{
    SDL_Delay(t);
}
#else
#if YesWindows
void DelayMs(long t)
{
    Sleep(t);
}
#else
void DelayMs(long t)
{
    usleep(t * 1000);
}
#endif
#endif


void PrintSerial(char *cadena)
{
    int tama;
    tama = strlen(cadena);

#if DEBUGCOM
    printf("debug->%s<-\n", cadena);
#endif

#if YesWindows
    WriteSerie(hSerial, cadena, tama);
#else
    write(fdrs232, cadena, tama);
#endif
}



int CloseRs232()
{
#ifdef DEBUGCOM
    printf("Cerrando puerto de comunicaciones\n");
#endif

#if YesWindows
    CloseHandle(hSerial);
#else
    tcflush(fdrs232, TCIFLUSH);
    close(fdrs232);
#endif
    return 0;
}


int IniRs232()
{

#if YesWindows
    //____________Programacion serie Windows__________________________
    hSerial =
	CreateFile(MODEMDEVICE, GENERIC_READ | GENERIC_WRITE, 0, NULL,
		   OPEN_EXISTING, 0, NULL);
    if (hSerial == INVALID_HANDLE_VALUE) {
	if (GetLastError() == ERROR_FILE_NOT_FOUND) {
#ifdef DEBUGCOM
	    printf("PUERTO %s NO EXISTE !! \n", MODEMDEVICE);
#endif
	    return -1;
	}
    } else {
//            dcbSerial.DCBlength=sizeof(dcbSerialParams);
	if (!GetCommState(hSerial, &dcbSerialParams)) {
	    printf("Error get Status!!\n");
	    return -1;
	}
	dcbSerialParams.BaudRate = MiBAUDIOS;
	dcbSerialParams.ByteSize = 8;
	dcbSerialParams.StopBits = ONESTOPBIT;
	dcbSerialParams.Parity = NOPARITY;
	if (!SetCommState(hSerial, &dcbSerialParams)) {
	    CloseHandle(hSerial);
	    printf("Error get Status2!!\n");
	    return -1;
	}
	time_out.ReadIntervalTimeout = 10;	//20;   
	time_out.ReadTotalTimeoutMultiplier = 1;	//2;
	time_out.ReadTotalTimeoutConstant = 2;	//50;
	time_out.WriteTotalTimeoutMultiplier = 2;
	time_out.WriteTotalTimeoutConstant = 50;
	if (SetCommTimeouts(hSerial, &time_out) == 0)
	    printf("Error SetCommTimeouts \n");
    }
#else
//_________Programacion Linux________________________

    fdrs232 = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NDELAY);
    if (fdrs232 < 0) {
#ifdef DEBUGCOM
	printf("Error puerto de comunicaciones\n");
#endif
	return (-1);
    }
// PARA QUE FUNCIONE EN DEBIAN 10 =========================
/* Let BREAK cause a SIGINT in input. */
    terminal_settings.c_iflag &= ~IGNBRK;
    terminal_settings.c_iflag |= BRKINT;

    terminal_settings.c_iflag |= IGNPAR;
    terminal_settings.c_iflag &= ~PARMRK;
    terminal_settings.c_iflag &= ~ISTRIP;
    terminal_settings.c_iflag &= ~(INLCR | IGNCR | ICRNL);

#ifdef IUCLC
    terminal_settings.c_iflag &= ~IUCLC;
#endif
    terminal_settings.c_cflag &= ~CSIZE;
    terminal_settings.c_cflag |= CS8;
    terminal_settings.c_cflag |= CREAD;
    terminal_settings.c_lflag |= ISIG;
    terminal_settings.c_lflag &= ~ICANON;
    terminal_settings.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
    terminal_settings.c_lflag &= ~IEXTEN;

    terminal_settings.c_cc[VTIME] = 0;
    terminal_settings.c_cc[VMIN] = 1;

    tcsetattr(fdrs232, TCSANOW, &terminal_settings);
// fin - PARA QUE FUNCIONE EN DEBIAN 10 =========================               



    newtermios.c_cflag = MiBAUDIOS | CS8 | CLOCAL | CREAD;
    newtermios.c_iflag = IGNPAR;
    newtermios.c_oflag = 0;
    newtermios.c_lflag = 0;
    newtermios.c_cc[VMIN] = 0;
    newtermios.c_cc[VTIME] = 0;

    cfsetospeed(&newtermios, MiBAUDIOS);
    cfsetispeed(&newtermios, MiBAUDIOS);
    if (tcflush(fdrs232, TCIFLUSH) == -1) {
	printf("Error RS 1\n");
	return -1;
    }
    if (tcflush(fdrs232, TCOFLUSH) == -1) {
	printf("Error RS 2\n");
	return -1;
    }
    if (tcsetattr(fdrs232, TCSANOW, &newtermios) == -1) {
	printf("Error RS 3\n");
	return -1;
    }
    //Hace que el puerto serie no espere
    fcntl(fdrs232, F_SETFL, O_NDELAY);

#endif

#if PORTYES
    printf("YES-- %s \n", MODEMDEVICE);
#endif
    return 0;
}

#if YesWindows
int WriteSerie(HANDLE hSerial, char *c, int tamano)
{
    int bRes;
    //DWORD dwError;
    DWORD dwNumBytesWritten = 0;
    bRes = WriteFile(hSerial, c, tamano, &dwNumBytesWritten, NULL);
    if (!bRes)
	printf("Error mandado Bytes %lu   \n", dwNumBytesWritten);
    return 1;
}


int ReadSerie(HANDLE hSerial, char *c, int tamano)
{
    int bRes;
    DWORD bytesRead = 0;
    bRes = ReadFile(hSerial, c, tamano, &bytesRead, NULL);
    if (!bRes) {
	printf("Error leyendo Bytes %lu \n", bytesRead);
	return -1;
    }
    if (bytesRead == 0)
	return -2;
    return bRes;
}

#endif
