mowc

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

commit b4dae62c779b979d0080ffe7f2f68228e914c0f4
parent 2e0eb088288dc4944502426d5db21efaa2ed3229
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Mon,  7 Jun 2021 23:41:29 -0500

initial calld implementation

Diffstat:
Aclients/calld.c | 135+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 135 insertions(+), 0 deletions(-)

diff --git a/clients/calld.c b/clients/calld.c @@ -0,0 +1,135 @@ +#include <assert.h> +#include <poll.h> +#include <stdio.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <unistd.h> + +#include <atd.h> +#include <encdec.h> + +#ifndef ATD_PATH +#define ATD_PATH "/tmp/atd-socket" +#endif + +#define ATD 0 +#define NUMFD 2 + +struct call calls[MAX_CALLS]; +struct call calls2[MAX_CALLS]; +struct call *active; + +void +handle_update() +{ + for (int i = 0; i < MAX_CALLS; i++) { + /* there is no active call with the id */ + if (!(calls[i].present || calls2[i].present)) + continue; + + /* an active call has been ended */ + if (calls[i].present && !calls2[i].present && active == &calls[i]) { + active = NULL; + fprintf(stderr, "kill\n"); + /* kill call program */ + continue; + } + + /* a new call */ + if (!calls[i].present) { + if (calls2[i].status == CALL_DIALING) { + fprintf(stderr, "launch call\n"); + /* launch call program */ + } else if (calls2[i].status == CALL_INCOMING) { + /* launch call answer program */ + fprintf(stderr, "launch answer\n"); + } + continue; + } + + /* TODO handle all cases */ + switch (calls[i].status) { + case CALL_DIALING: + if (calls2[i].status == CALL_ACTIVE) { + assert(!active); + active = &calls[i]; + /* launch call program */ + fprintf(stderr, "launch call\n"); + } + break; + case CALL_INCOMING: + if (calls2[i].status == CALL_ACTIVE) { + assert(!active); + active = &calls[i]; + /* launch call program */ + fprintf(stderr, "launch call\n"); + } + break; + default: + fprintf(stderr, "transition from %d to %d unhandled\n", calls[i].status, calls2[i].status); + } + } + + memcpy(calls, calls2, sizeof(calls)); + memset(calls2, 0, sizeof(calls2)); +} + +int +main(int argc, char *argv[]) +{ + struct sockaddr_un addr = { + .sun_family = AF_UNIX, + .sun_path = ATD_PATH, + }; + + int sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock == -1) { + fprintf(stderr, "failed to open atd socket\n"); + return 1; + } + + if (connect(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)) == -1) { + fprintf(stderr, "failed to connect to socket\n"); + close(sock); + return 1; + } + + if (atd_cmd_call_events(sock) < 0) { + fprintf(stderr, "failed to request to receive call events\n"); + close(sock); + return 1; + } + + struct pollfd fds[NUMFD]; + enum status status; + ssize_t ret; + + fds[ATD].fd = sock; + fds[ATD].events = POLLIN; + fds[1].fd = -1; + while (true) { + if (poll(fds, NUMFD, -1) == -1) + break; + + if (fds[ATD].revents & POLLIN) { + ret = read(fds[ATD].fd, &status, 1); + if (ret == -1) { + fprintf(stderr, "failed to read from atd\n"); + break; + } + + if (status == STATUS_CALL) { + if (dec_call_status(fds[ATD].fd, calls2) < 0) { + fprintf(stderr, "bad call status from atd\n"); + break; + } + } + + handle_update(); + } + } +err: + close(sock); + return 1; +}