Ubus
OpenWrt system message/RPC bus.
cli.c File Reference
#include <unistd.h>
#include <libubox/blobmsg_json.h>
#include "libubus.h"

Go to the source code of this file.

Data Structures

struct  cli_listen_data
 
struct  cli_wait_data
 

Functions

static const char * format_type (void *priv, struct blob_attr *attr)
 
static void receive_list_result (struct ubus_context *ctx, struct ubus_object_data *obj, void *priv)
 
static void receive_call_result_data (struct ubus_request *req, int type, struct blob_attr *msg)
 
static void print_event (const char *type, struct blob_attr *msg)
 
static int receive_request (struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg)
 
static void receive_event (struct ubus_context *ctx, struct ubus_event_handler *ev, const char *type, struct blob_attr *msg)
 
static int ubus_cli_error (char *cmd, int argc, char **argv, int err)
 
static int ubus_cli_list (struct ubus_context *ctx, int argc, char **argv)
 
static int ubus_cli_call (struct ubus_context *ctx, int argc, char **argv)
 
static void ubus_cli_listen_timeout (struct uloop_timeout *timeout)
 
static void do_listen (struct ubus_context *ctx, struct cli_listen_data *data)
 
static int ubus_cli_listen (struct ubus_context *ctx, int argc, char **argv)
 
static int ubus_cli_subscribe (struct ubus_context *ctx, int argc, char **argv)
 
static int ubus_cli_send (struct ubus_context *ctx, int argc, char **argv)
 
static void wait_check_object (struct cli_wait_data *data, const char *path)
 
static void wait_event_cb (struct ubus_context *ctx, struct ubus_event_handler *ev, const char *type, struct blob_attr *msg)
 
static void wait_list_cb (struct ubus_context *ctx, struct ubus_object_data *obj, void *priv)
 
static void wait_timeout (struct uloop_timeout *timeout)
 
static int ubus_cli_wait_for (struct ubus_context *ctx, int argc, char **argv)
 
static const char * ubus_cli_msg_type (uint32_t type)
 
static char * ubus_cli_get_monitor_data (struct blob_attr *data)
 
static void ubus_cli_monitor_cb (struct ubus_context *ctx, uint32_t seq, struct blob_attr *msg)
 
static int ubus_cli_monitor (struct ubus_context *ctx, int argc, char **argv)
 
static int add_monitor_type (const char *type)
 
static int usage (const char *prog)
 
int main (int argc, char **argv)
 

Variables

static struct blob_buf b
 
static int listen_timeout
 
static int timeout = 30
 
static bool simple_output = false
 
static int verbose = 0
 
static int monitor_dir = -1
 
static uint32_t monitor_mask
 
static const char *const monitor_types []
 
struct {
   const char *   name
 
   int(*   cb )(struct ubus_context *ctx,
      int argc, char **argv)
 
commands []
 

Function Documentation

◆ add_monitor_type()

static int add_monitor_type ( const char *  type)
static

Definition at line 538 of file cli.c.

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 }
static const char *const monitor_types[]
Definition: cli.c:26
static uint32_t monitor_mask
Definition: cli.c:25
uint8_t type
Definition: ubusmsg.h:1

◆ do_listen()

static void do_listen ( struct ubus_context ctx,
struct cli_listen_data data 
)
static

Definition at line 188 of file cli.c.

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 }
static void ubus_cli_listen_timeout(struct uloop_timeout *timeout)
Definition: cli.c:181
static int listen_timeout
Definition: cli.c:20
static struct ubus_context * ctx
Definition: client.c:22
static void ubus_add_uloop(struct ubus_context *ctx)
Definition: libubus.h:268
struct uloop_timeout timeout
Definition: cli.c:177
Here is the call graph for this function:
Here is the caller graph for this function:

◆ format_type()

static const char* format_type ( void *  priv,
struct blob_attr *  attr 
)
static

Definition at line 40 of file cli.c.

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 }
Here is the caller graph for this function:

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 592 of file cli.c.

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 verbose
Definition: cli.c:23
static int monitor_dir
Definition: cli.c:24
static int timeout
Definition: cli.c:21
static bool simple_output
Definition: cli.c:22
static struct @0 commands[]
static int add_monitor_type(const char *type)
Definition: cli.c:538
const char * name
Definition: cli.c:580
static int usage(const char *prog)
Definition: cli.c:553
struct ubus_context * ubus_connect(const char *path)
Definition: libubus.c:351
void ubus_free(struct ubus_context *ctx)
Definition: libubus.c:378
const char * ubus_strerror(int error)
Definition: libubus.c:59

◆ print_event()

static void print_event ( const char *  type,
struct blob_attr *  msg 
)
static

Definition at line 98 of file cli.c.

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 }
Here is the caller graph for this function:

◆ receive_call_result_data()

static void receive_call_result_data ( struct ubus_request req,
int  type,
struct blob_attr *  msg 
)
static

Definition at line 87 of file cli.c.

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 }
Here is the caller graph for this function:

◆ receive_event()

static void receive_event ( struct ubus_context ctx,
struct ubus_event_handler ev,
const char *  type,
struct blob_attr *  msg 
)
static

Definition at line 116 of file cli.c.

118 {
119  print_event(type, msg);
120 }
static void print_event(const char *type, struct blob_attr *msg)
Definition: cli.c:98
Here is the call graph for this function:
Here is the caller graph for this function:

◆ receive_list_result()

static void receive_list_result ( struct ubus_context ctx,
struct ubus_object_data obj,
void *  priv 
)
static

Definition at line 64 of file cli.c.

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 }
static const char * format_type(void *priv, struct blob_attr *attr)
Definition: cli.c:40
uint32_t id
Definition: libubus.h:182
struct blob_attr * signature
Definition: libubus.h:185
const char * path
Definition: libubus.h:184
Here is the call graph for this function:
Here is the caller graph for this function:

◆ receive_request()

static int receive_request ( struct ubus_context ctx,
struct ubus_object obj,
struct ubus_request_data req,
const char *  method,
struct blob_attr *  msg 
)
static

Definition at line 108 of file cli.c.

111 {
112  print_event(method, msg);
113  return 0;
114 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ubus_cli_call()

static int ubus_cli_call ( struct ubus_context ctx,
int  argc,
char **  argv 
)
static

Definition at line 152 of file cli.c.

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 }
static int ubus_cli_error(char *cmd, int argc, char **argv, int err)
Definition: cli.c:122
static void receive_call_result_data(struct ubus_request *req, int type, struct blob_attr *msg)
Definition: cli.c:87
static struct blob_buf b
Definition: cli.c:19
int ubus_lookup_id(struct ubus_context *ctx, const char *path, uint32_t *id)
Definition: libubus.c:192
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
@ UBUS_STATUS_PARSE_ERROR
Definition: ubusmsg.h:131
Here is the call graph for this function:

◆ ubus_cli_error()

static int ubus_cli_error ( char *  cmd,
int  argc,
char **  argv,
int  err 
)
static

Definition at line 122 of file cli.c.

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 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ubus_cli_get_monitor_data()

static char* ubus_cli_get_monitor_data ( struct blob_attr *  data)
static

Definition at line 417 of file cli.c.

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 }
@ 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
Here is the caller graph for this function:

◆ ubus_cli_list()

static int ubus_cli_list ( struct ubus_context ctx,
int  argc,
char **  argv 
)
static

Definition at line 139 of file cli.c.

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 }
static void receive_list_result(struct ubus_context *ctx, struct ubus_object_data *obj, void *priv)
Definition: cli.c:64
int ubus_lookup(struct ubus_context *ctx, const char *path, ubus_lookup_handler_t cb, void *priv)
Definition: libubus.c:161
struct avl_tree path
Definition: ubusd_obj.c:19
Here is the call graph for this function:

◆ ubus_cli_listen()

static int ubus_cli_listen ( struct ubus_context ctx,
int  argc,
char **  argv 
)
static

Definition at line 200 of file cli.c.

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 }
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 do_listen(struct ubus_context *ctx, struct cli_listen_data *data)
Definition: cli.c:188
int ubus_register_event_handler(struct ubus_context *ctx, struct ubus_event_handler *ev, const char *pattern)
Definition: libubus.c:225
ubus_event_handler_t cb
Definition: libubus.h:154
Here is the call graph for this function:

◆ ubus_cli_listen_timeout()

static void ubus_cli_listen_timeout ( struct uloop_timeout *  timeout)
static

Definition at line 181 of file cli.c.

182 {
183  struct cli_listen_data *data = container_of(timeout, struct cli_listen_data, timeout);
184  data->timed_out = true;
185  uloop_end();
186 }
bool timed_out
Definition: cli.c:178
Here is the caller graph for this function:

◆ ubus_cli_monitor()

static int ubus_cli_monitor ( struct ubus_context ctx,
int  argc,
char **  argv 
)
static

Definition at line 520 of file cli.c.

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 }
static void ubus_cli_monitor_cb(struct ubus_context *ctx, uint32_t seq, struct blob_attr *msg)
Definition: cli.c:478
static int ubus_monitor_start(struct ubus_context *ctx)
Definition: libubus.h:321
static int ubus_monitor_stop(struct ubus_context *ctx)
Definition: libubus.h:326
void(* monitor_cb)(struct ubus_context *ctx, uint32_t seq, struct blob_attr *data)
Definition: libubus.h:171
Here is the call graph for this function:

◆ ubus_cli_monitor_cb()

static void ubus_cli_monitor_cb ( struct ubus_context ctx,
uint32_t  seq,
struct blob_attr *  msg 
)
static

Definition at line 478 of file cli.c.

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 }
static const char * ubus_cli_msg_type(uint32_t type)
Definition: cli.c:399
static char * ubus_cli_get_monitor_data(struct blob_attr *data)
Definition: cli.c:417
uint32_t peer
Definition: ubusmsg.h:3
@ 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
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ubus_cli_msg_type()

static const char* ubus_cli_msg_type ( uint32_t  type)
static

Definition at line 399 of file cli.c.

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 }
Here is the caller graph for this function:

◆ ubus_cli_send()

static int ubus_cli_send ( struct ubus_context ctx,
int  argc,
char **  argv 
)
static

Definition at line 282 of file cli.c.

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 }
int ubus_send_event(struct ubus_context *ctx, const char *id, struct blob_attr *data)
Definition: libubus.c:258
Here is the call graph for this function:

◆ ubus_cli_subscribe()

static int ubus_cli_subscribe ( struct ubus_context ctx,
int  argc,
char **  argv 
)
static

Definition at line 241 of file cli.c.

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 }
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
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
ubus_handler_t cb
Definition: libubus.h:146
Here is the call graph for this function:

◆ ubus_cli_wait_for()

static int ubus_cli_wait_for ( struct ubus_context ctx,
int  argc,
char **  argv 
)
static

Definition at line 358 of file cli.c.

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 }
static void wait_list_cb(struct ubus_context *ctx, struct ubus_object_data *obj, void *priv)
Definition: cli.c:345
static void wait_timeout(struct uloop_timeout *timeout)
Definition: cli.c:353
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
struct ubus_event_handler ev
Definition: cli.c:298
struct uloop_timeout timeout
Definition: cli.c:297
int n_pending
Definition: cli.c:300
@ UBUS_STATUS_TIMEOUT
Definition: ubusmsg.h:126
Here is the call graph for this function:

◆ usage()

static int usage ( const char *  prog)
static

Definition at line 553 of file cli.c.

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 }

◆ wait_check_object()

static void wait_check_object ( struct cli_wait_data data,
const char *  path 
)
static

Definition at line 303 of file cli.c.

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 }
char ** pending
Definition: cli.c:299
Here is the caller graph for this function:

◆ wait_event_cb()

static void wait_event_cb ( struct ubus_context ctx,
struct ubus_event_handler ev,
const char *  type,
struct blob_attr *  msg 
)
static

Definition at line 324 of file cli.c.

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 }
static void wait_check_object(struct cli_wait_data *data, const char *path)
Definition: cli.c:303
Here is the call graph for this function:
Here is the caller graph for this function:

◆ wait_list_cb()

static void wait_list_cb ( struct ubus_context ctx,
struct ubus_object_data obj,
void *  priv 
)
static

Definition at line 345 of file cli.c.

346 {
347  struct cli_wait_data *data = priv;
348 
349  wait_check_object(data, obj->path);
350 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ wait_timeout()

static void wait_timeout ( struct uloop_timeout *  timeout)
static

Definition at line 353 of file cli.c.

354 {
355  uloop_end();
356 }
Here is the caller graph for this function:

Variable Documentation

◆ b

struct blob_buf b
static

Definition at line 1 of file cli.c.

◆ cb

int(* cb) (struct ubus_context *ctx, int argc, char **argv) ( struct ubus_context ctx,
int  argc,
char **  argv 
)

Definition at line 581 of file cli.c.

◆ 

struct { ... } commands[]
Initial value:
= {
{ "list", ubus_cli_list },
{ "call", ubus_cli_call },
{ "listen", ubus_cli_listen },
{ "subscribe", ubus_cli_subscribe },
{ "send", ubus_cli_send },
{ "wait_for", ubus_cli_wait_for },
{ "monitor", ubus_cli_monitor },
}
static int ubus_cli_wait_for(struct ubus_context *ctx, int argc, char **argv)
Definition: cli.c:358
static int ubus_cli_listen(struct ubus_context *ctx, int argc, char **argv)
Definition: cli.c:200
static int ubus_cli_subscribe(struct ubus_context *ctx, int argc, char **argv)
Definition: cli.c:241
static int ubus_cli_send(struct ubus_context *ctx, int argc, char **argv)
Definition: cli.c:282
static int ubus_cli_call(struct ubus_context *ctx, int argc, char **argv)
Definition: cli.c:152
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

◆ listen_timeout

int listen_timeout
static

Definition at line 20 of file cli.c.

◆ monitor_dir

int monitor_dir = -1
static

Definition at line 24 of file cli.c.

◆ monitor_mask

uint32_t monitor_mask
static

Definition at line 25 of file cli.c.

◆ monitor_types

const char* const monitor_types[]
static
Initial value:
= {
[UBUS_MSG_HELLO] = "hello",
[UBUS_MSG_STATUS] = "status",
[UBUS_MSG_DATA] = "data",
[UBUS_MSG_PING] = "ping",
[UBUS_MSG_LOOKUP] = "lookup",
[UBUS_MSG_INVOKE] = "invoke",
[UBUS_MSG_ADD_OBJECT] = "add_object",
[UBUS_MSG_REMOVE_OBJECT] = "remove_object",
[UBUS_MSG_SUBSCRIBE] = "subscribe",
[UBUS_MSG_UNSUBSCRIBE] = "unsubscribe",
[UBUS_MSG_NOTIFY] = "notify",
}
@ 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

Definition at line 26 of file cli.c.

◆ name

const char* name

Definition at line 580 of file cli.c.

◆ simple_output

bool simple_output = false
static

Definition at line 22 of file cli.c.

◆ timeout

int timeout = 30
static

Definition at line 21 of file cli.c.

◆ verbose

int verbose = 0
static

Definition at line 23 of file cli.c.