1
|
#include <stdlib.h>
|
2
|
#include <stdio.h>
|
3
|
#include <stddef.h>
|
4
|
#include <unistd.h>
|
5
|
#include <string.h>
|
6
|
#include <fcntl.h>
|
7
|
#include <errno.h>
|
8
|
#include <termios.h>
|
9
|
#include <sys/ioctl.h>
|
10
|
#include <sys/stat.h>
|
11
|
|
12
|
#if defined(__linux__)
|
13
|
# define MODEM "/dev/ttyACM0"
|
14
|
#elif defined(__APPLE__)
|
15
|
# define MODEM "/dev/cu.usbmodem0000001"
|
16
|
#elif defined(__NetBSD__)
|
17
|
# define MODEM "/dev/dtyU0"
|
18
|
#elif defined(__bsdi__) || defined(__DragonFly__)
|
19
|
# define MODEM "/dev/cuaU0"
|
20
|
#endif
|
21
|
|
22
|
static void make_blocking(int fd)
|
23
|
{
|
24
|
const int old = fcntl(fd, F_GETFL, 0);
|
25
|
fcntl(fd, F_SETFL, old & ~(int)O_NONBLOCK);
|
26
|
}
|
27
|
|
28
|
static void make_nonblocking(int fd)
|
29
|
{
|
30
|
const int old = fcntl(fd, F_GETFL, 0);
|
31
|
fcntl(fd, F_SETFL, old | (int)O_NONBLOCK);
|
32
|
}
|
33
|
|
34
|
/* gcc -Wall -g3 -O1 -std=c99 test.c -o test.exe */
|
35
|
int main(int argc, char* argv[])
|
36
|
{
|
37
|
int fd = open(MODEM, O_RDWR | O_NOCTTY | O_SYNC);
|
38
|
if (fd == -1) {
|
39
|
printf("open failed\n");
|
40
|
goto finish;
|
41
|
}
|
42
|
|
43
|
printf("Setting TIOCEXCL\n");
|
44
|
|
45
|
/* Mark the fd as exclusive so ModemManager */
|
46
|
/* and friends cannot open and muck with state. */
|
47
|
if (ioctl(fd, TIOCEXCL, NULL) == -1) {
|
48
|
printf("ioctl failed\n");
|
49
|
goto finish;
|
50
|
}
|
51
|
|
52
|
printf("Getting tty\n");
|
53
|
|
54
|
struct termios tty;
|
55
|
if (tcgetattr(fd, &tty) != 0) {
|
56
|
printf("tcgetattr failed\n");
|
57
|
goto finish;
|
58
|
}
|
59
|
|
60
|
printf("Setting tty options\n");
|
61
|
|
62
|
cfmakeraw(&tty);
|
63
|
tty.c_cflag |= (CLOCAL | CRTSCTS);
|
64
|
// tty.c_cflag &= ~CSTOPB; /* 1 stop bit */
|
65
|
// tty.c_cflag |= CSTOPB; /* 2 stop bit */
|
66
|
|
67
|
cfsetospeed(&tty, B57600);
|
68
|
cfsetispeed(&tty, B57600);
|
69
|
|
70
|
printf("Flushing tty\n");
|
71
|
|
72
|
if (tcflush(fd, TCIOFLUSH) != 0) {
|
73
|
printf("tcflush failed\n");
|
74
|
goto finish;
|
75
|
}
|
76
|
|
77
|
printf("Setting tty\n");
|
78
|
|
79
|
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
|
80
|
printf("tcsetattr failed\n");
|
81
|
goto finish;
|
82
|
}
|
83
|
|
84
|
/*********** Write ***********/
|
85
|
|
86
|
printf("Writing ATZ\n");
|
87
|
|
88
|
ssize_t res = write(fd, "ATZ\r", 4);
|
89
|
if (res == -1) {
|
90
|
printf("write failed\n");
|
91
|
goto finish;
|
92
|
}
|
93
|
|
94
|
printf("Waiting for write\n");
|
95
|
|
96
|
res = tcdrain(fd);
|
97
|
if (res == -1) {
|
98
|
printf("tcdrain failed\n");
|
99
|
goto finish;
|
100
|
}
|
101
|
|
102
|
printf("Wrote: ATZ\n");
|
103
|
|
104
|
/*********** Read ***********/
|
105
|
|
106
|
printf("Reading response\n");
|
107
|
|
108
|
make_blocking(fd);
|
109
|
|
110
|
for ( ; ; )
|
111
|
{
|
112
|
unsigned char buf[512];
|
113
|
res = read(fd, buf, sizeof(buf));
|
114
|
if (res == -1 && errno == EWOULDBLOCK) {
|
115
|
break;
|
116
|
}
|
117
|
else if (res == -1) {
|
118
|
printf("read failed\n");
|
119
|
goto finish;
|
120
|
}
|
121
|
|
122
|
make_nonblocking(fd);
|
123
|
|
124
|
buf[res] = '\0';
|
125
|
printf("Read: %s\n", buf);
|
126
|
}
|
127
|
|
128
|
finish:
|
129
|
|
130
|
if (fd != -1)
|
131
|
close(fd);
|
132
|
|
133
|
return 0;
|
134
|
}
|