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
|
#include "modem.h"
#include "lock.h"
/* Baudrate for the TTY. Should be greater the 64000. */
#define BAUD_RATE B115200
struct modem *modem_open(const char *dev) {
struct modem *m;
int fd = -1, n;
struct termios ts, ts2;
assert(dev);
if (device_lock(dev) != 0)
return -1;
if ((fd = open(dev, O_RDWR|O_NDELAY)) < 0) {
daemon_log(LOG_ERR, "Failed to open device <%s>: %s", dev, strerror(errno));
goto fail;
}
if ((n = fcntl(fd, F_GETFL, 0)) < 0 || fcntl(fd, F_SETFL, n & ~O_NDELAY) < 0) {
daemon_log(LOG_ERR, "Failed to remove O_NDELAY flag from device: %s", strerror(errno));
goto fail;
}
memset(&ts, 0, sizeof ts);
ts.c_cflag = CRTSCTS | IGNPAR | HUPCL | CS8;
ts.c_iflag = IGNPAR;
ts.c_oflag = 0;
ts.c_lflag = 0;
ts.c_cc[VMIN] = 1;
ts.c_cc[VTIME] = 0;
cfsetospeed(&ts, BAUD_RATE);
cfsetispeed(&ts, BAUD_RATE);
tcflush(fd, TCIFLUSH);
if (tcsetattr(fd, TCSANOW, &ts) < 0) {
daemon_log(LOG_ERR, "Failed to set TTY attributes: %s", strerror(errno));
goto fail;
}
if (tcgetattr(fd, &ts2) < 0 || memcmp(&ts, &ts2) != 0) {
daemon_log(LOG_ERR, "Failed to set TTY attributes");
goto fail;
}
m = malloc(sizeof(struct modem));
assert(m);
memset(m, 0, sizeof(struct modem));
m->dev = strdup(dev);
assert(m->dev);
m->fd = fd;
m->state = MODEM_STATE_INIT;
return m;
fail:
if (fd >= 0)
close(fd);
device_unlock(dev);
return NULL;
}
void modem_close(struct modem *m) {
assert(m);
device_unlock(m->dev);
close(m->fd);
free(m->dev);
free(m);
}
static void* modem_cb(oop_source *source, int fd, oop_event event, void *user) {
struct modem *m;
assert(source && user);
m = (struct modem*) user;
if (m->mode == MODEM_STATE_INIT) {
} else if (m->mode == MODEM_STATE_AUDIO) {
if (event)
}
return OOP_CONTINUE;
}
|