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