diff options
Diffstat (limited to 'src/modem.c')
-rw-r--r-- | src/modem.c | 84 |
1 files changed, 77 insertions, 7 deletions
diff --git a/src/modem.c b/src/modem.c index 44eec06..0d47e4d 100644 --- a/src/modem.c +++ b/src/modem.c @@ -55,6 +55,7 @@ struct modem *modem_open(const char *dev) { assert(m->dev); m->fd = fd; m->state = MODEM_STATE_INIT; + m->child_pid = -1; return m; @@ -70,25 +71,94 @@ fail: void modem_close(struct modem *m) { assert(m); - device_unlock(m->dev); + if (m->child_pid != -1) + child_process_kill(m->child_pid); + close(m->fd); + device_unlock(m->dev); free(m->dev); free(m); } -static void* modem_cb(oop_source *source, int fd, oop_event event, void *user) { - struct modem *m; +static int modem_read(struct modem *m) { + char *p; + ssize_t s; + assert(m && m->input_buf); + + p = m->input_buf+m->input_buf_len; + if ((s = read(m->fd, &p, MODEM_BUF_LEN-m->input_buf_len)) <= 0) { + daemon_log(LOG_ERR, "Failed to read() from modem: %s", !s ? "EOF" : strerror(errno)); + return -1; + } + + m->input_buf_len += s; +} + +static void* oop_timeout_cb(oop_source *source,struct timeval tv,void *user) { + struct modem *m = (struct modem*) user; + assert(source && user); + + daemon_log(LOG_ERR, "Timeout reached for device <%s>", m->device); + return OOP_HALT; +} + +static void modem_timeout(struct modem *m, int t) { + struct timeval tv = { t, 0 }; + assert(m); + assert(event_source && event_source->on_time); + event_source->cancel_time(event_source, m->timeout, oop_timeout_cb, m); + + if (t > 0) { + gettimeofday(&m->timeout); + m->tv_sec += t; + + assert(event_source && event_source->on_time); + event_source->on_time(event_source, m->timeout, oop_timeout_cb, m); + } +} + +static void* oop_init_cb(oop_source *source, int fd, oop_event event, void *user) { + struct modem *m = (struct modem*) user; assert(source && user); - m = (struct modem*) user; + assert(m && m->fd == fd && m->mode == MODEM_STATE_INIT); + + if (event == OOP_READ) { + if (modem_read(m) < 0) + return OOP_HALT; + + } else if (event == OOP_WRITE) { + modem_write(m); + } + + return OOP_CONTINUE; +} - if (m->mode == MODEM_STATE_INIT) { - } else if (m->mode == MODEM_STATE_AUDIO) { +static void* oop_audio_simple_cb(oop_source *source, int fd, oop_event event, void *user) { + struct modem *m = (struct modem*) user; + assert(source && user); + assert(m && m->mode == MODEM_STATE_AUDIO_SIMPLE); - if (event) + if (event == OOP_READ) { + modem_read(m); + } else if (event == OOP_WRITE) { + modem_write(m); } + + return OOP_CONTINUE; +} +static void* oop_audio_shbuf_cb(oop_source *source, int fd, oop_event event, void *user) { + struct modem *m = (struct modem*) user; + assert(source && user); + assert(m && m->mode == MODEM_STATE_AUDIO_SHBUF); + + if (event == OOP_READ) { + modem_read(m); + } else if (event == OOP_WRITE) { + modem_write(m); + } return OOP_CONTINUE; } |