atd

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/atd
Log | Files | Refs

commit 64afb8d2db309b5c445d63d016d26b3b67e5829a
parent b666d095f209f9fa6cc20962a1b05cde2519a38d
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Sat,  5 Jun 2021 21:12:05 -0500

parse clcc

Diffstat:
Matd.c | 67++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Matd.h | 3+++
Mqueue.h | 1+
3 files changed, 64 insertions(+), 7 deletions(-)

diff --git a/atd.c b/atd.c @@ -28,6 +28,8 @@ #define STDOUT 0 #define STDIN 1 #define STDERR 2 + + #define LISTENER 3 #define BACKEND 5 #define SIGNALINT 6 @@ -51,6 +53,12 @@ struct command currentcmd; int cmd_progress; bool active_command = false; bool check_call_status = false; +bool handling_urc = false; +enum atcmd currentatcmd; + +#define MAX_CALLS 8 +struct call calls[MAX_CALLS]; +struct call calls2[MAX_CALLS]; ssize_t parse_str(char *in, char **out) @@ -121,8 +129,29 @@ send_status(int fd, enum status status) return 0; } +struct call +parseclcc(char *start, size_t len) +{ + unsigned char idx; + unsigned char dir; + unsigned char stat; + unsigned char mode; + unsigned char mpty; + char number[PHONE_NUMBER_MAX_LEN]; + unsigned char type; + unsigned char alpha; + + struct call call = { .present = true }; + + int ret = sscanf(start, "+CLCC: %hhu,%hhu,%hhu,%hhu,%hhu,\"%[+1234567890ABCD]\",%hhu,%hhu", &idx, &dir, &call.status, &mode, &mpty, call.num, &type, &alpha); + + fprintf(stderr, "clcc: got %d successful matches\n", ret); + + calls2[idx] = call; +} + size_t -handle_resp(struct command cmd, int fd, struct fdbuf *fdbuf) +handle_resp(int fd, struct fdbuf *fdbuf) { fprintf(stderr, "handle_resp start\n"); char *start = fdbuf->out, *ptr = memmem(fdbuf->out, fdbuf->outlen, "\r\n", 2); @@ -141,11 +170,18 @@ handle_resp(struct command cmd, int fd, struct fdbuf *fdbuf) if (strncmp(start, "OK", sizeof("OK") - 1) == 0) { status = STATUS_OK; active_command = false; + if (handling_urc) { + handling_urc = false; + } fprintf(stderr, "got OK\n"); } else if (strncmp(start, "ERROR", sizeof("ERROR") - 1) == 0) { status = STATUS_ERROR; active_command = false; fprintf(stderr, "got ERROR\n"); + if (currentatcmd == CLCC) { + memcpy(calls, calls2, MAX_CALLS*sizeof(calls[0])); + memset(calls2, 0, MAX_CALLS*sizeof(calls[0])); + } } else if (strncmp(start, "NO CARRIER", sizeof("NO CARRIER") - 1) == 0) { check_call_status = true; fprintf(stderr, "got NO CARRIER\n"); @@ -158,6 +194,11 @@ handle_resp(struct command cmd, int fd, struct fdbuf *fdbuf) } else if (strncmp(start, "BUSY", sizeof("BUSY") - 1) == 0) { check_call_status = true; fprintf(stderr, "got BUSY\n"); + } else if (strncmp(start, "+CLCC", sizeof("+CLCC") - 1) == 0) { + fprintf(stderr, "got +CLCC\n"); + assert(check_call_status); + + struct call call = parseclcc(start, ptr - start); } if (status && fd > 0) @@ -205,6 +246,7 @@ bool send_command(int fd, struct fdbuf *fdbuf, enum atcmd atcmd, union atdata atdata) { ssize_t ret; + fprintf(stderr, "send command\n"); if (atcmd == ATD) { ret = snprintf(fdbuf->in, BUFSIZE, atcmds[atcmd], atdata.dial.num); } else { @@ -225,6 +267,7 @@ send_command(int fd, struct fdbuf *fdbuf, enum atcmd atcmd, union atdata atdata) } fprintf(stderr, "done writing: %d\n", fdbuf->inlen); active_command = true; + currentatcmd = atcmd; return true; } @@ -380,13 +423,15 @@ int main(int argc, char *argv[]) break; } - ret = handle_resp(cmd, fds[cmd.index].fd, &fdbufs[BACKEND]); + ret = handle_resp(fds[cmd.index].fd, &fdbufs[BACKEND]); memmove(fdbufs[BACKEND].out, fdbufs[BACKEND].out + ret, BUFSIZE - ret); fdbufs[BACKEND].outlen -= ret; fdbufs[BACKEND].outptr -= ret; } - if (cmdq.count && !active_command) + /* note that this doesn't take effect until the next poll cycle... + * maybe this can be replaced with something more integrated? */ + if ((cmdq.count || check_call_status) && !active_command) POLLADD(fds[BACKEND], POLLOUT); else POLLDROP(fds[BACKEND], POLLOUT); @@ -394,11 +439,19 @@ int main(int argc, char *argv[]) /* send next command to modem */ if (fds[BACKEND].revents & POLLOUT) { fprintf(stderr, "have a command!\n"); - cmd = command_dequeue(); - fprintf(stderr, "op: %d\n", cmd.op); - if (!send_command(fds[BACKEND].fd, &fdbufs[BACKEND], cmddata[cmd.op].atcmd, cmd.data)) - break; + if (check_call_status) { + if (!send_command(fds[BACKEND].fd, &fdbufs[BACKEND], CLCC, (union atdata){0})) + break; + handling_urc = true; + } else { + cmd = command_dequeue(); + fprintf(stderr, "op: %d\n", cmd.op); + assert(cmd.op != CMD_NONE); + + if (!send_command(fds[BACKEND].fd, &fdbufs[BACKEND], cmddata[cmd.op].atcmd, cmd.data)) + break; + } /* don't write any more until we hear back */ if (fdbufs[BACKEND].inlen == 0) { diff --git a/atd.h b/atd.h @@ -1,3 +1,5 @@ +#include <stdbool.h> + #define PHONE_NUMBER_MAX_LEN 15 #define DIALING_DIGITS "0123456789*#+ABC" @@ -43,6 +45,7 @@ struct command { }; struct call { + bool present; enum callstatus status; char num[PHONE_NUMBER_MAX_LEN]; }; diff --git a/queue.h b/queue.h @@ -23,6 +23,7 @@ struct command command_dequeue() { return (struct command){ .op = CMD_NONE }; cmd = cmdq.cmds[cmdq.first]; + cmdq.cmds[cmdq.first].op = CMD_NONE; cmdq.first = (cmdq.first + 1) % QUEUE_SIZE; cmdq.count--; return cmd;