commit b4dae62c779b979d0080ffe7f2f68228e914c0f4
parent 2e0eb088288dc4944502426d5db21efaa2ed3229
Author: Nihal Jere <nihal@nihaljere.xyz>
Date: Mon, 7 Jun 2021 23:41:29 -0500
initial calld implementation
Diffstat:
A | clients/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;
+}