diff options
Diffstat (limited to 'src/modem.c')
-rw-r--r-- | src/modem.c | 59 |
1 files changed, 51 insertions, 8 deletions
diff --git a/src/modem.c b/src/modem.c index ef1d7fd..1269fbb 100644 --- a/src/modem.c +++ b/src/modem.c @@ -55,11 +55,12 @@ struct modem *modem_open(const char *dev) { assert(m->dev); m->buffio = buffio_new(fd); assert(m->buffio); - m->state = MODEM_STATE_INIT; + m->buffio->output_empty_cb = modem_output_empty_cb; + m->buffio->input_ready_cb = modem_output_ready_cb; + m->child_pid = -1; - modem_timeout(m, 10); - modem_next_command(m); + modem_init(m); return m; @@ -195,11 +196,10 @@ static const char* const init_at_commands[INIT_AT_COMMANDS*2] = { -static void modem_input_init_cb(struct buffio *b, void *user) { +static void modem_input_ready_cb(struct buffio *b, void *user) { struct modem *m = user; assert(b && m && m->buffio == b); - switch (m->state) { case MODEM_STATE_INIT: { @@ -213,6 +213,7 @@ static void modem_input_init_cb(struct buffio *b, void *user) { if (m->command_index >= INIT_AT_COMMANDS) { m->state = MODEM_STATE_CALLER_NUMBER_EXPECT; + modem_timeout(m, 0); modem_input_init_cb(b, user); } else modem_next_command(m); @@ -294,15 +295,49 @@ static void modem_input_init_cb(struct buffio *b, void *user) { break; case MODEM_STATE_CONNECTION: + + m->state = MODEM_STATE_HANGUP; break; - case MODEM_STATE_DONE: + case MODEM_STATE_HANGUP: { + + modem_send_command(m, { DLE, DC4, DLE, ETX, 0 }); + m->state = MODEM_STATE_FORCE_HANGUP; break; + } + } +} + + +static void modem_output_empty_cb(struct buffio *b, void *user) { + struct modem *m = user; + assert(b && m && m->buffio == b); + + switch (m->state) { + case MODEM_STATE_FORCE_HANGUP: + modem_force_hangup(m); + modem_init(m); + break; } - } +void modem_force_hangup(struct modem *m) { + struct termios pts; + assert(m && m->buffio); + + tcgetattr(m->buffio->fd, &pts); + cfsetospeed(&pts, B0); + cfsetispeed(&pts, B0); + tcsetattr(m->buffio->fd, TCSANOW, &pts); + + tcgetattr(m->buffio->fd, &pts); + cfsetospeed(&pts, BAUD_RATE); + cfsetispeed(&pts, BAUD_RATE); + tcsetattr(m->buffio->fd, TCSANOW, &pts); +} + + static void modem_send_command(struct modem *m, const char *p) { assert(m && m->buffio); @@ -328,6 +363,14 @@ static void modem_next_command(struct modem *m) { m->buffio->input_cb = modem_input_cb; buffio_command(m->buffio, p); + } -// { DLE, DC4, DLE, ETX, 'A', 'T', 'H', '\n', "AT&F\n" }, +static void modem_init(struct modem *m) { + assert(m); + m->state = MODEM_STATE_INIT; + m->command_index = 0; + + modem_timeout(m, 10); + modem_next_command(m); +} |