summaryrefslogtreecommitdiffstats
path: root/src/modem.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/modem.c')
-rw-r--r--src/modem.c84
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;
}