Ubus
OpenWrt system message/RPC bus.
cli.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2011 Felix Fietkau <nbd@openwrt.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License version 2.1
6  * as published by the Free Software Foundation
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  */
13 
14 #include <unistd.h>
15 
16 #include <libubox/blobmsg_json.h>
17 #include "libubus.h"
18 
19 static struct blob_buf b;
20 static int listen_timeout;
21 static int timeout = 30;
22 static bool simple_output = false;
23 static int verbose = 0;
24 static int monitor_dir = -1;
25 static uint32_t monitor_mask;
26 static const char * const monitor_types[] = {
27  [UBUS_MSG_HELLO] = "hello",
28  [UBUS_MSG_STATUS] = "status",
29  [UBUS_MSG_DATA] = "data",
30  [UBUS_MSG_PING] = "ping",
31  [UBUS_MSG_LOOKUP] = "lookup",
32  [UBUS_MSG_INVOKE] = "invoke",
33  [UBUS_MSG_ADD_OBJECT] = "add_object",
34  [UBUS_MSG_REMOVE_OBJECT] = "remove_object",
35  [UBUS_MSG_SUBSCRIBE] = "subscribe",
36  [UBUS_MSG_UNSUBSCRIBE] = "unsubscribe",
37  [UBUS_MSG_NOTIFY] = "notify",
38 };
39 
40 static const char *format_type(void *priv, struct blob_attr *attr)
41 {
42  static const char * const attr_types[] = {
43  [BLOBMSG_TYPE_INT8] = "\"Boolean\"",
44  [BLOBMSG_TYPE_INT32] = "\"Integer\"",
45  [BLOBMSG_TYPE_STRING] = "\"String\"",
46  [BLOBMSG_TYPE_ARRAY] = "\"Array\"",
47  [BLOBMSG_TYPE_TABLE] = "\"Table\"",
48  };
49  const char *type = NULL;
50  size_t typeid;
51 
52  if (blob_id(attr) != BLOBMSG_TYPE_INT32)
53  return NULL;
54 
55  typeid = blobmsg_get_u32(attr);
56  if (typeid < ARRAY_SIZE(attr_types))
57  type = attr_types[typeid];
58  if (!type)
59  type = "\"(unknown)\"";
60 
61  return type;
62 }
63 
64 static void receive_list_result(struct ubus_context *ctx, struct ubus_object_data *obj, void *priv)
65 {
66  struct blob_attr *cur;
67  char *s;
68  size_t rem;
69 
70  if (simple_output || !verbose) {
71  printf("%s\n", obj->path);
72  return;
73  }
74 
75  printf("'%s' @%08x\n", obj->path, obj->id);
76 
77  if (!obj->signature)
78  return;
79 
80  blob_for_each_attr(cur, obj->signature, rem) {
81  s = blobmsg_format_json_with_cb(cur, false, format_type, NULL, -1);
82  printf("\t%s\n", s);
83  free(s);
84  }
85 }
86 
87 static void receive_call_result_data(struct ubus_request *req, int type, struct blob_attr *msg)
88 {
89  char *str;
90  if (!msg)
91  return;
92 
93  str = blobmsg_format_json_indent(msg, true, simple_output ? -1 : 0);
94  printf("%s\n", str);
95  free(str);
96 }
97 
98 static void print_event(const char *type, struct blob_attr *msg)
99 {
100  char *str;
101 
102  str = blobmsg_format_json(msg, true);
103  printf("{ \"%s\": %s }\n", type, str);
104  fflush(stdout);
105  free(str);
106 }
107 
108 static int receive_request(struct ubus_context *ctx, struct ubus_object *obj,
109  struct ubus_request_data *req,
110  const char *method, struct blob_attr *msg)
111 {
112  print_event(method, msg);
113  return 0;
114 }
115 
116 static void receive_event(struct ubus_context *ctx, struct ubus_event_handler *ev,
117  const char *type, struct blob_attr *msg)
118 {
119  print_event(type, msg);
120 }
121 
122 static int ubus_cli_error(char *cmd, int argc, char **argv, int err)
123 {
124  int i;
125 
126  if (!simple_output && !isatty(fileno(stderr))) {
127  fprintf(stderr, "Command failed: ubus %s ", cmd);
128  for (i = 0; i < argc; i++) {
129  fprintf(stderr, "%s ", argv[i]);
130  }
131  fprintf(stderr, "(%s)\n", ubus_strerror(err));
132 
133  return -err;
134  }
135 
136  return err;
137 }
138 
139 static int ubus_cli_list(struct ubus_context *ctx, int argc, char **argv)
140 {
141  const char *path = NULL;
142 
143  if (argc > 1)
144  return -2;
145 
146  if (argc == 1)
147  path = argv[0];
148 
149  return ubus_lookup(ctx, path, receive_list_result, NULL);
150 }
151 
152 static int ubus_cli_call(struct ubus_context *ctx, int argc, char **argv)
153 {
154  uint32_t id;
155  int ret;
156 
157  if (argc < 2 || argc > 3)
158  return -2;
159 
160  blob_buf_init(&b, 0);
161  if (argc == 3 && !blobmsg_add_json_from_string(&b, argv[2])) {
162  return ubus_cli_error("call", argc, argv, UBUS_STATUS_PARSE_ERROR);
163  }
164 
165  ret = ubus_lookup_id(ctx, argv[0], &id);
166  if (ret)
167  return ret;
168 
169  ret = ubus_invoke(ctx, id, argv[1], b.head, receive_call_result_data, NULL, timeout * 1000);
170  if (ret)
171  return ubus_cli_error("call", argc, argv, ret);
172 
173  return ret;
174 }
175 
177  struct uloop_timeout timeout;
178  bool timed_out;
179 };
180 
181 static void ubus_cli_listen_timeout(struct uloop_timeout *timeout)
182 {
183  struct cli_listen_data *data = container_of(timeout, struct cli_listen_data, timeout);
184  data->timed_out = true;
185  uloop_end();
186 }
187 
188 static void do_listen(struct ubus_context *ctx, struct cli_listen_data *data)
189 {
190  memset(data, 0, sizeof(*data));
191  data->timeout.cb = ubus_cli_listen_timeout;
192  uloop_init();
194  if (listen_timeout)
195  uloop_timeout_set(&data->timeout, listen_timeout * 1000);
196  uloop_run();
197  uloop_done();
198 }
199 
200 static int ubus_cli_listen(struct ubus_context *ctx, int argc, char **argv)
201 {
202  struct ubus_event_handler ev = {
203  .cb = receive_event,
204  };
205  struct cli_listen_data data;
206  const char *event;
207  int ret = 0;
208 
209  if (argc > 0) {
210  event = argv[0];
211  } else {
212  event = "*";
213  argc = 1;
214  }
215 
216  do {
217  ret = ubus_register_event_handler(ctx, &ev, event);
218  if (ret)
219  break;
220 
221  argv++;
222  argc--;
223  if (argc <= 0)
224  break;
225 
226  event = argv[0];
227  } while (1);
228 
229  if (ret) {
230  if (!simple_output)
231  fprintf(stderr, "Error while registering for event '%s': %s\n",
232  event, ubus_strerror(ret));
233  return -1;
234  }
235 
236  do_listen(ctx, &data);
237 
238  return 0;
239 }
240 
241 static int ubus_cli_subscribe(struct ubus_context *ctx, int argc, char **argv)
242 {
243  struct ubus_subscriber sub = {
244  .cb = receive_request,
245  };
246  struct cli_listen_data data;
247  const char *event;
248  int ret = 0;
249 
250  if (argc > 0) {
251  event = argv[0];
252  } else {
253  if (!simple_output)
254  fprintf(stderr, "You need to specify an object to subscribe to\n");
255  return -1;
256  }
257 
258  ret = ubus_register_subscriber(ctx, &sub);
259  for (; !ret && argc > 0; argc--, argv++) {
260  uint32_t id;
261 
262  ret = ubus_lookup_id(ctx, argv[0], &id);
263  if (ret)
264  break;
265 
266  ret = ubus_subscribe(ctx, &sub, id);
267  }
268 
269  if (ret) {
270  if (!simple_output)
271  fprintf(stderr, "Error while registering for event '%s': %s\n",
272  event, ubus_strerror(ret));
273  return -1;
274  }
275 
276  do_listen(ctx, &data);
277 
278  return 0;
279 }
280 
281 
282 static int ubus_cli_send(struct ubus_context *ctx, int argc, char **argv)
283 {
284  if (argc < 1 || argc > 2)
285  return -2;
286 
287  blob_buf_init(&b, 0);
288 
289  if (argc == 2 && !blobmsg_add_json_from_string(&b, argv[1])) {
291  }
292 
293  return ubus_send_event(ctx, argv[0], b.head);
294 }
295 
297  struct uloop_timeout timeout;
298  struct ubus_event_handler ev;
299  char **pending;
301 };
302 
303 static void wait_check_object(struct cli_wait_data *data, const char *path)
304 {
305  int i;
306 
307  for (i = 0; i < data->n_pending; i++) {
308  if (strcmp(path, data->pending[i]) != 0)
309  continue;
310 
311  data->n_pending--;
312  if (i == data->n_pending)
313  break;
314 
315  memmove(&data->pending[i], &data->pending[i + 1],
316  (data->n_pending - i) * sizeof(*data->pending));
317  i--;
318  }
319 
320  if (!data->n_pending)
321  uloop_end();
322 }
323 
324 static void wait_event_cb(struct ubus_context *ctx, struct ubus_event_handler *ev,
325  const char *type, struct blob_attr *msg)
326 {
327  static const struct blobmsg_policy policy = {
328  "path", BLOBMSG_TYPE_STRING
329  };
330  struct cli_wait_data *data = container_of(ev, struct cli_wait_data, ev);
331  struct blob_attr *attr;
332  const char *path;
333 
334  if (strcmp(type, "ubus.object.add") != 0)
335  return;
336 
337  blobmsg_parse(&policy, 1, &attr, blob_data(msg), blob_len(msg));
338  if (!attr)
339  return;
340 
341  path = blobmsg_data(attr);
342  wait_check_object(data, path);
343 }
344 
345 static void wait_list_cb(struct ubus_context *ctx, struct ubus_object_data *obj, void *priv)
346 {
347  struct cli_wait_data *data = priv;
348 
349  wait_check_object(data, obj->path);
350 }
351 
352 
353 static void wait_timeout(struct uloop_timeout *timeout)
354 {
355  uloop_end();
356 }
357 
358 static int ubus_cli_wait_for(struct ubus_context *ctx, int argc, char **argv)
359 {
360  struct cli_wait_data data = {
361  .timeout.cb = wait_timeout,
362  .ev.cb = wait_event_cb,
363  .pending = argv,
364  .n_pending = argc,
365  };
366  int ret;
367 
368  if (argc < 1)
369  return -2;
370 
371  uloop_init();
373 
374  ret = ubus_register_event_handler(ctx, &data.ev, "ubus.object.add");
375  if (ret)
376  return ret;
377 
378  if (!data.n_pending)
379  return ret;
380 
381  ret = ubus_lookup(ctx, NULL, wait_list_cb, &data);
382  if (ret)
383  return ret;
384 
385  if (!data.n_pending)
386  return ret;
387 
388  uloop_timeout_set(&data.timeout, timeout * 1000);
389  uloop_run();
390  uloop_done();
391 
392  if (data.n_pending)
393  return UBUS_STATUS_TIMEOUT;
394 
395  return ret;
396 }
397 
398 static const char *
400 {
401  const char *ret = NULL;
402  static char unk_type[16];
403 
404 
405  if (type < ARRAY_SIZE(monitor_types))
406  ret = monitor_types[type];
407 
408  if (!ret) {
409  snprintf(unk_type, sizeof(unk_type), "%d", type);
410  ret = unk_type;
411  }
412 
413  return ret;
414 }
415 
416 static char *
417 ubus_cli_get_monitor_data(struct blob_attr *data)
418 {
419  static const struct blob_attr_info policy[UBUS_ATTR_MAX] = {
420  [UBUS_ATTR_STATUS] = { .type = BLOB_ATTR_INT32 },
421  [UBUS_ATTR_OBJPATH] = { .type = BLOB_ATTR_STRING },
422  [UBUS_ATTR_OBJID] = { .type = BLOB_ATTR_INT32 },
423  [UBUS_ATTR_METHOD] = { .type = BLOB_ATTR_STRING },
424  [UBUS_ATTR_OBJTYPE] = { .type = BLOB_ATTR_INT32 },
425  [UBUS_ATTR_SIGNATURE] = { .type = BLOB_ATTR_NESTED },
426  [UBUS_ATTR_DATA] = { .type = BLOB_ATTR_NESTED },
427  [UBUS_ATTR_ACTIVE] = { .type = BLOB_ATTR_INT8 },
428  [UBUS_ATTR_NO_REPLY] = { .type = BLOB_ATTR_INT8 },
429  [UBUS_ATTR_USER] = { .type = BLOB_ATTR_STRING },
430  [UBUS_ATTR_GROUP] = { .type = BLOB_ATTR_STRING },
431  };
432  static const char * const names[UBUS_ATTR_MAX] = {
433  [UBUS_ATTR_STATUS] = "status",
434  [UBUS_ATTR_OBJPATH] = "objpath",
435  [UBUS_ATTR_OBJID] = "objid",
436  [UBUS_ATTR_METHOD] = "method",
437  [UBUS_ATTR_OBJTYPE] = "objtype",
438  [UBUS_ATTR_SIGNATURE] = "signature",
439  [UBUS_ATTR_DATA] = "data",
440  [UBUS_ATTR_ACTIVE] = "active",
441  [UBUS_ATTR_NO_REPLY] = "no_reply",
442  [UBUS_ATTR_USER] = "user",
443  [UBUS_ATTR_GROUP] = "group",
444  };
445  struct blob_attr *tb[UBUS_ATTR_MAX];
446  int i;
447 
448  blob_buf_init(&b, 0);
449  blob_parse(data, tb, policy, UBUS_ATTR_MAX);
450 
451  for (i = 0; i < UBUS_ATTR_MAX; i++) {
452  const char *n = names[i];
453  struct blob_attr *v = tb[i];
454 
455  if (!tb[i] || !n)
456  continue;
457 
458  switch(policy[i].type) {
459  case BLOB_ATTR_INT32:
460  blobmsg_add_u32(&b, n, blob_get_int32(v));
461  break;
462  case BLOB_ATTR_STRING:
463  blobmsg_add_string(&b, n, blob_data(v));
464  break;
465  case BLOB_ATTR_INT8:
466  blobmsg_add_u8(&b, n, !!blob_get_int8(v));
467  break;
468  case BLOB_ATTR_NESTED:
469  blobmsg_add_field(&b, BLOBMSG_TYPE_TABLE, n, blobmsg_data(v), blobmsg_data_len(v));
470  break;
471  }
472  }
473 
474  return blobmsg_format_json(b.head, true);
475 }
476 
477 static void
478 ubus_cli_monitor_cb(struct ubus_context *ctx, uint32_t seq, struct blob_attr *msg)
479 {
480  static const struct blob_attr_info policy[UBUS_MONITOR_MAX] = {
481  [UBUS_MONITOR_CLIENT] = { .type = BLOB_ATTR_INT32 },
482  [UBUS_MONITOR_PEER] = { .type = BLOB_ATTR_INT32 },
483  [UBUS_MONITOR_SEND] = { .type = BLOB_ATTR_INT8 },
484  [UBUS_MONITOR_TYPE] = { .type = BLOB_ATTR_INT32 },
485  [UBUS_MONITOR_DATA] = { .type = BLOB_ATTR_NESTED },
486  };
487  struct blob_attr *tb[UBUS_MONITOR_MAX];
488  uint32_t client, peer, type;
489  bool send;
490  char *data;
491 
492  blob_parse_untrusted(msg, blob_raw_len(msg), tb, policy, UBUS_MONITOR_MAX);
493 
494  if (!tb[UBUS_MONITOR_CLIENT] ||
495  !tb[UBUS_MONITOR_PEER] ||
496  !tb[UBUS_MONITOR_SEND] ||
497  !tb[UBUS_MONITOR_TYPE] ||
498  !tb[UBUS_MONITOR_DATA]) {
499  printf("Invalid monitor msg\n");
500  return;
501  }
502 
503  send = blob_get_int32(tb[UBUS_MONITOR_SEND]);
504  client = blob_get_int32(tb[UBUS_MONITOR_CLIENT]);
505  peer = blob_get_int32(tb[UBUS_MONITOR_PEER]);
506  type = blob_get_int32(tb[UBUS_MONITOR_TYPE]);
507 
508  if (monitor_mask && type < 32 && !(monitor_mask & (1 << type)))
509  return;
510 
511  if (monitor_dir >= 0 && send != monitor_dir)
512  return;
513 
515  printf("%s %08x #%08x %14s: %s\n", send ? "->" : "<-", client, peer, ubus_cli_msg_type(type), data);
516  free(data);
517  fflush(stdout);
518 }
519 
520 static int ubus_cli_monitor(struct ubus_context *ctx, int argc, char **argv)
521 {
522  int ret;
523 
524  uloop_init();
527  ret = ubus_monitor_start(ctx);
528  if (ret)
529  return ret;
530 
531  uloop_run();
532  uloop_done();
533 
535  return 0;
536 }
537 
538 static int add_monitor_type(const char *type)
539 {
540  size_t i;
541 
542  for (i = 0; i < ARRAY_SIZE(monitor_types); i++) {
543  if (!monitor_types[i] || strcmp(monitor_types[i], type) != 0)
544  continue;
545 
546  monitor_mask |= 1 << i;
547  return 0;
548  }
549 
550  return -1;
551 }
552 
553 static int usage(const char *prog)
554 {
555  fprintf(stderr,
556  "Usage: %s [<options>] <command> [arguments...]\n"
557  "Options:\n"
558  " -s <socket>: Set the unix domain socket to connect to\n"
559  " -t <timeout>: Set the timeout (in seconds) for a command to complete\n"
560  " -S: Use simplified output (for scripts)\n"
561  " -v: More verbose output\n"
562  " -m <type>: (for monitor): include a specific message type\n"
563  " (can be used more than once)\n"
564  " -M <r|t> (for monitor): only capture received or transmitted traffic\n"
565  "\n"
566  "Commands:\n"
567  " - list [<path>] List objects\n"
568  " - call <path> <method> [<message>] Call an object method\n"
569  " - subscribe <path> [<path>...] Subscribe to object(s) notifications\n"
570  " - listen [<path>...] Listen for events\n"
571  " - send <type> [<message>] Send an event\n"
572  " - wait_for <object> [<object>...] Wait for multiple objects to appear on ubus\n"
573  " - monitor Monitor ubus traffic\n"
574  "\n", prog);
575  return 1;
576 }
577 
578 
579 static struct {
580  const char *name;
581  int (*cb)(struct ubus_context *ctx, int argc, char **argv);
582 } commands[] = {
583  { "list", ubus_cli_list },
584  { "call", ubus_cli_call },
585  { "listen", ubus_cli_listen },
586  { "subscribe", ubus_cli_subscribe },
587  { "send", ubus_cli_send },
588  { "wait_for", ubus_cli_wait_for },
589  { "monitor", ubus_cli_monitor },
590 };
591 
592 int main(int argc, char **argv)
593 {
594  const char *progname, *ubus_socket = NULL;
595  struct ubus_context *ctx;
596  int ret = 0;
597  char *cmd;
598  size_t i;
599  int ch;
600 
601  progname = argv[0];
602 
603  while ((ch = getopt(argc, argv, "m:M:vs:t:S")) != -1) {
604  switch (ch) {
605  case 's':
606  ubus_socket = optarg;
607  break;
608  case 't':
609  listen_timeout = atoi(optarg);
610  timeout = atoi(optarg);
611  break;
612  case 'S':
613  simple_output = true;
614  break;
615  case 'v':
616  verbose++;
617  break;
618  case 'm':
619  if (add_monitor_type(optarg))
620  return usage(progname);
621  break;
622  case 'M':
623  switch (optarg[0]) {
624  case 'r':
625  monitor_dir = 0;
626  break;
627  case 't':
628  monitor_dir = 1;
629  break;
630  default:
631  return usage(progname);
632  }
633  break;
634  default:
635  return usage(progname);
636  }
637  }
638 
639  argc -= optind;
640  argv += optind;
641 
642  cmd = argv[0];
643  if (argc < 1)
644  return usage(progname);
645 
646  ctx = ubus_connect(ubus_socket);
647  if (!ctx) {
648  if (!simple_output)
649  fprintf(stderr, "Failed to connect to ubus\n");
650  return -1;
651  }
652 
653  argv++;
654  argc--;
655 
656  ret = -2;
657  for (i = 0; i < ARRAY_SIZE(commands); i++) {
658  if (strcmp(commands[i].name, cmd) != 0)
659  continue;
660 
661  ret = commands[i].cb(ctx, argc, argv);
662  break;
663  }
664 
665  if (ret > 0 && !simple_output)
666  fprintf(stderr, "Command failed: %s\n", ubus_strerror(ret));
667  else if (ret == -2)
668  usage(progname);
669 
670  ubus_free(ctx);
671  return ret;
672 }
static int ubus_cli_wait_for(struct ubus_context *ctx, int argc, char **argv)
Definition: cli.c:358
static int verbose
Definition: cli.c:23
static int ubus_cli_error(char *cmd, int argc, char **argv, int err)
Definition: cli.c:122
static int receive_request(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg)
Definition: cli.c:108
static int ubus_cli_listen(struct ubus_context *ctx, int argc, char **argv)
Definition: cli.c:200
static int monitor_dir
Definition: cli.c:24
int main(int argc, char **argv)
Definition: cli.c:592
static int timeout
Definition: cli.c:21
static int ubus_cli_subscribe(struct ubus_context *ctx, int argc, char **argv)
Definition: cli.c:241
static void wait_list_cb(struct ubus_context *ctx, struct ubus_object_data *obj, void *priv)
Definition: cli.c:345
static int ubus_cli_send(struct ubus_context *ctx, int argc, char **argv)
Definition: cli.c:282
static void wait_check_object(struct cli_wait_data *data, const char *path)
Definition: cli.c:303
static bool simple_output
Definition: cli.c:22
static void receive_list_result(struct ubus_context *ctx, struct ubus_object_data *obj, void *priv)
Definition: cli.c:64
static void receive_call_result_data(struct ubus_request *req, int type, struct blob_attr *msg)
Definition: cli.c:87
static struct @0 commands[]
static int add_monitor_type(const char *type)
Definition: cli.c:538
static const char *const monitor_types[]
Definition: cli.c:26
static struct blob_buf b
Definition: cli.c:19
const char * name
Definition: cli.c:580
static int ubus_cli_call(struct ubus_context *ctx, int argc, char **argv)
Definition: cli.c:152
static void receive_event(struct ubus_context *ctx, struct ubus_event_handler *ev, const char *type, struct blob_attr *msg)
Definition: cli.c:116
static void ubus_cli_monitor_cb(struct ubus_context *ctx, uint32_t seq, struct blob_attr *msg)
Definition: cli.c:478
static int ubus_cli_list(struct ubus_context *ctx, int argc, char **argv)
Definition: cli.c:139
static int ubus_cli_monitor(struct ubus_context *ctx, int argc, char **argv)
Definition: cli.c:520
static const char * format_type(void *priv, struct blob_attr *attr)
Definition: cli.c:40
static void ubus_cli_listen_timeout(struct uloop_timeout *timeout)
Definition: cli.c:181
static const char * ubus_cli_msg_type(uint32_t type)
Definition: cli.c:399
static uint32_t monitor_mask
Definition: cli.c:25
static char * ubus_cli_get_monitor_data(struct blob_attr *data)
Definition: cli.c:417
int(* cb)(struct ubus_context *ctx, int argc, char **argv)
Definition: cli.c:581
static void print_event(const char *type, struct blob_attr *msg)
Definition: cli.c:98
static int listen_timeout
Definition: cli.c:20
static int usage(const char *prog)
Definition: cli.c:553
static void wait_timeout(struct uloop_timeout *timeout)
Definition: cli.c:353
static void do_listen(struct ubus_context *ctx, struct cli_listen_data *data)
Definition: cli.c:188
static void wait_event_cb(struct ubus_context *ctx, struct ubus_event_handler *ev, const char *type, struct blob_attr *msg)
Definition: cli.c:324
static struct ubus_context * ctx
Definition: client.c:22
int ubus_subscribe(struct ubus_context *ctx, struct ubus_subscriber *obj, uint32_t id)
Definition: libubus-sub.c:118
int ubus_register_subscriber(struct ubus_context *ctx, struct ubus_subscriber *s)
Definition: libubus-sub.c:77
struct ubus_context * ubus_connect(const char *path)
Definition: libubus.c:351
int ubus_lookup(struct ubus_context *ctx, const char *path, ubus_lookup_handler_t cb, void *priv)
Definition: libubus.c:161
int ubus_send_event(struct ubus_context *ctx, const char *id, struct blob_attr *data)
Definition: libubus.c:258
void ubus_free(struct ubus_context *ctx)
Definition: libubus.c:378
int ubus_lookup_id(struct ubus_context *ctx, const char *path, uint32_t *id)
Definition: libubus.c:192
const char * ubus_strerror(int error)
Definition: libubus.c:59
int ubus_register_event_handler(struct ubus_context *ctx, struct ubus_event_handler *ev, const char *pattern)
Definition: libubus.c:225
static int ubus_monitor_start(struct ubus_context *ctx)
Definition: libubus.h:321
static void ubus_add_uloop(struct ubus_context *ctx)
Definition: libubus.h:268
static int ubus_monitor_stop(struct ubus_context *ctx)
Definition: libubus.h:326
static int ubus_invoke(struct ubus_context *ctx, uint32_t obj, const char *method, struct blob_attr *msg, ubus_data_handler_t cb, void *priv, int timeout)
Definition: libubus.h:354
struct uloop_timeout timeout
Definition: cli.c:177
bool timed_out
Definition: cli.c:178
struct ubus_event_handler ev
Definition: cli.c:298
char ** pending
Definition: cli.c:299
struct uloop_timeout timeout
Definition: cli.c:297
int n_pending
Definition: cli.c:300
void(* monitor_cb)(struct ubus_context *ctx, uint32_t seq, struct blob_attr *data)
Definition: libubus.h:171
ubus_event_handler_t cb
Definition: libubus.h:154
uint32_t id
Definition: libubus.h:182
struct blob_attr * signature
Definition: libubus.h:185
const char * path
Definition: libubus.h:184
ubus_handler_t cb
Definition: libubus.h:146
struct avl_tree path
Definition: ubusd_obj.c:19
uint16_t seq
Definition: ubusmsg.h:2
uint8_t type
Definition: ubusmsg.h:1
uint32_t peer
Definition: ubusmsg.h:3
@ UBUS_MSG_INVOKE
Definition: ubusmsg.h:53
@ UBUS_MSG_DATA
Definition: ubusmsg.h:44
@ UBUS_MSG_REMOVE_OBJECT
Definition: ubusmsg.h:56
@ UBUS_MSG_STATUS
Definition: ubusmsg.h:41
@ UBUS_MSG_PING
Definition: ubusmsg.h:47
@ UBUS_MSG_ADD_OBJECT
Definition: ubusmsg.h:55
@ UBUS_MSG_LOOKUP
Definition: ubusmsg.h:50
@ UBUS_MSG_NOTIFY
Definition: ubusmsg.h:71
@ UBUS_MSG_HELLO
Definition: ubusmsg.h:38
@ UBUS_MSG_SUBSCRIBE
Definition: ubusmsg.h:63
@ UBUS_MSG_UNSUBSCRIBE
Definition: ubusmsg.h:64
@ UBUS_STATUS_TIMEOUT
Definition: ubusmsg.h:126
@ UBUS_STATUS_PARSE_ERROR
Definition: ubusmsg.h:131
@ UBUS_MONITOR_DATA
Definition: ubusmsg.h:112
@ UBUS_MONITOR_CLIENT
Definition: ubusmsg.h:107
@ UBUS_MONITOR_SEND
Definition: ubusmsg.h:109
@ UBUS_MONITOR_MAX
Definition: ubusmsg.h:115
@ UBUS_MONITOR_PEER
Definition: ubusmsg.h:108
@ UBUS_MONITOR_TYPE
Definition: ubusmsg.h:111
@ UBUS_ATTR_OBJTYPE
Definition: ubusmsg.h:88
@ UBUS_ATTR_ACTIVE
Definition: ubusmsg.h:94
@ UBUS_ATTR_OBJPATH
Definition: ubusmsg.h:84
@ UBUS_ATTR_METHOD
Definition: ubusmsg.h:86
@ UBUS_ATTR_STATUS
Definition: ubusmsg.h:82
@ UBUS_ATTR_NO_REPLY
Definition: ubusmsg.h:95
@ UBUS_ATTR_OBJID
Definition: ubusmsg.h:85
@ UBUS_ATTR_SIGNATURE
Definition: ubusmsg.h:89
@ UBUS_ATTR_GROUP
Definition: ubusmsg.h:100
@ UBUS_ATTR_DATA
Definition: ubusmsg.h:91
@ UBUS_ATTR_USER
Definition: ubusmsg.h:99
@ UBUS_ATTR_MAX
Definition: ubusmsg.h:103