#include "serial.h"

serialport* OpenSerial(const char* deviceName) {
  serialport* newPort;
  /* alloca spazio per la struttura newPort */
  newPort = (serialport*)malloc( sizeof(serialport) );
  if (!newPort) return 0;
  newPort->deviceName = (char*)malloc( strlen(deviceName) );
  if ( !newPort->deviceName ) {
    free (newPort);
    return 0;
  }
  strcpy( newPort->deviceName, deviceName);
  /* prova ad aprire la porta */
  newPort->fd = open(deviceName, O_RDWR | O_NOCTTY );
  if ( newPort->fd<0 ) {
    free (newPort);
    return 0;
  }
  /* 
     Tutto OK, allora configura la porta per I/O non canonico, con
     timeout di SERIAL_TIMEOUT s. 
  */
  tcgetattr(newPort->fd,&(newPort->oldSettings));
  newPort->currentSettings = newPort->oldSettings;
  newPort->currentSettings.c_cflag = BAUDRATE | CRTSCTS | CLOCAL | CS8 | CREAD;
  //  newPort->currentSettings.c_iflag = IGNPAR | IGNCR;
  newPort->currentSettings.c_iflag = IGNPAR | ICRNL ;
  newPort->currentSettings.c_oflag = 0;
  /* not canonical input */
  newPort->currentSettings.c_lflag = 0;
  newPort->currentSettings.c_cc[VMIN]=0; 
  newPort->currentSettings.c_cc[VTIME]=10*SERIAL_TIMEOUT; 
  tcflush(newPort->fd, TCIFLUSH);
  tcsetattr(newPort->fd,TCSANOW,&(newPort->currentSettings));
  return newPort;  
}

void CloseSerial(serialport* port) {
  tcsetattr(port->fd,TCSANOW,&(port->oldSettings));
  close(port->fd);
  free (port->deviceName);
  free (port);
  return;
}

int WriteSerial(serialport* port, const char* buffer) {
  int size, realsize;
  size = strlen(buffer);
  if ( size>MAXBUFFERSIZE || size<0 ) return -1;
  realsize = write(port->fd, buffer, size);
  if (buffer[size-1]!='\n') realsize+=write(port->fd,"\n", 1);
  return realsize;
}

int ReadSerial(serialport* port, char* buffer) {
  int size, sizetot=0;
  char *pos=buffer;
  while ( (size=read(port->fd,pos,MAXBUFFERSIZE-sizetot))>0 ){
    if (size<MAXBUFFERSIZE-sizetot) {
      pos+=size;
      sizetot+=size;
      if ( *(pos-1)=='\n' ) break;
    } else return -1;
  }
  buffer[sizetot]='\0';
  return sizetot;
}
