atd

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

commit 7a066f48fc6d5af9ca44b1be2d1f2c50444e520c
parent d7d61e0aff365a13e79c757b44eb64405d6d40eb
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Thu, 29 Apr 2021 21:56:13 -0500

add queue, cleanup, fix broken things

Diffstat:
Matc.c | 38+++++++++++++++++++++++++++++++-------
Matd.c | 82+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Matd.h | 8+++++---
Aqueue.h | 29+++++++++++++++++++++++++++++
4 files changed, 114 insertions(+), 43 deletions(-)

diff --git a/atc.c b/atc.c @@ -7,12 +7,33 @@ #include "atd.h" int -call(int fd, char *num) +sendcode(int fd, int code) { - char callcode = CMD_DIAL; + int ret, left = 2; + char buf[2]; + char *ptr = buf; + buf[0] = code; + buf[1] = '\0'; + + while (left > 0) { + ret = write(fd, ptr, left); + if (ret == -1) + return -1; + + ptr += ret; + left -= ret; + } + + return 0; +} + +int +dial(int fd, char *num) +{ + char dialcode = CMD_DIAL; int ret, left = strlen(num); do { - ret = write(fd, &callcode, 1); + ret = write(fd, &dialcode, 1); if (ret == -1) return -1; if (ret == 1) @@ -50,10 +71,9 @@ main(int argc, char *argv[]) if (argc < 2) return 1; - if (strcmp(argv[1], "call") == 0) { + if (strcmp(argv[1], "dial") == 0) { if (argc < 3) return 1; - cmd = CMD_DIAL; } else if (strcmp(argv[1], "answer") == 0) { cmd = CMD_ANSWER; @@ -78,10 +98,14 @@ main(int argc, char *argv[]) switch (cmd) { case CMD_DIAL: - call(sock, argv[2]); + dial(sock, argv[2]); + break; + default: + sendcode(sock, cmd); + break; } - sleep(5); + sleep(1); close(con); close(sock); diff --git a/atd.c b/atd.c @@ -13,6 +13,7 @@ #include "atd.h" #include "util.h" +#include "queue.h" #define AT_MAX 256 #define ATD_SOCKET "/tmp/atd-socket" @@ -31,13 +32,6 @@ char *argv0; -struct { - char *ptrs[QUEUE_MAX]; - char **start; - char **next; - size_t count; -} atq; - struct fdbuf { ssize_t inlen; ssize_t outlen; @@ -47,7 +41,10 @@ struct fdbuf { char *outptr; }; -/* add one command to queue, returns 0 if command was validated and added successfully, -1 if the command is invalid but terminated, and -2 if the command is invalid and unterminated. Then sets next to point after the command */ +/* add one command to queue, returns the number of bytes intepreted if the + * command was validated and added successfully, -1 if the queue is full, -2 if + * the command is invalid but terminated, and -3 if the command is invalid and + * unterminated */ /* TODO what if queue is full? */ ssize_t cmdadd(struct fdbuf fdbuf) { struct command cmd; @@ -55,48 +52,59 @@ ssize_t cmdadd(struct fdbuf fdbuf) { char *ptr = fdbuf.out; size_t count = 0; - /* given that we have a max length for a command, if the buffer does not contain a terminated command, we can assume that the command is incomplete and read mode data from the fd until the buffer is full. If it still doesn't contain a terminated command, then we know that we are dealing with garbage, and we throw it out, and inform the client. In case of garbage, two '\0' in a row flush the buffer */ + if (cmdq.count == QUEUE_SIZE) + return -1; + + /* given that we have a max length for a command, if the buffer does not + * contain a terminated command, we can assume that the command is + * incomplete and read more data from the fd until the buffer is full. If + * it still doesn't contain a terminated command, then we know that we are + * dealing with garbage, and we throw it out, and inform the client. In + * case of garbage, two '\0' in a row flush the buffer */ if (end == NULL) - return -2; + return -3; switch (*(ptr++)) { case CMD_DIAL: cmd.op = CMD_DIAL; /* TODO replace this malloc */ - cmd.data = malloc(sizeof(struct data_dial)); - if (cmd.data == NULL) - goto bad; + char num[PHONE_NUMBER_MAX_LEN]; while (*ptr != '\0') { if (count > PHONE_NUMBER_MAX_LEN || strchr(DIALING_DIGITS, *ptr) == NULL) goto bad; - ((struct data_dial *)cmd.data)->num[count] = *(ptr++); + num[count] = *(ptr++); count++; } - ((struct data_dial *)cmd.data)->count = count; + + cmd.data = malloc(count + 1); + if (cmd.data == NULL) + goto bad; + + memcpy(cmd.data, num, count); + ((char*)cmd.data)[count] = '\0'; - fprintf(stderr, "received dial with number "); - for (int i = 0; i < count; i++) - fputc(((struct data_dial *)cmd.data)->num[i], stderr); - fputc('\n', stderr); + fprintf(stderr, "received dial with number %s\n", cmd.data); break; case CMD_ANSWER: - ptr++; if (*ptr != '\0') goto bad; fprintf(stderr, "received answer\n"); + break; case CMD_HANGUP: - ptr++; if (*ptr != '\0') goto bad; - fprintf(stderr, "received answer\n"); + fprintf(stderr, "received hangup\n"); + break; + default: + fprintf(stderr, "got code: %d\n", *(ptr - 1)); } return ptr - fdbuf.out; bad: fdbuf.outptr = end + 1; - return -1; + return -2; } int main(int argc, char *argv[]) @@ -135,26 +143,32 @@ int main(int argc, char *argv[]) fds[i].fd = -1; int backsock = socket(AF_UNIX, SOCK_STREAM, 0); - if (backsock == -1) - die("failed to create backend socket:"); + if (backsock == -1) { + warn("failed to create backend socket:"); + goto error; + } int back = connect(backsock, (struct sockaddr *) &backaddr, sizeof(struct sockaddr_un)); if (back == -1) { - die("failed to connect to backend:"); + warn("failed to connect to backend:"); + goto error; } int sock = socket(AF_UNIX, SOCK_STREAM, 0); if (sock == -1) { - die("failed to create socket:"); + warn("failed to create socket:"); + goto error; } /* TODO replace these dies with warns and gotos so the socket file gets removed properly */ if (bind(sock, (struct sockaddr *) &sockaddr, sizeof(struct sockaddr_un)) == -1) { - die("failed to bind to socket:"); + warn("failed to bind to socket:"); + goto error; } if (listen(sock, 50) == -1) { - die("failed to set socket to listening:"); + warn("failed to set socket to listening:"); + goto error; } fds[STDIN].fd = STDIN; @@ -174,7 +188,6 @@ int main(int argc, char *argv[]) break; } - /* handle interrupt */ if ((fds[SIGNALINT].revents & POLLIN) || fds[LISTENER].revents & POLLHUP) { warn("time to die"); break; @@ -198,7 +211,9 @@ int main(int argc, char *argv[]) fdbufs[i].outlen += len; fdbufs[i].outptr += len; - // parsecmd should parse as much as it can, letting us know how much was left unparsed so we can move it to the beginning of the buffer. + // parsecmd should parse as much as it can, letting us know how + // much was left unparsed so we can move it to the beginning of + // the buffer. len = cmdadd(fdbufs[i]); if (len == -2) { continue; @@ -263,8 +278,9 @@ int main(int argc, char *argv[]) } } - for (int i = 0; i < MAX_FDS; i++) { - if (fds[i].fd > STDERR) +error: + for (int i = STDERR+1; i < MAX_FDS; i++) { + if (fds[i].fd > 0) close(fds[i].fd); } unlink(ATD_SOCKET); diff --git a/atd.h b/atd.h @@ -9,11 +9,13 @@ enum ops { }; struct command { + int index; enum ops op; void *data; }; -struct data_dial { - char num[20]; - size_t count; +char *cmd_to_at[] = { + [CMD_DIAL] = "ATD%s;", + [CMD_ANSWER] = "ATA\r\n", + [CMD_HANGUP] = "ATH\r\n", }; diff --git a/queue.h b/queue.h @@ -0,0 +1,29 @@ +#define QUEUE_SIZE 50 + +struct { + struct command cmds[QUEUE_SIZE]; + int first; + int next; /* where to place the next command */ + int count; +} cmdq; + +int command_enqueue(struct command cmd) { + assert(cmdq.count <= QUEUE_SIZE); + if (cmdq.count == QUEUE_SIZE) + return -1; + + cmdq.cmds[cmdq.next] = cmd; + cmdq.next = (cmdq.next + 1) % QUEUE_SIZE; + return ++cmdq.count; +} + +struct command command_dequeue() { + struct command cmd; + if (cmdq.count == 0) + return (struct command){ .op = CMD_NONE }; + + cmd = cmdq.cmds[cmdq.first]; + cmdq.first = (cmdq.first + 1) % QUEUE_SIZE; + cmdq.count--; + return cmd; +}