Amxb_Ubus  3.3.1
Ambiorix Ubus API
amxb_ubus.h File Reference
#include <libubus.h>
#include <libubox/blob.h>
#include <libubox/uloop.h>
#include <libubox/usock.h>
#include <libubox/list.h>
#include <amxc/amxc_macros.h>
#include <amxc/amxc.h>
#include <amxp/amxp.h>
#include <amxd/amxd_dm.h>
#include <amxd/amxd_object.h>
#include <amxd/amxd_function.h>
#include <amxd/amxd_path.h>
#include <amxb/amxb.h>
#include <amxb/amxb_be_intf.h>

Go to the source code of this file.

Data Structures

struct  _amxb_ubus_sub
 
struct  _amxb_ubus
 
struct  _amxb_ubus_object
 
struct  _amxb_ubus_request
 

Typedefs

typedef struct _amxb_ubus_sub amxb_ubus_sub_t
 
typedef struct _amxb_ubus amxb_ubus_t
 
typedef struct _amxb_ubus_object amxb_ubus_object_t
 
typedef struct _amxb_ubus_request amxb_ubus_request_t
 

Functions

amxb_be_info_t * amxb_be_info (void)
 
int PRIVATE amxb_ubus_parse_blob (amxc_var_t *var, struct blob_attr *attr, bool table)
 
int PRIVATE amxb_ubus_parse_blob_table (amxc_var_t *var, struct blob_attr *attr, int len)
 
int PRIVATE amxb_ubus_parse_blob_array (amxc_var_t *var, struct blob_attr *attr, int len)
 
int PRIVATE amxb_ubus_format_blob (amxc_var_t *data, const char *key, struct blob_buf *b)
 
int PRIVATE amxb_ubus_format_blob_table (const amxc_htable_t *table, struct blob_buf *b)
 
int PRIVATE amxb_ubus_format_blob_array (const amxc_llist_t *list, struct blob_buf *b)
 
int PRIVATE amxb_ubus_get_longest_path (amxb_ubus_t *amxb_ubus_ctx, amxd_path_t *path, amxc_string_t *rel_path)
 
void PRIVATE amxb_ubus_result_data (struct ubus_request *req, int type, struct blob_attr *msg)
 
int PRIVATE amxb_ubus_invoke_base (amxb_ubus_t *amxb_ubus_ctx, const char *object, amxc_var_t *args, amxb_request_t *request, uint32_t *id)
 
void *PRIVATE amxb_ubus_connect (const char *host, const char *port, const char *path, amxp_signal_mngr_t *sigmngr)
 
int PRIVATE amxb_ubus_disconnect (void *ctx)
 
int PRIVATE amxb_ubus_get_fd (void *ctx)
 
int PRIVATE amxb_ubus_read (void *ctx)
 
void PRIVATE amxb_ubus_free (void *ctx)
 
int PRIVATE amxb_ubus_invoke (void *const ctx, amxb_invoke_t *invoke_ctx, amxc_var_t *args, amxb_request_t *request, int timeout)
 
int PRIVATE amxb_ubus_async_invoke (void *const ctx, amxb_invoke_t *invoke_ctx, amxc_var_t *args, amxb_request_t *request)
 
int PRIVATE amxb_ubus_wait_request (void *const ctx, amxb_request_t *request, int timeout)
 
int PRIVATE amxb_ubus_close_request (void *const ctx, amxb_request_t *request)
 
int PRIVATE amxb_ubus_subscribe (void *const ctx, const char *object)
 
int PRIVATE amxb_ubus_unsubscribe (void *const ctx, const char *object)
 
int PRIVATE amxb_ubus_register (void *const ctx, amxd_dm_t *const dm)
 
void PRIVATE amxb_ubus_cancel_requests (amxb_ubus_t *amxb_ubus_ctx)
 
void PRIVATE amxb_ubus_obj_it_free (amxc_llist_it_t *it)
 
int PRIVATE amxb_ubus_list (void *const bus_ctx, const char *object, uint32_t flags, uint32_t access, amxb_request_t *request)
 
const amxc_var_t * amxb_ubus_get_config_option (const char *name)
 

Typedef Documentation

◆ amxb_ubus_object_t

◆ amxb_ubus_request_t

◆ amxb_ubus_sub_t

◆ amxb_ubus_t

typedef struct _amxb_ubus amxb_ubus_t

Function Documentation

◆ amxb_be_info()

amxb_be_info_t* amxb_be_info ( void  )

Definition at line 442 of file amxb_ubus.c.

442  {
443  return &amxb_ubus_be_info;
444 }
amxb_be_info_t amxb_ubus_be_info
Definition: amxb_ubus.c:433
Here is the caller graph for this function:

◆ amxb_ubus_async_invoke()

int PRIVATE amxb_ubus_async_invoke ( void *const  ctx,
amxb_invoke_t *  invoke_ctx,
amxc_var_t *  args,
amxb_request_t *  request 
)

Definition at line 405 of file amxb_ubus_invoke.c.

408  {
409  amxb_ubus_t* amxb_ubus_ctx = (amxb_ubus_t*) ctx;
410  uint32_t id = 0;
411  int ret = -1;
412  amxb_ubus_request_t* amxb_ubus_req = NULL;
413 
414  when_str_empty(invoke_ctx->object, exit);
415  amxb_ubus_req = (amxb_ubus_request_t*) calloc(1, sizeof(amxb_ubus_request_t));
416  when_null(amxb_ubus_req, exit);
417  amxc_var_init(&amxb_ubus_req->args);
418  amxb_ubus_transform_args(&amxb_ubus_req->args, args, invoke_ctx->method);
419 
420  if(amxb_ubus_invoke_base(amxb_ubus_ctx,
421  invoke_ctx->object,
422  args,
423  request,
424  &id) != 0) {
425  when_failed(amxb_ubus_convert(amxb_ubus_ctx, invoke_ctx, &amxb_ubus_req->args), exit);
426  when_failed(amxb_ubus_invoke_base(amxb_ubus_ctx,
427  invoke_ctx->object,
428  &amxb_ubus_req->args,
429  request,
430  &id),
431  exit);
432  }
433 
434  amxb_ubus_req->request = request;
435  amxb_ubus_req->id = id;
436  request->bus_data = amxb_ubus_req;
437 
438  amxb_ubus_req->ubus_req = (struct ubus_request*) calloc(1, sizeof(struct ubus_request));
439  when_null(amxb_ubus_req->ubus_req, exit);
440 
441  ret = ubus_invoke_async(amxb_ubus_ctx->ubus_ctx,
442  id,
443  invoke_ctx->method,
444  amxb_ubus_ctx->b.head,
445  amxb_ubus_req->ubus_req);
446 
447  amxb_ubus_req->ubus_req->data_cb = amxb_ubus_result_data;
448  amxb_ubus_req->ubus_req->complete_cb = amxb_ubus_request_done;
449  amxb_ubus_req->ubus_req->priv = amxb_ubus_req;
450 
451  ubus_complete_request_async(amxb_ubus_ctx->ubus_ctx, amxb_ubus_req->ubus_req);
452 
453 exit:
454  if(ret != 0) {
455  if(amxb_ubus_req != NULL) {
456  amxc_var_clean(&amxb_ubus_req->args);
457  free(amxb_ubus_req->ubus_req);
458  }
459  free(amxb_ubus_req);
460  request->bus_data = NULL;
461  }
462  return ret;
463 }
static void amxb_ubus_transform_args(amxc_var_t *dest, amxc_var_t *args, const char *method)
static int amxb_ubus_convert(amxb_ubus_t *amxb_ubus_ctx, amxb_invoke_t *invoke_ctx, amxc_var_t *args)
int PRIVATE amxb_ubus_invoke_base(amxb_ubus_t *amxb_ubus_ctx, const char *object, amxc_var_t *args, amxb_request_t *request, uint32_t *id)
static void amxb_ubus_request_done(struct ubus_request *req, int ret)
void PRIVATE amxb_ubus_result_data(struct ubus_request *req, AMXB_UNUSED int type, struct blob_attr *msg)
struct ubus_request * ubus_req
Definition: amxb_ubus.h:106
amxb_request_t * request
Definition: amxb_ubus.h:109
amxc_var_t args
Definition: amxb_ubus.h:108
struct blob_buf b
Definition: amxb_ubus.h:89
struct ubus_context * ubus_ctx
Definition: amxb_ubus.h:87
Here is the call graph for this function:

◆ amxb_ubus_cancel_requests()

void PRIVATE amxb_ubus_cancel_requests ( amxb_ubus_t amxb_ubus_ctx)

Definition at line 592 of file amxb_ubus_register.c.

592  {
593  amxc_var_t ret;
594  amxc_var_init(&ret);
595  amxc_llist_for_each(it, &amxb_ubus_ctx->pending_reqs) {
596  amxb_ubus_fcall_t* fcall = amxc_container_of(it, amxb_ubus_fcall_t, it);
597  blob_buf_init(&amxb_ubus_ctx->b, 0);
598  amxb_ubus_func_return(fcall->amxb_ubus_ctx, &ret);
599  ubus_send_reply(amxb_ubus_ctx->ubus_ctx, &fcall->req, amxb_ubus_ctx->b.head);
600 
601  ubus_complete_deferred_request(amxb_ubus_ctx->ubus_ctx,
602  &fcall->req,
603  UBUS_STATUS_UNKNOWN_ERROR);
604 
605  amxd_function_set_deferred_cb(fcall->call_id, NULL, NULL);
606  amxd_function_deferred_remove(fcall->call_id);
607  amxc_llist_it_take(it);
608  free(fcall);
609  }
610 
611  amxc_var_clean(&ret);
612 }
static void amxb_ubus_func_return(amxb_ubus_t *amxb_ubus_ctx, amxc_var_t *ret)
struct ubus_request_data req
amxb_ubus_t * amxb_ubus_ctx
amxc_llist_t pending_reqs
Definition: amxb_ubus.h:94
Here is the call graph for this function:
Here is the caller graph for this function:

◆ amxb_ubus_close_request()

int PRIVATE amxb_ubus_close_request ( void *const  ctx,
amxb_request_t *  request 
)

Definition at line 475 of file amxb_ubus_invoke.c.

476  {
477  amxb_ubus_t* amxb_ubus_ctx = (amxb_ubus_t*) ctx;
478  amxb_ubus_request_t* amxb_ubus_req = (amxb_ubus_request_t*) request->bus_data;
479 
480  if(amxb_ubus_req != NULL) {
481  struct ubus_request* ubus_req = amxb_ubus_req->ubus_req;
482  ubus_abort_request(amxb_ubus_ctx->ubus_ctx, ubus_req);
483  amxc_var_clean(&amxb_ubus_req->args);
484  free(ubus_req);
485  free(amxb_ubus_req);
486  request->bus_data = NULL;
487  }
488  return 0;
489 }

◆ amxb_ubus_connect()

void* PRIVATE amxb_ubus_connect ( const char *  host,
const char *  port,
const char *  path,
amxp_signal_mngr_t *  sigmngr 
)

Definition at line 222 of file amxb_ubus.c.

225  {
226  amxb_ubus_t* amxb_ubus_ctx = NULL;
227 
228  when_not_null(host, exit);
229  when_not_null(port, exit);
230 
231  amxb_ubus_ctx = (amxb_ubus_t*) calloc(1, sizeof(amxb_ubus_t));
232  when_null(amxb_ubus_ctx, exit);
233 
234  amxb_ubus_ctx->ubus_ctx = ubus_connect(path);
235  if(amxb_ubus_ctx->ubus_ctx == NULL) {
236  free(amxb_ubus_ctx);
237  amxb_ubus_ctx = NULL;
238  goto exit;
239  }
240 
241  amxc_htable_init(&amxb_ubus_ctx->subscribers, 5);
242  blob_buf_init(&amxb_ubus_ctx->b, 0);
243  amxb_ubus_ctx->sigmngr = sigmngr;
244  amxc_llist_init(&amxb_ubus_ctx->registered_objs);
245  amxc_llist_init(&amxb_ubus_ctx->pending_reqs);
246 
247  if(GET_BOOL(config_opts, "watch-ubus-events")) {
248  amxb_ubus_ctx->watcher.cb = amxb_ubus_watcher;
249  ubus_register_event_handler(amxb_ubus_ctx->ubus_ctx,
250  &amxb_ubus_ctx->watcher, "ubus.object.add");
251  }
252  amxp_slot_connect(NULL,
253  "config:changed",
254  NULL,
256  amxb_ubus_ctx);
257 
258 exit:
259  return amxb_ubus_ctx;
260 }
static const amxc_var_t * config_opts
Definition: amxb_ubus.c:67
static void amxb_ubus_watcher(UNUSED struct ubus_context *ctx, struct ubus_event_handler *ev, UNUSED const char *type, struct blob_attr *msg)
Definition: amxb_ubus.c:125
static void amxb_ubus_config_changed(UNUSED const char *const sig_name, UNUSED const amxc_var_t *const data, void *const priv)
Definition: amxb_ubus.c:200
amxc_htable_t subscribers
Definition: amxb_ubus.h:88
struct ubus_event_handler watcher
Definition: amxb_ubus.h:92
amxc_llist_t registered_objs
Definition: amxb_ubus.h:91
amxp_signal_mngr_t * sigmngr
Definition: amxb_ubus.h:90
static amxp_signal_mngr_t * sigmngr
Here is the call graph for this function:
Here is the caller graph for this function:

◆ amxb_ubus_disconnect()

int PRIVATE amxb_ubus_disconnect ( void *  ctx)

Definition at line 262 of file amxb_ubus.c.

262  {
263  amxb_ubus_t* amxb_ubus_ctx = (amxb_ubus_t*) ctx;
264 
265  when_null(amxb_ubus_ctx, exit);
266  when_null(amxb_ubus_ctx->ubus_ctx, exit);
267 
268  amxp_slot_disconnect_with_priv(NULL,
270  amxb_ubus_ctx);
271 
272  amxc_htable_clean(&amxb_ubus_ctx->subscribers, amxb_ubus_remove_sub);
273  amxb_ubus_cancel_requests(amxb_ubus_ctx);
274  ubus_free(amxb_ubus_ctx->ubus_ctx);
275  blob_buf_free(&amxb_ubus_ctx->b);
276  amxb_ubus_ctx->ubus_ctx = NULL;
277 
278 exit:
279  return 0;
280 }
static void amxb_ubus_remove_sub(AMXB_UNUSED const char *key, amxc_htable_it_t *it)
Definition: amxb_ubus.c:71
void PRIVATE amxb_ubus_cancel_requests(amxb_ubus_t *amxb_ubus_ctx)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ amxb_ubus_format_blob()

int PRIVATE amxb_ubus_format_blob ( amxc_var_t *  data,
const char *  key,
struct blob_buf *  b 
)

Definition at line 166 of file amxb_ubus_blob.c.

168  {
169  void* c;
170 
171  switch(amxc_var_type_of(data)) {
172  case AMXC_VAR_ID_BOOL: {
173  blobmsg_add_u8(b, key, (uint8_t) amxc_var_constcast(bool, data));
174  }
175  break;
176 
177  case AMXC_VAR_ID_INT8: {
178  blobmsg_add_u8(b, key, (uint8_t) amxc_var_constcast(int8_t, data));
179  }
180  break;
181  case AMXC_VAR_ID_UINT8: {
182  if(amxc_var_constcast(uint8_t, data) > INT8_MAX) {
183  blobmsg_add_u16(b, key, (uint16_t) amxc_var_constcast(uint8_t, data));
184  } else {
185  blobmsg_add_u8(b, key, (uint8_t) amxc_var_constcast(uint8_t, data));
186  }
187  }
188  break;
189  case AMXC_VAR_ID_INT16: {
190  blobmsg_add_u16(b, key, (uint16_t) amxc_var_constcast(int16_t, data));
191  }
192  break;
193  case AMXC_VAR_ID_UINT16: {
194  if(amxc_var_constcast(uint16_t, data) > INT16_MAX) {
195  blobmsg_add_u32(b, key, (uint32_t) amxc_var_constcast(uint16_t, data));
196  } else {
197  blobmsg_add_u16(b, key, (uint16_t) amxc_var_constcast(uint16_t, data));
198  }
199  }
200  break;
201  case AMXC_VAR_ID_INT32: {
202  blobmsg_add_u32(b, key, (uint32_t) amxc_var_constcast(int32_t, data));
203  }
204  break;
205  case AMXC_VAR_ID_UINT32: {
206  if(amxc_var_constcast(uint32_t, data) > INT32_MAX) {
207  blobmsg_add_u64(b, key, (uint64_t) amxc_var_constcast(uint32_t, data));
208  } else {
209  blobmsg_add_u32(b, key, (uint32_t) amxc_var_constcast(uint32_t, data));
210  }
211  }
212  break;
213  case AMXC_VAR_ID_INT64: {
214  blobmsg_add_u64(b, key, (uint64_t) amxc_var_constcast(int64_t, data));
215  }
216  break;
217  case AMXC_VAR_ID_UINT64: {
218  blobmsg_add_u64(b, key, (uint64_t) amxc_var_constcast(uint64_t, data));
219  }
220  break;
221 
222  case AMXC_VAR_ID_HTABLE: {
223  const amxc_htable_t* table = amxc_var_constcast(amxc_htable_t, data);
224  c = blobmsg_open_table(b, key);
225  amxb_ubus_format_blob_table(table, b);
226  blobmsg_close_table(b, c);
227  }
228  break;
229 
230  case AMXC_VAR_ID_LIST: {
231  const amxc_llist_t* list = amxc_var_constcast(amxc_llist_t, data);
232  c = blobmsg_open_array(b, key);
234  blobmsg_close_array(b, c);
235  }
236  break;
237 
238  default: {
239  char* string = amxc_var_dyncast(cstring_t, data);
240  blobmsg_add_string(b, key, string == NULL ? "" : string);
241  free(string);
242  }
243  break;
244  }
245 
246  return 0;
247 }
int PRIVATE amxb_ubus_format_blob_array(const amxc_llist_t *list, struct blob_buf *b)
int PRIVATE amxb_ubus_format_blob_table(const amxc_htable_t *table, struct blob_buf *b)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ amxb_ubus_format_blob_array()

int PRIVATE amxb_ubus_format_blob_array ( const amxc_llist_t *  list,
struct blob_buf *  b 
)

Definition at line 265 of file amxb_ubus_blob.c.

266  {
267  int retval = -1;
268 
269  amxc_llist_for_each(it, list) {
270  amxc_var_t* data = amxc_var_from_llist_it(it);
271  when_failed(amxb_ubus_format_blob(data, NULL, b), exit);
272  }
273 
274  retval = 0;
275 
276 exit:
277  return retval;
278 }
int PRIVATE amxb_ubus_format_blob(amxc_var_t *data, const char *key, struct blob_buf *b)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ amxb_ubus_format_blob_table()

int PRIVATE amxb_ubus_format_blob_table ( const amxc_htable_t *  table,
struct blob_buf *  b 
)

Definition at line 249 of file amxb_ubus_blob.c.

250  {
251  int retval = -1;
252 
253  amxc_htable_for_each(it, table) {
254  const char* key = amxc_htable_it_get_key(it);
255  amxc_var_t* data = amxc_var_from_htable_it(it);
256  when_failed(amxb_ubus_format_blob(data, key, b), exit);
257  }
258 
259  retval = 0;
260 
261 exit:
262  return retval;
263 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ amxb_ubus_free()

void PRIVATE amxb_ubus_free ( void *  ctx)

Definition at line 316 of file amxb_ubus.c.

316  {
317  amxb_ubus_t* amxb_ubus_ctx = (amxb_ubus_t*) ctx;
318 
319  when_null(amxb_ubus_ctx, exit);
320  amxc_llist_clean(&amxb_ubus_ctx->registered_objs, amxb_ubus_obj_it_free);
321  free(amxb_ubus_ctx);
322 
323 exit:
324  return;
325 }
void PRIVATE amxb_ubus_obj_it_free(amxc_llist_it_t *it)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ amxb_ubus_get_config_option()

const amxc_var_t* amxb_ubus_get_config_option ( const char *  name)

Definition at line 218 of file amxb_ubus.c.

218  {
219  return GET_ARG(config_opts, name);
220 }

◆ amxb_ubus_get_fd()

int PRIVATE amxb_ubus_get_fd ( void *  ctx)

Definition at line 282 of file amxb_ubus.c.

282  {
283  amxb_ubus_t* amxb_ubus_ctx = (amxb_ubus_t*) ctx;
284  int fd = -1;
285 
286  when_null(amxb_ubus_ctx, exit);
287  when_null(amxb_ubus_ctx->ubus_ctx, exit);
288 
289  fd = amxb_ubus_ctx->ubus_ctx->sock.fd;
290 
291 exit:
292  return fd;
293 }
Here is the caller graph for this function:

◆ amxb_ubus_get_longest_path()

int PRIVATE amxb_ubus_get_longest_path ( amxb_ubus_t amxb_ubus_ctx,
amxd_path_t *  path,
amxc_string_t *  rel_path 
)

Definition at line 243 of file amxb_ubus_invoke.c.

245  {
246  int retval = -1;
247  char* part = NULL;
248  const char* object = NULL;
249  uint32_t id = 0;
250 
251  do{
252  object = amxd_path_get(path, 0);
253  when_str_empty(object, exit);
254  retval = ubus_lookup_id(amxb_ubus_ctx->ubus_ctx, object, &id);
255  if((retval == 0) && (id != 0)) {
256  break;
257  }
258  free(part);
259  part = amxd_path_get_last(path, true);
260  amxc_string_prependf(rel_path, "%s", part);
261  } while (part != NULL);
262 
263 exit:
264  free(part);
265  return retval;
266 }
Here is the caller graph for this function:

◆ amxb_ubus_invoke()

int PRIVATE amxb_ubus_invoke ( void *const  ctx,
amxb_invoke_t *  invoke_ctx,
amxc_var_t *  args,
amxb_request_t *  request,
int  timeout 
)

Definition at line 331 of file amxb_ubus_invoke.c.

335  {
336  amxb_ubus_t* amxb_ubus_ctx = (amxb_ubus_t*) ctx;
337  uint32_t id = 0;
338  int ret = amxd_status_unknown_error;
339  amxb_ubus_request_t* amxb_ubus_req = NULL;
340 
341  when_str_empty(invoke_ctx->object, exit);
342  amxb_ubus_req = (amxb_ubus_request_t*) calloc(1, sizeof(amxb_ubus_request_t));
343  when_null(amxb_ubus_req, exit);
344  amxc_var_init(&amxb_ubus_req->args);
345  amxb_ubus_transform_args(&amxb_ubus_req->args, args, invoke_ctx->method);
346 
347  if(amxb_ubus_invoke_base(amxb_ubus_ctx,
348  invoke_ctx->object,
349  args,
350  request,
351  &id) != 0) {
352  when_failed(amxb_ubus_convert(amxb_ubus_ctx, invoke_ctx, &amxb_ubus_req->args), exit);
353  ret = amxb_ubus_invoke_base(amxb_ubus_ctx,
354  invoke_ctx->object,
355  &amxb_ubus_req->args,
356  request,
357  &id);
358  ret = amxb_ubus_status_to_amxd_status(ret, request->result);
359  request->bus_retval = ret;
360  amxb_ubus_req->converted = true;
361  when_failed(ret, exit);
362  }
363 
364  amxb_ubus_req->request = request;
365  request->bus_data = amxb_ubus_req;
366 
367  ret = ubus_invoke(amxb_ubus_ctx->ubus_ctx,
368  id,
369  invoke_ctx->method,
370  amxb_ubus_ctx->b.head,
372  amxb_ubus_req,
373  timeout * 1000);
374 
375  if((ret == UBUS_STATUS_METHOD_NOT_FOUND) && (invoke_ctx->method[0] != '_')) {
376  const amxc_htable_t* htable = NULL;
377  htable = amxc_var_constcast(amxc_htable_t, &amxb_ubus_req->args);
378  blob_buf_init(&amxb_ubus_ctx->b, 0);
379 
380  amxb_ubus_format_blob_table(htable, &amxb_ubus_ctx->b);
381 
382  ret = ubus_invoke(amxb_ubus_ctx->ubus_ctx,
383  id,
384  "_exec",
385  amxb_ubus_ctx->b.head,
387  amxb_ubus_req,
388  timeout * 1000);
389  }
390 
391  ret = amxb_ubus_status_to_amxd_status(ret, request->result);
392  request->bus_retval = ret;
393  if(amxb_ubus_req->converted) {
394  amxb_ubus_convert_out_args(request->result);
395  }
396 
397 exit:
398  if(amxb_ubus_req != NULL) {
399  amxc_var_clean(&amxb_ubus_req->args);
400  }
401  free(amxb_ubus_req);
402  return ret;
403 }
int PRIVATE amxb_ubus_format_blob_table(const amxc_htable_t *table, struct blob_buf *b)
static void amxb_ubus_convert_out_args(amxc_var_t *result)
static int amxb_ubus_status_to_amxd_status(int rv, amxc_var_t *result)
Here is the call graph for this function:

◆ amxb_ubus_invoke_base()

int PRIVATE amxb_ubus_invoke_base ( amxb_ubus_t amxb_ubus_ctx,
const char *  object,
amxc_var_t *  args,
amxb_request_t *  request,
uint32_t *  id 
)

Definition at line 303 of file amxb_ubus_invoke.c.

307  {
308  int retval = -1;
309 
310  // lookup id can cause the ubus blob msg to be overwritten
311  // first do the lookup and then initialize the blob
312  retval = ubus_lookup_id(amxb_ubus_ctx->ubus_ctx, object, id);
313  if(retval != 0) {
314  goto exit;
315  }
316 
317  blob_buf_init(&amxb_ubus_ctx->b, 0);
318 
319  if(args != NULL) {
320  when_true(amxc_var_type_of(args) != AMXC_VAR_ID_HTABLE, exit);
321  const amxc_htable_t* htable = amxc_var_constcast(amxc_htable_t, args);
322  when_failed(amxb_ubus_format_blob_table(htable, &amxb_ubus_ctx->b), exit);
323  }
324 
325  amxc_var_set_type(request->result, AMXC_VAR_ID_LIST);
326 
327 exit:
328  return retval;
329 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ amxb_ubus_list()

int PRIVATE amxb_ubus_list ( void *const  bus_ctx,
const char *  object,
uint32_t  flags,
uint32_t  access,
amxb_request_t *  request 
)

Definition at line 332 of file amxb_ubus_list.c.

336  {
337  amxb_bus_ctx_t* bus_ctx = NULL;
338  amxb_ubus_t* amxb_ubus_ctx = (amxb_ubus_t*) ctx;
339  int rv = -1;
340  ubus_filter_t filter;
341 
342  memset(&filter, 0, sizeof(ubus_filter_t));
343  filter.flags = flags;
344  filter.access = access;
345  filter.request = request;
346  amxc_var_set_type(&filter.amx_paths, AMXC_VAR_ID_LIST);
347  amxc_var_set_type(&filter.objects, AMXC_VAR_ID_HTABLE);
348 
349  bus_ctx = amxb_request_get_ctx(request);
350  if((object == NULL) || (*object == 0)) {
351  filter.depth = 1;
352  filter.flags &= ~(AMXB_FLAG_OBJECTS | AMXB_FLAG_INSTANCES);
353  rv = ubus_lookup(amxb_ubus_ctx->ubus_ctx, NULL, amxb_ubus_objects_cb, &filter);
354  filter.flags &= ~(AMXB_FLAG_PARAMETERS | AMXB_FLAG_FUNCTIONS);
355  amxc_var_for_each(path, &filter.amx_paths) {
356  const char* p = GET_CHAR(path, NULL);
358  }
359  request->cb_fn(bus_ctx, NULL, request->priv);
360  } else {
361  filter.flags |= (AMXB_FLAG_OBJECTS | AMXB_FLAG_INSTANCES);
362  rv = amxb_ubus_list_object_describe(bus_ctx, object, &filter);
363 
364  if(rv != 0) {
365  filter.flags &= ~(AMXB_FLAG_OBJECTS | AMXB_FLAG_INSTANCES);
366  rv = amxb_ubus_list_native(amxb_ubus_ctx, object, &filter);
367  amxc_var_for_each(path, &filter.amx_paths) {
368  const char* p = GET_CHAR(path, NULL);
370  }
371  }
372  request->cb_fn(bus_ctx, NULL, request->priv);
373  }
374 
375  amxc_var_clean(&filter.objects);
376  amxc_var_clean(&filter.amx_paths);
377  amxb_close_request(&request);
378  return rv;
379 }
static int amxb_ubus_list_object_describe(amxb_bus_ctx_t *bus_ctx, const char *object, ubus_filter_t *filter)
static int amxb_ubus_list_native(amxb_ubus_t *amxb_ubus_ctx, const char *object, ubus_filter_t *filter)
static void amxb_ubus_objects_cb(AMXB_UNUSED struct ubus_context *c, struct ubus_object_data *o, void *p)
amxb_request_t * request
amxc_var_t amx_paths
uint32_t access
uint32_t flags
amxc_var_t objects
uint32_t depth
static amxb_bus_ctx_t * bus_ctx
Here is the call graph for this function:

◆ amxb_ubus_obj_it_free()

void PRIVATE amxb_ubus_obj_it_free ( amxc_llist_it_t *  it)

Definition at line 614 of file amxb_ubus_register.c.

614  {
615  amxb_ubus_object_t* obj = amxc_llist_it_get_data(it,
617  it);
618  struct ubus_method* methods = (struct ubus_method*) obj->ubus_obj.methods;
619 
620  amxc_llist_it_take(it);
621  for(int i = 0; i < obj->ubus_obj.n_methods; i++) {
622  struct blobmsg_policy* policy =
623  (struct blobmsg_policy*) methods[i].policy;
624  free(policy);
625  methods[i].policy = NULL;
626  }
627 
628 
629  amxp_slot_disconnect_with_priv(&obj->amxb_ubus_ctx->dm->sigmngr,
631  obj);
632 
633  free(obj->ubus_path);
634  free(methods);
635  free(obj->ubus_obj.type);
636  free(obj);
637 }
static void amxb_ubus_send_notification(const char *const sig_name, const amxc_var_t *const data, void *const priv)
struct ubus_object ubus_obj
Definition: amxb_ubus.h:101
amxb_ubus_t * amxb_ubus_ctx
Definition: amxb_ubus.h:102
amxd_dm_t * dm
Definition: amxb_ubus.h:95
Here is the call graph for this function:
Here is the caller graph for this function:

◆ amxb_ubus_parse_blob()

int PRIVATE amxb_ubus_parse_blob ( amxc_var_t *  var,
struct blob_attr *  attr,
bool  table 
)

Definition at line 111 of file amxb_ubus_blob.c.

113  {
114  int len;
115  int off = 0;
116  void* data;
117 
118  if(!blobmsg_check_attr(attr, false)) {
119  return 0;
120  }
121 
122  if(table) {
123  if(blobmsg_name(attr)[0] != 0) {
124  var = amxc_var_add_new_key(var, blobmsg_name(attr));
125  off++;
126  } else {
127  return 0;
128  }
129  }
130 
131  data = blobmsg_data(attr);
132  len = blobmsg_data_len(attr);
133  amxb_ubus_set_var(var, attr, data, len);
134 
135  return off + 1;
136 }
static void amxb_ubus_set_var(amxc_var_t *var, struct blob_attr *attr, void *data, int len)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ amxb_ubus_parse_blob_array()

int PRIVATE amxb_ubus_parse_blob_array ( amxc_var_t *  var,
struct blob_attr *  attr,
int  len 
)

Definition at line 152 of file amxb_ubus_blob.c.

154  {
155  int rem = len;
156  struct blob_attr* pos;
157 
158  __blob_for_each_attr(pos, attr, rem) {
159  amxc_var_t* item = amxc_var_add_new(var);
160  amxb_ubus_parse_blob(item, pos, false);
161  }
162 
163  return 1;
164 }
int PRIVATE amxb_ubus_parse_blob(amxc_var_t *var, struct blob_attr *attr, bool table)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ amxb_ubus_parse_blob_table()

int PRIVATE amxb_ubus_parse_blob_table ( amxc_var_t *  var,
struct blob_attr *  attr,
int  len 
)

Definition at line 138 of file amxb_ubus_blob.c.

140  {
141  int rem = len;
142  struct blob_attr* pos;
143 
144  __blob_for_each_attr(pos, attr, rem) {
145  amxb_ubus_parse_blob(var, pos, true);
146  }
147 
148  return 1;
149 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ amxb_ubus_read()

int PRIVATE amxb_ubus_read ( void *  ctx)

Definition at line 295 of file amxb_ubus.c.

295  {
296  amxb_ubus_t* amxb_ubus_ctx = (amxb_ubus_t*) ctx;
297  struct ubus_context* ubus_ctx = NULL;
298  int retval = -1;
299 
300  when_null(amxb_ubus_ctx, exit);
301  when_null(amxb_ubus_ctx->ubus_ctx, exit);
302 
303  ubus_ctx = amxb_ubus_ctx->ubus_ctx;
304  ubus_ctx->sock.cb(&ubus_ctx->sock, ULOOP_READ);
305 
306  if(ubus_ctx->sock.eof) {
307  retval = -1;
308  } else {
309  retval = 0;
310  }
311 
312 exit:
313  return retval;
314 }

◆ amxb_ubus_register()

int PRIVATE amxb_ubus_register ( void *const  ctx,
amxd_dm_t *const  dm 
)

Definition at line 639 of file amxb_ubus_register.c.

640  {
641  int status = UBUS_STATUS_UNKNOWN_ERROR;
642  amxb_ubus_t* amxb_ubus_ctx = (amxb_ubus_t*) ctx;
643  const amxc_var_t* cfg_ros = amxb_ubus_get_config_option("register-on-start-event");
644 
645  when_not_null(amxb_ubus_ctx->dm, exit);
646  amxb_ubus_ctx->dm = dm;
647 
648  if(amxc_var_dyncast(bool, cfg_ros)) {
649  amxp_slot_connect(&dm->sigmngr,
650  "app:start",
651  NULL,
653  amxb_ubus_ctx);
654  } else {
655  amxb_ubus_register_dm(NULL, NULL, ctx);
656  }
657 
658  status = UBUS_STATUS_OK;
659 
660 exit:
661  return status;
662 }
const amxc_var_t * amxb_ubus_get_config_option(const char *name)
Definition: amxb_ubus.c:218
static void amxb_ubus_register_dm(UNUSED const char *const sig_name, UNUSED const amxc_var_t *const data, void *const priv)
static amxd_dm_t dm

◆ amxb_ubus_result_data()

void PRIVATE amxb_ubus_result_data ( struct ubus_request *  req,
int  type,
struct blob_attr *  msg 
)

◆ amxb_ubus_subscribe()

int PRIVATE amxb_ubus_subscribe ( void *const  ctx,
const char *  object 
)

Definition at line 95 of file amxb_ubus_subscribe.c.

96  {
97  amxb_ubus_t* amxb_ubus_ctx = (amxb_ubus_t*) ctx;
98  amxc_htable_it_t* it = NULL;
99  amxb_ubus_sub_t* amxb_ubus_sub = NULL;
100  amxc_string_t rel_path;
101  amxd_path_t path;
102  int ret = -1;
103  uint32_t id = 0;
104 
105  amxc_string_init(&rel_path, 64);
106  amxd_path_init(&path, NULL);
107  amxd_path_setf(&path, true, "%s", object);
108 
109  when_failed(amxb_ubus_get_longest_path(amxb_ubus_ctx, &path, &rel_path), exit);
110 
111  ret = ubus_lookup_id(amxb_ubus_ctx->ubus_ctx, amxd_path_get(&path, 0), &id);
112  when_true(ret != 0, exit);
113 
114  it = amxc_htable_get(&amxb_ubus_ctx->subscribers, amxd_path_get(&path, 0));
115  when_not_null(it, exit);
116 
117  amxb_ubus_sub = (amxb_ubus_sub_t*) calloc(1, sizeof(amxb_ubus_sub_t));
118  amxc_htable_insert(&amxb_ubus_ctx->subscribers,
119  object,
120  &amxb_ubus_sub->it);
121 
122  ret = ubus_register_subscriber(amxb_ubus_ctx->ubus_ctx,
123  &amxb_ubus_sub->sub);
124  when_true(ret != 0, exit);
125  amxb_ubus_sub->sub.cb = amxb_ubus_receive_notification;
126 
127  ret = ubus_subscribe(amxb_ubus_ctx->ubus_ctx, &amxb_ubus_sub->sub, id);
128 
129 exit:
130  amxc_string_clean(&rel_path);
131  amxd_path_clean(&path);
132  return ret;
133 }
int PRIVATE amxb_ubus_get_longest_path(amxb_ubus_t *amxb_ubus_ctx, amxd_path_t *path, amxc_string_t *rel_path)
static int amxb_ubus_receive_notification(struct ubus_context *ctx, AMXB_UNUSED struct ubus_object *obj, AMXB_UNUSED struct ubus_request_data *req, const char *method, struct blob_attr *msg)
amxc_htable_it_t it
Definition: amxb_ubus.h:81
struct ubus_subscriber sub
Definition: amxb_ubus.h:82
Here is the call graph for this function:
Here is the caller graph for this function:

◆ amxb_ubus_unsubscribe()

int PRIVATE amxb_ubus_unsubscribe ( void *const  ctx,
const char *  object 
)

Definition at line 135 of file amxb_ubus_subscribe.c.

136  {
137  amxb_ubus_t* amxb_ubus_ctx = (amxb_ubus_t*) ctx;
138  amxb_ubus_sub_t* amxb_ubus_sub = NULL;
139  amxc_htable_it_t* it = NULL;
140  amxc_string_t rel_path;
141  amxd_path_t path;
142  int ret = 0;
143  uint32_t id = 0;
144 
145  amxc_string_init(&rel_path, 64);
146  amxd_path_init(&path, NULL);
147  amxd_path_setf(&path, true, "%s", object);
148 
149  amxb_ubus_get_longest_path(amxb_ubus_ctx, &path, &rel_path);
150 
151  it = amxc_htable_get(&amxb_ubus_ctx->subscribers, object);
152  when_null(it, leave);
153  amxb_ubus_sub = amxc_htable_it_get_data(it, amxb_ubus_sub_t, it);
154 
155  ret = ubus_lookup_id(amxb_ubus_ctx->ubus_ctx, amxd_path_get(&path, 0), &id);
156  when_true(ret != 0, exit);
157 
158  ubus_unsubscribe(amxb_ubus_ctx->ubus_ctx, &amxb_ubus_sub->sub, id);
159 
160 exit:
161  ret = ubus_unregister_subscriber(amxb_ubus_ctx->ubus_ctx, &amxb_ubus_sub->sub);
162 
163  amxc_htable_it_clean(it, NULL);
164  amxp_timer_delete(&amxb_ubus_sub->reactivate);
165  free(amxb_ubus_sub);
166 
167 leave:
168  amxc_string_clean(&rel_path);
169  amxd_path_clean(&path);
170 
171  return ret;
172 }
amxp_timer_t * reactivate
Definition: amxb_ubus.h:83
Here is the call graph for this function:

◆ amxb_ubus_wait_request()

int PRIVATE amxb_ubus_wait_request ( void *const  ctx,
amxb_request_t *  request,
int  timeout 
)