Amxb_Ubus  3.3.1
Ambiorix Ubus API
amxb_ubus_list.c File Reference
#include "amxb_ubus.h"

Go to the source code of this file.

Data Structures

struct  _ubus_filter
 

Macros

#define _GNU_SOURCE
 

Typedefs

typedef struct _ubus_filter ubus_filter_t
 

Functions

static int32_t amxb_ubus_object_depth (const char *path)
 
static bool amxb_ubus_has_function (struct ubus_object_data *o, const char *func_name)
 
static void amxb_ubus_add_functions (struct ubus_object_data *o, ubus_filter_t *filter, const char *path, amxc_var_t *retval)
 
static void amxb_ubus_fill_list (amxb_bus_ctx_t *bus_ctx, const char *path, amxc_var_t *data, const char *type, bool fetch_names, amxc_var_t *retval)
 
static int amxb_ubus_list_object_describe (amxb_bus_ctx_t *bus_ctx, const char *object, ubus_filter_t *filter)
 
static int amxb_ubus_add (const char *recv_path, struct ubus_object_data *o, ubus_filter_t *filter, amxc_var_t *output, bool functions)
 
static void amxb_ubus_path_to_depth (amxd_path_t *path, ubus_filter_t *filter, uint32_t depth)
 
static void amxb_ubus_objects_cb (AMXB_UNUSED struct ubus_context *c, struct ubus_object_data *o, void *p)
 
static int amxb_ubus_list_native (amxb_ubus_t *amxb_ubus_ctx, const char *object, ubus_filter_t *filter)
 
int amxb_ubus_list (void *const ctx, const char *object, uint32_t flags, uint32_t access, amxb_request_t *request)
 

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 56 of file amxb_ubus_list.c.

Typedef Documentation

◆ ubus_filter_t

typedef struct _ubus_filter ubus_filter_t

Function Documentation

◆ amxb_ubus_add()

static int amxb_ubus_add ( const char *  recv_path,
struct ubus_object_data *  o,
ubus_filter_t filter,
amxc_var_t *  output,
bool  functions 
)
static

Definition at line 214 of file amxb_ubus_list.c.

218  {
219  int retval = -1;
220  if(amxb_ubus_has_function(o, "_describe")) {
221  amxc_var_add(cstring_t, &filter->amx_paths, recv_path);
222  } else {
223  amxc_var_add(cstring_t, output, recv_path);
224  if(functions) {
225  amxb_ubus_add_functions(o, filter, recv_path, output);
226  }
227  retval = 0;
228  }
229 
230  return retval;
231 }
static void amxb_ubus_add_functions(struct ubus_object_data *o, ubus_filter_t *filter, const char *path, amxc_var_t *retval)
static bool amxb_ubus_has_function(struct ubus_object_data *o, const char *func_name)
amxc_var_t amx_paths
Here is the call graph for this function:
Here is the caller graph for this function:

◆ amxb_ubus_add_functions()

static void amxb_ubus_add_functions ( struct ubus_object_data *  o,
ubus_filter_t filter,
const char *  path,
amxc_var_t *  retval 
)
static

Definition at line 103 of file amxb_ubus_list.c.

106  {
107  if(o->signature && ((filter->flags & AMXB_FLAG_FUNCTIONS) != 0)) {
108  struct blob_attr* cur;
109  size_t rem = 0;
110  (void) rem; // clang complains about not used variable
111  // but rem is needed to be able to use the following macro
112  blob_for_each_attr(cur, o->signature, rem) {
113  (void) rem; // clang complains about not used variable
114  amxc_string_t func_name;
115  amxc_string_init(&func_name, 0);
116  amxc_string_setf(&func_name, "%s%s", path, blobmsg_name(cur));
117  amxc_var_add(cstring_t, retval, amxc_string_get(&func_name, 0));
118  amxc_string_clean(&func_name);
119  }
120  }
121 }
uint32_t flags
Here is the caller graph for this function:

◆ amxb_ubus_fill_list()

static void amxb_ubus_fill_list ( amxb_bus_ctx_t *  bus_ctx,
const char *  path,
amxc_var_t *  data,
const char *  type,
bool  fetch_names,
amxc_var_t *  retval 
)
static

Definition at line 123 of file amxb_ubus_list.c.

128  {
129  amxc_string_t name;
130  amxc_string_init(&name, 0);
131 
132  amxc_var_t* type_data = GETP_ARG(data, type);
133  amxc_var_for_each(d, type_data) {
134  if(amxc_var_type_of(type_data) == AMXC_VAR_ID_HTABLE) {
135  amxc_string_setf(&name, "%s%s", path, amxc_var_key(d));
136  } else {
137  amxc_string_setf(&name, "%s%s", path, GET_CHAR(d, NULL));
138  }
139  amxc_var_add(cstring_t, retval, amxc_string_get(&name, 0));
140  if(fetch_names) {
141  amxc_var_t tmp;
142  amxc_var_init(&tmp);
143  amxb_describe(bus_ctx, amxc_string_get(&name, 0), 0, &tmp, 5);
144  amxc_string_setf(&name, "%s%s", path, GETP_CHAR(&tmp, "0.name"));
145  amxc_var_add(cstring_t, retval, amxc_string_get(&name, 0));
146  amxc_var_clean(&tmp);
147  }
148  }
149 
150  amxc_string_clean(&name);
151 }
static amxb_bus_ctx_t * bus_ctx
Here is the caller graph for this function:

◆ amxb_ubus_has_function()

static bool amxb_ubus_has_function ( struct ubus_object_data *  o,
const char *  func_name 
)
static

Definition at line 84 of file amxb_ubus_list.c.

84  {
85  bool retval = false;
86  struct blob_attr* cur;
87  size_t rem = 0;
88  (void) rem; // clang complains about not used variable
89 
90  when_null(o->signature, exit);
91  blob_for_each_attr(cur, o->signature, rem) {
92  (void) rem; // clang complains about not used variable
93  if(strcmp(func_name, blobmsg_name(cur)) == 0) {
94  retval = true;
95  goto exit;
96  }
97  }
98 
99 exit:
100  return retval;
101 }
Here is the caller graph for this function:

◆ amxb_ubus_list()

int amxb_ubus_list ( void *const  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)
struct ubus_context * ubus_ctx
Definition: amxb_ubus.h:87
amxb_request_t * request
uint32_t access
amxc_var_t objects
uint32_t depth
Here is the call graph for this function:

◆ amxb_ubus_list_native()

static int amxb_ubus_list_native ( amxb_ubus_t amxb_ubus_ctx,
const char *  object,
ubus_filter_t filter 
)
static

Definition at line 307 of file amxb_ubus_list.c.

309  {
310  int rv = 0;
311 
312  if(object[strlen(object) - 1] == '.') {
313  amxc_string_t path;
314 
315  filter->path = object;
316  filter->path_len = strlen(object);
317  filter->depth = amxb_ubus_object_depth(object);
318 
319  amxc_string_init(&path, 0);
320  amxc_string_setf(&path, "%s", object);
321  amxc_string_set_at(&path, strlen(object) - 1, "*", 1, amxc_string_overwrite);
322  rv = ubus_lookup(amxb_ubus_ctx->ubus_ctx,
323  amxc_string_get(&path, 0),
325  filter);
326  amxc_string_clean(&path);
327  }
328 
329  return rv;
330 }
static int32_t amxb_ubus_object_depth(const char *path)
uint32_t path_len
const char * path
Here is the call graph for this function:
Here is the caller graph for this function:

◆ amxb_ubus_list_object_describe()

static int amxb_ubus_list_object_describe ( amxb_bus_ctx_t *  bus_ctx,
const char *  object,
ubus_filter_t filter 
)
static

Definition at line 153 of file amxb_ubus_list.c.

155  {
156  int rv = 0;
157  amxc_var_t tmp;
158  amxc_string_t path;
159  amxc_var_t* subojects = NULL;
160  amxc_var_t output;
161 
162  amxc_string_init(&path, 0);
163  amxc_var_init(&tmp);
164 
165  rv = amxb_describe(bus_ctx, object, filter->flags, &tmp, 5);
166  when_failed(rv, exit);
167 
168  amxc_var_init(&output);
169  amxc_var_set_type(&output, AMXC_VAR_ID_LIST);
170  amxc_var_add(cstring_t, &output, object);
171 
172  if(GETP_UINT32(&tmp, "0.type_id") != 2) {
173  if((filter->flags & AMXB_FLAG_PARAMETERS) != 0) {
174  amxb_ubus_fill_list(bus_ctx, object, &tmp, "0.parameters", false, &output);
175  }
176  if((filter->flags & AMXB_FLAG_FUNCTIONS) != 0) {
177  amxb_ubus_fill_list(bus_ctx, object, &tmp, "0.functions", false, &output);
178  }
179  if((filter->flags & AMXB_FLAG_OBJECTS) != 0) {
180  if(filter->flags & AMXB_FLAG_FIRST_LVL) {
181  amxb_ubus_fill_list(bus_ctx, object, &tmp, "0.objects", false, &output);
182  } else {
183  subojects = GETP_ARG(&tmp, "0.objects");
184  }
185  }
186  } else {
187  if((filter->flags & AMXB_FLAG_INSTANCES) != 0) {
188  if(filter->flags & AMXB_FLAG_FIRST_LVL) {
189  amxb_ubus_fill_list(bus_ctx, object, &tmp, "0.instances", true, &output);
190  } else {
191  subojects = GETP_ARG(&tmp, "0.instances");
192  }
193  }
194  }
195 
196  if(filter->request->cb_fn) {
197  filter->request->cb_fn(bus_ctx, &output, filter->request->priv);
198  }
199 
200  // remove all items, they are not needed anymore
201  amxc_var_clean(&output);
202 
203  amxc_var_for_each(subobj, subojects) {
204  amxc_string_setf(&path, "%s%s.", object, GET_CHAR(subobj, NULL));
205  amxb_ubus_list_object_describe(bus_ctx, amxc_string_get(&path, 0), filter);
206  }
207 
208 exit:
209  amxc_var_clean(&tmp);
210  amxc_string_clean(&path);
211  return rv;
212 }
static void amxb_ubus_fill_list(amxb_bus_ctx_t *bus_ctx, const char *path, amxc_var_t *data, const char *type, bool fetch_names, amxc_var_t *retval)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ amxb_ubus_object_depth()

static int32_t amxb_ubus_object_depth ( const char *  path)
static

Definition at line 72 of file amxb_ubus_list.c.

72  {
73  uint32_t length = path == NULL ? 0 : strlen(path);
74  int32_t depth = 0;
75  for(uint32_t i = 0; i < length; i++) {
76  if(path[i] == '.') {
77  depth++;
78  }
79  }
80 
81  return depth;
82 }
Here is the caller graph for this function:

◆ amxb_ubus_objects_cb()

static void amxb_ubus_objects_cb ( AMXB_UNUSED struct ubus_context *  c,
struct ubus_object_data *  o,
void *  p 
)
static

Definition at line 249 of file amxb_ubus_list.c.

251  {
252  ubus_filter_t* filter = (ubus_filter_t*) p;
253  const char* recv_path = NULL;
254  amxd_path_t path;
255  amxc_var_t retval;
256  amxc_var_t tmp;
257  uint32_t depth = 0;
258  amxb_bus_ctx_t* bus_ctx = amxb_request_get_ctx(filter->request);
259  bool functions = true;
260 
261  amxc_var_init(&retval);
262  amxc_var_init(&tmp);
263  amxc_var_set_type(&retval, AMXC_VAR_ID_LIST);
264  amxd_path_init(&path, NULL);
265  amxd_path_setf(&path, true, "%s", o->path);
266  recv_path = amxd_path_get(&path, AMXD_OBJECT_TERMINATE);
267  depth = amxd_path_get_depth(&path);
268 
269  if((filter->path_len != 0) &&
270  (strncmp(recv_path, filter->path, filter->path_len) != 0)) {
271  goto exit;
272  }
273 
274  if(depth < filter->depth) {
275  goto exit;
276  }
277 
278  if(depth > filter->depth) {
279  if((filter->flags & AMXB_FLAG_FIRST_LVL) != 0) {
280  if(amxb_ubus_has_function(o, "_describe")) {
281  amxb_ubus_path_to_depth(&path, filter, depth);
282  } else {
283  functions = false;
284  amxb_ubus_path_to_depth(&path, filter, filter->path == NULL? depth:depth - 1);
285  }
286  recv_path = amxd_path_get(&path, AMXD_OBJECT_TERMINATE);
287  }
288  }
289 
290  if(GET_ARG(&filter->objects, recv_path) != NULL) {
291  goto exit;
292  }
293 
294  if(amxb_ubus_add(recv_path, o, filter, &retval, functions) == 0) {
295  if(filter->request->cb_fn) {
296  filter->request->cb_fn(bus_ctx, &retval, filter->request->priv);
297  }
298  }
299  amxc_var_add_key(bool, &filter->objects, recv_path, true);
300 
301 exit:
302  amxc_var_clean(&tmp);
303  amxc_var_clean(&retval);
304  amxd_path_clean(&path);
305 }
static int amxb_ubus_add(const char *recv_path, struct ubus_object_data *o, ubus_filter_t *filter, amxc_var_t *output, bool functions)
static void amxb_ubus_path_to_depth(amxd_path_t *path, ubus_filter_t *filter, uint32_t depth)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ amxb_ubus_path_to_depth()

static void amxb_ubus_path_to_depth ( amxd_path_t *  path,
ubus_filter_t filter,
uint32_t  depth 
)
static

Definition at line 233 of file amxb_ubus_list.c.

235  {
236  while(depth > filter->depth) {
237  char* part = amxd_path_get_last(path, true);
238  free(part);
239  depth--;
240  }
241 }
Here is the caller graph for this function: