1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
#include <errno.h>
#include <fcntl.h> /* O_RDWR */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <time.h>
#include <unistd.h>
#define BUFFER_SIZE sizeof(char) * 256
int openSerialPort(char pathToPort[]) {
static int serialPort;
struct termios serialTerminal;
serialPort = open(pathToPort, O_RDWR);
if (serialPort < 0) {
printf("Error open(): %s\n", strerror(errno));
return -1;
}
if (tcgetattr(serialPort, &serialTerminal) != 0) {
printf("Error tcgetattr(): %s\n", strerror(errno));
close(serialPort);
return -1;
}
serialTerminal.c_cflag |= CREAD;
/* serialTerminal.c_iflag &= ~(BRKINT | IGNBRK | INLCR | IGNCR | ICRNL | IXOFF
| IUTF8 | IUCLC | IXANY | IMAXBEL); */
serialTerminal.c_iflag &=
~(IGNBRK | BRKINT | INLCR | IGNCR | ICRNL | IXON | IXOFF | IUCLC | IXANY |
IMAXBEL | IGNPAR | PARMRK | INPCK | ISTRIP);
/* serialTerminal.c_lflag &= ~(ECHO | ECHONL | NOFLSH | ISIG | TOSTOP | ICANON
| IEXTEN | ECHOE | ECHOK); */
serialTerminal.c_lflag &= ~(ICANON | ISIG | ECHO | ECHONL | ECHOE | ECHOK);
/* serialTerminal.c_oflag &=
~(OLCUC | OCRNL | OPOST | OFILL | ONLCR | ONOCR | ONLRET | OFDEL); */
serialTerminal.c_oflag &= ~(OPOST);
serialTerminal.c_cc[VTIME] = 2;
serialTerminal.c_cc[VMIN] = 0;
cfsetispeed(&serialTerminal, B115200);
cfsetospeed(&serialTerminal, B115200);
if (tcsetattr(serialPort, TCSANOW, &serialTerminal) != 0) {
printf("Error tcsetattr(): %s\n", strerror(errno));
close(serialPort);
return -1;
}
return serialPort;
}
int querySerialPort(char **output, int serialPort, char *input) {
time_t timeStart;
unsigned long idx;
int bytesRead, returnCode, isEnd, beforeLength;
char *txBuffer, *buffer = malloc(BUFFER_SIZE);
const char *responseCodes[8] = {"\r\nOK\r\n", "\r\nCONNECT\r\n",
"\r\nRING\r\n", "\r\nNO CARRIER\r\n",
"\r\nERROR\r\n", "\r\nNO DIALTONE\r\n",
"\r\nBUSY\r\n", "\r\nNO ANSWER\r\n"};
txBuffer = malloc(sizeof(char) * (strlen(input) + 2));
strcpy(txBuffer, input);
strncat(txBuffer, "\r", 2 * sizeof(char));
if (write(serialPort, txBuffer, sizeof(char) * (strlen(txBuffer))) < 0) {
printf("Error write(): %s\n", strerror(errno));
free(txBuffer);
free(buffer);
return 1;
}
free(txBuffer);
*output = realloc(*output, sizeof(char));
**output = '\0';
bytesRead = 0;
returnCode = isEnd = 0;
timeStart = time(NULL);
while (!isEnd) {
bytesRead = read(serialPort, buffer, BUFFER_SIZE);
if (bytesRead < 0) {
printf("Error reading serial port\n");
returnCode = 1;
break;
}
if (bytesRead > 0) {
beforeLength = strlen(*output);
*output = realloc(*output, sizeof(char) * (beforeLength + 1) + bytesRead);
memcpy(*output + beforeLength, buffer, bytesRead);
(*output)[beforeLength + (bytesRead / sizeof(char))] = '\0';
for (idx = 0; idx < sizeof(responseCodes) / sizeof(*responseCodes);
idx++) {
if (strstr(*output, responseCodes[idx])) {
isEnd = 1;
break;
}
}
} else if (bytesRead == 0 && time(NULL) - timeStart > 180) {
printf("Response timeout after 180 seconds\n");
returnCode = 1;
break;
}
}
free(buffer);
return returnCode;
}
|