73 uint32_t length = path == NULL ? 0 : strlen(path);
75 for(uint32_t i = 0; i < length; i++) {
86 struct blob_attr* cur;
90 when_null(o->signature, exit);
91 blob_for_each_attr(cur, o->signature, rem) {
93 if(strcmp(func_name, blobmsg_name(cur)) == 0) {
106 amxc_var_t* retval) {
107 if(o->signature && ((filter->
flags & AMXB_FLAG_FUNCTIONS) != 0)) {
108 struct blob_attr* cur;
112 blob_for_each_attr(cur, o->signature, rem) {
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);
128 amxc_var_t* retval) {
130 amxc_string_init(&name, 0);
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));
137 amxc_string_setf(&name,
"%s%s", path, GET_CHAR(d, NULL));
139 amxc_var_add(cstring_t, retval, amxc_string_get(&name, 0));
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);
150 amxc_string_clean(&name);
159 amxc_var_t* subojects = NULL;
162 amxc_string_init(&path, 0);
165 rv = amxb_describe(
bus_ctx,
object, filter->
flags, &tmp, 5);
166 when_failed(rv, exit);
168 amxc_var_init(&output);
169 amxc_var_set_type(&output, AMXC_VAR_ID_LIST);
170 amxc_var_add(cstring_t, &output,
object);
172 if(GETP_UINT32(&tmp,
"0.type_id") != 2) {
173 if((filter->
flags & AMXB_FLAG_PARAMETERS) != 0) {
176 if((filter->
flags & AMXB_FLAG_FUNCTIONS) != 0) {
179 if((filter->
flags & AMXB_FLAG_OBJECTS) != 0) {
180 if(filter->
flags & AMXB_FLAG_FIRST_LVL) {
183 subojects = GETP_ARG(&tmp,
"0.objects");
187 if((filter->
flags & AMXB_FLAG_INSTANCES) != 0) {
188 if(filter->
flags & AMXB_FLAG_FIRST_LVL) {
191 subojects = GETP_ARG(&tmp,
"0.instances");
201 amxc_var_clean(&output);
203 amxc_var_for_each(subobj, subojects) {
204 amxc_string_setf(&path,
"%s%s.",
object, GET_CHAR(subobj, NULL));
209 amxc_var_clean(&tmp);
210 amxc_string_clean(&path);
215 struct ubus_object_data* o,
221 amxc_var_add(cstring_t, &filter->
amx_paths, recv_path);
223 amxc_var_add(cstring_t, output, recv_path);
236 while(depth > filter->
depth) {
237 char* part = amxd_path_get_last(path,
true);
250 struct ubus_object_data* o,
253 const char* recv_path = NULL;
259 bool functions =
true;
261 amxc_var_init(&retval);
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);
270 (strncmp(recv_path, filter->
path, filter->
path_len) != 0)) {
274 if(depth < filter->depth) {
278 if(depth > filter->
depth) {
279 if((filter->
flags & AMXB_FLAG_FIRST_LVL) != 0) {
286 recv_path = amxd_path_get(&path, AMXD_OBJECT_TERMINATE);
290 if(GET_ARG(&filter->
objects, recv_path) != NULL) {
294 if(
amxb_ubus_add(recv_path, o, filter, &retval, functions) == 0) {
299 amxc_var_add_key(
bool, &filter->
objects, recv_path,
true);
302 amxc_var_clean(&tmp);
303 amxc_var_clean(&retval);
304 amxd_path_clean(&path);
312 if(
object[strlen(
object) - 1] ==
'.') {
315 filter->
path = object;
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),
326 amxc_string_clean(&path);
336 amxb_request_t* request) {
337 amxb_bus_ctx_t*
bus_ctx = NULL;
343 filter.
flags = flags;
346 amxc_var_set_type(&filter.
amx_paths, AMXC_VAR_ID_LIST);
347 amxc_var_set_type(&filter.
objects, AMXC_VAR_ID_HTABLE);
349 bus_ctx = amxb_request_get_ctx(request);
350 if((
object == NULL) || (*
object == 0)) {
352 filter.
flags &= ~(AMXB_FLAG_OBJECTS | AMXB_FLAG_INSTANCES);
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);
359 request->cb_fn(
bus_ctx, NULL, request->priv);
361 filter.
flags |= (AMXB_FLAG_OBJECTS | AMXB_FLAG_INSTANCES);
365 filter.
flags &= ~(AMXB_FLAG_OBJECTS | AMXB_FLAG_INSTANCES);
367 amxc_var_for_each(path, &filter.
amx_paths) {
368 const char* p = GET_CHAR(path, NULL);
372 request->cb_fn(
bus_ctx, NULL, request->priv);
375 amxc_var_clean(&filter.
objects);
377 amxb_close_request(&request);
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_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_native(amxb_ubus_t *amxb_ubus_ctx, const char *object, ubus_filter_t *filter)
static void amxb_ubus_path_to_depth(amxd_path_t *path, ubus_filter_t *filter, uint32_t depth)
static void amxb_ubus_add_functions(struct ubus_object_data *o, ubus_filter_t *filter, const char *path, amxc_var_t *retval)
struct _ubus_filter ubus_filter_t
static void amxb_ubus_objects_cb(AMXB_UNUSED struct ubus_context *c, struct ubus_object_data *o, void *p)
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)
int amxb_ubus_list(void *const ctx, const char *object, uint32_t flags, uint32_t access, amxb_request_t *request)
struct ubus_context * ubus_ctx
static amxb_bus_ctx_t * bus_ctx