aboutsummaryrefslogtreecommitdiffstats
path: root/src/icipc-client.c
blob: 587878c3053a51852f18c3c7d073384792324a74 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/* PipeWire AGL Cluster IPC
 *
 * Copyright © 2021 Collabora Ltd.
 *    @author Julian Bouzas <julian.bouzas@collabora.com>
 *
 * SPDX-License-Identifier: MIT
 */

#include <pthread.h>
#include <assert.h>

#include <spa/pod/builder.h>
#include <icipc/icipc.h>

struct client_data {
  struct icipc_client *c;
  pthread_mutex_t mutex;
  pthread_cond_t cond;
  bool reply_received;
};

static void
reply_handler (struct icipc_sender *self, const uint8_t *buffer, size_t size, void *p)
{
  struct client_data *data = p;
  const char *error = NULL;

  if (buffer) {
    const struct spa_pod *pod = icipc_client_send_request_finish (self, buffer, size, &error);
    if (!pod)
      printf ("error: %s\n", error ? error : "unknown");
    else
      printf ("success!\n");
  } else {
    printf ("error: lost connection with server\n");
  }

  /* signal reply received */
  pthread_mutex_lock (&data->mutex);
  data->reply_received = true;
  pthread_cond_signal (&data->cond);
  pthread_mutex_unlock (&data->mutex);
}

int
main (int argc, char *argv[])
{
  struct client_data data;

  if (argc < 2) {
    printf ("usage: <server-path>\n");
    return -1;
  }

  /* init */
  data.c = icipc_client_new (argv[1], true);
  pthread_mutex_init (&data.mutex, NULL);
  pthread_cond_init (&data.cond, NULL);
  data.reply_received = false;

  while (true) {
    char str[1024];

    printf ("> ");
    fgets (str, 1023, stdin);

    if (strncmp (str, "help", 4) == 0) {
      printf ("help\tprints this message\n");
      printf ("quit\texits the client\n");
      printf ("send\tsends a request, usage: send <request-name> [args]\n");
    } else if (strncmp (str, "quit", 4) == 0) {
      printf ("exiting...\n");
      break;
    } else if (strncmp (str, "send", 4) == 0) {
      char request_name[128];
      char request_args[1024];
      int n = sscanf(str, "send %s %s", request_name, request_args);
      if (n <= 0)
        continue;

      /* send request */
      if (n >= 2) {
        /* TODO: for now we always create a string pod for args */
        struct {
          struct spa_pod_string pod;
          char str[1024];
        } args;
        args.pod = SPA_POD_INIT_String(1024);
        strncpy (args.str, request_args, 1024);
        icipc_client_send_request (data.c, request_name, (const struct spa_pod *)&args,
	    reply_handler, &data);
      } else {
        icipc_client_send_request (data.c, request_name, NULL, reply_handler, &data);
      }

      /* wait for reply */
      pthread_mutex_lock (&data.mutex);
      while (!data.reply_received)
        pthread_cond_wait (&data.cond, &data.mutex);
      pthread_mutex_unlock (&data.mutex);
    }
  }

  /* clean up */
  pthread_cond_destroy (&data.cond);
  pthread_mutex_destroy (&data.mutex);
  icipc_client_free (data.c);
  return 0;
}