commit 3103e6f39f27efab0e4dea190c49fcc61ed0abfd
parent 56b4a0e05f56251d7eefcd235bb1ffdbcdfb80ac
Author: Nihal Jere <nihal@nihaljere.xyz>
Date: Tue, 18 May 2021 23:01:34 -0500
atsim interaction works now
Diffstat:
M | atd.c | | | 81 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- |
M | atd.h | | | 2 | +- |
M | atsim.c | | | 58 | +++++++++++++++++++++++----------------------------------- |
3 files changed, 101 insertions(+), 40 deletions(-)
diff --git a/atd.c b/atd.c
@@ -46,7 +46,7 @@ struct fdbuf {
* the command is invalid but terminated, and -3 if the command is invalid and
* unterminated */
ssize_t cmdadd(struct fdbuf fdbuf) {
- struct command cmd;
+ struct command cmd = {0, CMD_NONE, NULL};
char *end = memchr(fdbuf.out, '\0', fdbuf.outlen);
char *ptr = fdbuf.out;
size_t count = 0;
@@ -63,9 +63,9 @@ ssize_t cmdadd(struct fdbuf fdbuf) {
if (end == NULL)
return -3;
- switch (*(ptr++)) {
+ cmd.op = *(ptr++);
+ switch (cmd.op) {
case CMD_DIAL:
- cmd.op = CMD_DIAL;
char num[PHONE_NUMBER_MAX_LEN];
while (*ptr != '\0') {
if (count > PHONE_NUMBER_MAX_LEN || strchr(DIALING_DIGITS, *ptr) == NULL)
@@ -90,6 +90,7 @@ ssize_t cmdadd(struct fdbuf fdbuf) {
fprintf(stderr, "received answer\n");
break;
case CMD_HANGUP:
+ fprintf(stderr, "received hangup\n");
if (*ptr != '\0')
goto bad;
fprintf(stderr, "received hangup\n");
@@ -98,6 +99,9 @@ ssize_t cmdadd(struct fdbuf fdbuf) {
fprintf(stderr, "got code: %d\n", *(ptr - 1));
}
+ /* we already checked that the queue has enough capacity */
+ command_enqueue(cmd);
+
return ptr - fdbuf.out;
bad:
@@ -105,6 +109,21 @@ bad:
return -2;
}
+size_t
+handle_resp(struct fdbuf *fdbuf)
+{
+ fprintf(stderr, "got here\n");
+ char *ptr = strchr(fdbuf->outptr, '\n');
+ size_t len;
+ if (ptr) {
+ len = ptr - fdbuf->outptr;
+ fprintf(stderr, "response: %*.*s\n", len, len, fdbuf->outptr);
+ return len;
+ }
+
+ return 0;
+}
+
int main(int argc, char *argv[])
{
argv0 = argv[0];
@@ -174,7 +193,8 @@ int main(int argc, char *argv[])
fds[LISTENER].fd = sock;
fds[LISTENER].events = POLLIN;
fds[BACKEND].fd = backsock;
- fds[BACKEND].events = 0;
+ fds[BACKEND].events = POLLIN;
+ fdbufs[BACKEND].outptr = fdbufs[BACKEND].out;
fds[SIGNALINT].fd = sigintfd;
fds[SIGNALINT].events = POLLIN;
@@ -216,11 +236,13 @@ int main(int argc, char *argv[])
} else if (len == -1) {
// TODO mark paused
} else {
+ fprintf(stderr, "got here\n");
assert(len <= BUFSIZE);
fdbufs[i].outlen -= len;
memmove(fdbufs[i].out, fdbufs[i].out + len, fdbufs[i].outlen);
assert(fdbufs[i].outlen >= 0);
fdbufs[i].outptr = fdbufs[i].out + fdbufs[i].outlen;
+ fds[BACKEND].events |= POLLOUT;
}
}
}
@@ -255,6 +277,57 @@ int main(int argc, char *argv[])
}
}
+ /* send next command to modem */
+ if (cmdq.count && (fds[BACKEND].revents & POLLOUT)) {
+ fprintf(stderr, "have a command!\n");
+ struct command cmd = command_dequeue();
+ size_t len;
+ fprintf(stderr, "op: %d\n", cmd.op);
+
+ if (!cmd.op)
+ continue;
+
+ if (cmd.data) {
+ len = snprintf(fdbufs[BACKEND].in, BUFSIZE, cmd_to_at[cmd.op], cmd.data);
+ } else {
+ len = snprintf(fdbufs[BACKEND].in, BUFSIZE, cmd_to_at[cmd.op]);
+ }
+ fprintf(stderr, "after data\n");
+ if (len >= BUFSIZE) {
+ warn("AT command too long!");
+ break;
+ }
+ fdbufs[BACKEND].inptr = fdbufs[BACKEND].in;
+ fdbufs[BACKEND].inlen = len;
+ int wr = write(fds[BACKEND].fd, fdbufs[BACKEND].inptr, fdbufs[BACKEND].inlen);
+ if (wr == -1) {
+ warn("failed to write to backend!");
+ break;
+ }
+ fdbufs[BACKEND].inptr += wr;
+ fdbufs[BACKEND].inlen -= wr;
+ fprintf(stderr, "done writing\n");
+
+ /* don't write any more until we hear back */
+ if (fdbufs[BACKEND].inlen == 0) {
+ fds[BACKEND].events &= ~POLLOUT;
+ fds[BACKEND].events &= POLLIN;
+ }
+ }
+
+ if (fds[BACKEND].revents & POLLIN) {
+ fprintf(stderr, "len: %d\n", fdbufs[BACKEND].outlen);
+ int ret = read(fds[BACKEND].fd, fdbufs[BACKEND].outptr, BUFSIZE - fdbufs[BACKEND].outlen);
+ if (ret == -1) {
+ warn("failed to read from backend:");
+ break;
+ }
+
+ fdbufs[BACKEND].outlen += ret;
+ ret = handle_resp(&fdbufs[BACKEND]);
+ memmove(fdbufs[BACKEND].outptr, fdbufs[BACKEND].outptr + ret + 1, BUFSIZE - (ret + 1));
+ }
+
if (fds[LISTENER].revents & POLLIN) {
/* TODO come up with a better way of assigning indices? */
for (int i = RSRVD_FDS; i < MAX_FDS; i++) {
diff --git a/atd.h b/atd.h
@@ -15,7 +15,7 @@ struct command {
};
char *cmd_to_at[] = {
- [CMD_DIAL] = "ATD%s;",
+ [CMD_DIAL] = "ATD%s;\r\n",
[CMD_ANSWER] = "ATA\r\n",
[CMD_HANGUP] = "ATH\r\n",
};
diff --git a/atsim.c b/atsim.c
@@ -1,4 +1,5 @@
#include <stdio.h>
+#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <poll.h>
@@ -10,6 +11,8 @@
#define SOCKFD 2
#define FDCOUNT 3
+#define BUFSIZE 1024
+
int main() {
struct sockaddr_un sockaddr = {
.sun_family = AF_UNIX,
@@ -18,8 +21,8 @@ int main() {
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
struct pollfd fds[FDCOUNT];
- char tosock[1024];
- char fromsock[1024];
+ char tosock[BUFSIZE];
+ char fromsock[BUFSIZE];
char *fromoff = fromsock;
char *tooff = tosock;
@@ -52,65 +55,50 @@ int main() {
fds[STDOUT].fd = 0;
fds[STDOUT].events = 0;
+ fprintf(stderr, "at loop\n");
while (true) {
- if (poll(fds, 2, -1) == -1) {
+ if (poll(fds, FDCOUNT, -1) == -1) {
fprintf(stderr, "poll failed");
}
- /* can read from socket */
+ if (fds[SOCKFD].revents & POLLHUP)
+ break;
+
if (fds[SOCKFD].revents & POLLIN) {
- int ret = read(fds[SOCKFD].fd, fromsock, 1024);
+ int ret = read(fds[SOCKFD].fd, fromsock, BUFSIZE);
if (ret == -1) {
fprintf(stderr, "failed to read from socket\n");
return 1;
}
- fromcount = ret;
- fromoff = fromsock;
- fds[SOCKFD].events &= ~POLLIN;
- fds[STDOUT].events |= POLLOUT;
+ write(STDOUT, fromsock, ret);
+ fds[STDIN].events |= POLLIN;
}
- if (fds[STDOUT].events & POLLOUT) {
- int ret = write(fds[STDOUT].fd, fromoff, fromcount);
+ if (fds[SOCKFD].revents & POLLOUT) {
+ fprintf(stderr, "in SOCKFD POLLOUT: %d\n", tocount);
+ int ret = write(fds[SOCKFD].fd, tosock, tocount);
if (ret == -1) {
- fprintf(stderr, "failed to write to stdout\n");
- return 1;
- }
- fromcount -= ret;
- fromoff += ret;
-
- /* we are done writing to stdout, so we can resume to reading */
- if (fromcount == 0) {
- fds[STDOUT].events &= ~POLLOUT;
- fds[SOCKFD].events |= POLLIN;
- }
- }
-
- if (fds[SOCKFD].events & POLLOUT) {
- int ret = write(fds[SOCKFD].fd, tooff, tocount);
- if (ret == -1) {
- fprintf(stderr, "failed to write to stdout\n");
+ fprintf(stderr, "failed to read from socket\n");
return 1;
}
tocount -= ret;
- tooff += ret;
-
- /* we are done writing to stdout, so we can resume reading */
- if (fromcount == 0) {
+ memmove(tosock, tosock + ret, BUFSIZE - ret);
+ fprintf(stderr, "tocount: %d\n", tocount);
+ if (tocount == 0) {
fds[SOCKFD].events &= ~POLLOUT;
- fds[STDIN].events |= POLLIN;
+ fds[SOCKFD].events &= POLLIN;
}
}
if (fds[STDIN].revents & POLLIN) {
- int ret = read(fds[STDIN].fd, tosock, 1024);
+ fprintf(stderr, "in STDIN POLLIN\n");
+ int ret = read(fds[STDIN].fd, tosock, BUFSIZE);
if (ret == -1) {
fprintf(stderr, "failed to read from stdin\n");
return 1;
}
tocount = ret;
tooff = fromsock;
- fds[STDIN].events &= ~POLLIN;
fds[SOCKFD].events |= POLLOUT;
}
}