#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include "serial.h" #include "log.h" #include "config.h" #include "gpio.h" #include "runtime.h" #include "mf700.h" #include "reader.h" int serial_interfaceattribs(int *fd, int speed){ struct termios tty; if (tcgetattr(*fd, &tty) < 0) { char *log; if(asprintf(&log, "Error from tcgetattr: %s", strerror(errno)) > 0 ){ writesyslog(LOG_ERR, log); } free(log); return -1; } cfsetospeed(&tty, (speed_t)speed); cfsetispeed(&tty, (speed_t)speed); tty.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */ tty.c_cflag &= ~(unsigned)CSIZE; tty.c_cflag |= CS8; /* 8-bit characters */ tty.c_cflag &= ~(unsigned)PARENB; /* no parity bit */ tty.c_cflag &= ~(unsigned)CSTOPB; /* only need 1 stop bit */ tty.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */ tty.c_iflag &= ~((unsigned)IXON | (unsigned)IXOFF | (unsigned)IXANY); // Turn off flow control /* setup for non-canonical raw mode */ cfmakeraw(&tty); /* fetch bytes as they become available */ tty.c_cc[VMIN] = 73; tty.c_cc[VTIME] = 1; //block time out 0.1 sec if (tcsetattr(*fd, TCSANOW, &tty) != 0) { char *log; if(asprintf(&log, "Error from tcsetter: %s", strerror(errno)) > 0 ){ writesyslog(LOG_ERR, log); } free(log); return -1; } return 0; } int openserialport(struct serialport_t *serial, char *serialpath){ serial->fd = open(serialpath, O_RDWR | O_NOCTTY | O_SYNC); if (serial->fd < 0) { char *log; if(asprintf(&log, "Error opening %s: %s", serialpath, strerror(errno)) > 0 ){ writesyslog(LOG_ERR, log); } free(log); printf("Serial port error %s\n", serialpath); return -1; } serial_interfaceattribs(&serial->fd, BAUDRATE); return 0; } struct serialport_t sharedbuffer; //read serial port thread void *readserialport(void *ptr){ unsigned char chr; struct serialport_t *serial; serial = (struct serialport_t *) ptr; unsigned int idx = 0; while(1){ ssize_t len1 = read(serial->fd, &chr, sizeof(chr)); if (len1 > 0){ if ((chr == '\r' || chr == '\n') && idx == 72){ serial->buff[idx] = '\0'; pthread_mutex_lock(&sharedbuffermutex); memcpy(&sharedbuffer, serial, sizeof(struct serialport_t)); pthread_cond_signal(&sharedbuffersignal); pthread_mutex_unlock(&sharedbuffermutex); idx = 0; }else if (idx > 72){ idx = 0; }else if (chr == ACK || chr == NACK ){ idx = 0; }else { serial->buff[idx] = chr; idx++; } } } } void *serialdatawatch(void *ptr){ struct config_t *config; config = (struct config_t *) ptr; while(1) { pthread_mutex_lock(&sharedbuffermutex); //wait for signal from serial read pthread_cond_wait(&sharedbuffersignal, &sharedbuffermutex); struct reader_t reader; reader.fd = sharedbuffer.fd; reader.reader = sharedbuffer.reader; reader.config = config; memcpy(reader.buff, sharedbuffer.buff, sizeof(reader.buff)); readerrequest(&reader, config); //remove all credential data from buffer memset(&sharedbuffer, 0, sizeof(struct serialport_t)); pthread_mutex_unlock(&sharedbuffermutex); } }