summaryrefslogtreecommitdiffstats
path: root/src/modem.c
blob: 44eec06481b363a552d4ba460663a39fe4b3df0e (plain)
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;
}