56 #include <sys/types.h>
60 #include <amxc/amxc_string_split.h>
65 #include <amxb_ubus_version.h>
72 amxc_htable_it_t* it) {
80 amxc_var_t* uris = GET_ARG(configuration,
"uris");
84 if((configuration != NULL) && (uris == NULL)) {
85 uris = amxc_var_add_key(amxc_llist_t, configuration,
"uris", NULL);
88 if(stat(
"/var/run/ubus.sock", &sb) == 0) {
89 amxc_var_add(cstring_t, uris,
"ubus:/var/run/ubus.sock");
91 if(stat(
"/var/run/ubus/ubus.sock", &sb) == 0) {
92 amxc_var_add(cstring_t, uris,
"ubus:/var/run/ubus/ubus.sock");
99 amxb_bus_ctx_t*
bus_ctx = amxc_llist_it_get_data(lit, amxb_bus_ctx_t, it);
105 amxc_htable_t* subscribers = NULL;
107 const char* path = NULL;
110 subscribers = container_of(amxb_ubus_sub->
it.ait->array, amxc_htable_t, table);
111 amxb_ubus_ctx = container_of(subscribers,
amxb_ubus_t, subscribers);
112 path = amxc_htable_it_get_key(&amxb_ubus_sub->
it);
114 amxc_htable_it_take(&amxb_ubus_sub->
it);
115 ret = ubus_unregister_subscriber(amxb_ubus_ctx->
ubus_ctx, &amxb_ubus_sub->
sub);
116 when_failed(ret, exit);
120 amxp_timer_delete(&amxb_ubus_sub->
reactivate);
121 amxc_htable_it_clean(&amxb_ubus_sub->
it, NULL);
126 struct ubus_event_handler* ev,
127 UNUSED
const char* type,
128 struct blob_attr* msg) {
130 amxc_var_t watch_event;
131 amxc_htable_it_t* it = NULL;
132 const char* p = NULL;
134 amxc_string_t signal_name;
136 amxc_string_init(&signal_name, 0);
137 amxc_var_init(&watch_event);
138 amxc_var_set_type(&watch_event, AMXC_VAR_ID_HTABLE);
140 (
struct blob_attr*) blob_data(msg),
143 p = GET_CHAR(&watch_event,
"path");
144 amxc_string_setf(&signal_name,
"wait:%s.", p);
145 amxp_sigmngr_trigger_signal(NULL, amxc_string_get(&signal_name, 0), NULL);
147 it = amxc_htable_get(&amxb_ubus_ctx->
subscribers, p);
156 amxp_timer_start(amxb_ubus_sub->
reactivate, 100);
159 amxc_string_clean(&signal_name);
160 amxc_var_clean(&watch_event);
165 amxc_string_t* path = amxc_string_from_llist_it(it);
166 amxp_sigmngr_emit_signal(NULL, amxc_string_get(path, 0), NULL);
167 amxc_string_delete(&path);
174 UNUSED
struct ubus_event_handler* ev,
175 UNUSED
const char* type,
176 struct blob_attr* msg) {
177 amxc_var_t watch_event;
178 amxc_string_t* sig_name = NULL;
180 amxc_var_init(&watch_event);
181 amxc_var_set_type(&watch_event, AMXC_VAR_ID_HTABLE);
183 (
struct blob_attr*) blob_data(msg),
186 amxc_string_new(&sig_name, 0);
187 amxc_string_setf(sig_name,
"wait:%s.", GET_CHAR(&watch_event,
"path"));
188 if(amxp_sigmngr_find_signal(NULL, amxc_string_get(sig_name, 0)) != NULL) {
195 amxc_string_delete(&sig_name);
197 amxc_var_clean(&watch_event);
201 UNUSED
const amxc_var_t*
const data,
205 if(amxb_ubus_ctx->
watcher.cb == NULL) {
207 ubus_register_event_handler(amxb_ubus_ctx->
ubus_ctx,
208 &amxb_ubus_ctx->
watcher,
"ubus.object.add");
211 if(amxb_ubus_ctx->
watcher.cb != NULL) {
212 ubus_unregister_event_handler(amxb_ubus_ctx->
ubus_ctx, &amxb_ubus_ctx->
watcher);
213 amxb_ubus_ctx->
watcher.cb = NULL;
228 when_not_null(host, exit);
229 when_not_null(port, exit);
232 when_null(amxb_ubus_ctx, exit);
234 amxb_ubus_ctx->
ubus_ctx = ubus_connect(path);
235 if(amxb_ubus_ctx->
ubus_ctx == NULL) {
237 amxb_ubus_ctx = NULL;
242 blob_buf_init(&amxb_ubus_ctx->
b, 0);
249 ubus_register_event_handler(amxb_ubus_ctx->
ubus_ctx,
250 &amxb_ubus_ctx->
watcher,
"ubus.object.add");
252 amxp_slot_connect(NULL,
259 return amxb_ubus_ctx;
265 when_null(amxb_ubus_ctx, exit);
266 when_null(amxb_ubus_ctx->
ubus_ctx, exit);
268 amxp_slot_disconnect_with_priv(NULL,
275 blob_buf_free(&amxb_ubus_ctx->
b);
286 when_null(amxb_ubus_ctx, exit);
287 when_null(amxb_ubus_ctx->
ubus_ctx, exit);
289 fd = amxb_ubus_ctx->
ubus_ctx->sock.fd;
297 struct ubus_context* ubus_ctx = NULL;
300 when_null(amxb_ubus_ctx, exit);
301 when_null(amxb_ubus_ctx->
ubus_ctx, exit);
304 ubus_ctx->sock.cb(&ubus_ctx->sock, ULOOP_READ);
306 if(ubus_ctx->sock.eof) {
319 when_null(amxb_ubus_ctx, exit);
328 UNUSED
const amxc_var_t*
const d,
342 when_null(amxb_ubus_ctx, exit);
345 ubus_register_event_handler(amxb_ubus_ctx->
ubus_ctx,
357 return AMXB_BE_DISCOVER | AMXB_BE_DISCOVER_RESOLVE;
363 bool has_object =
false;
365 when_null(
object, exit);
367 retval = ubus_lookup_id(amxb_ubus_ctx->
ubus_ctx,
object, &
id);
369 when_failed(retval, exit);
371 has_object = (
id != 0);
378 .it = { .ait = NULL, .key = NULL, .next = NULL },
380 .connections = { .head = NULL, .tail = NULL },
382 .size =
sizeof(amxb_be_funcs_t),
401 .get_supported = NULL,
411 .get_instances = NULL,
412 .get_filtered = NULL,
428 .major = AMXB_UBUS_VERSION_MAJOR,
429 .minor = AMXB_UBUS_VERSION_MINOR,
430 .build = AMXB_UBUS_VERSION_BUILD,
438 .description =
"AMXB Backend for UBUS (Openwrt/Prplwrt)",
int PRIVATE amxb_ubus_disconnect(void *ctx)
static void amxb_ubus_remove_sub(AMXB_UNUSED const char *key, amxc_htable_it_t *it)
static int amxb_ubus_set_config(amxc_var_t *const configuration)
static int amxb_ubus_wait_for(void *const ctx, UNUSED const char *object)
static void amxb_ubus_remove_connections(amxc_llist_it_t *lit)
static const amxc_var_t * config_opts
static void amxb_ubus_reactivate_subscription(UNUSED amxp_timer_t *timer, void *priv)
amxb_be_info_t * amxb_be_info(void)
void PRIVATE amxb_ubus_free(void *ctx)
static amxb_version_t ubus_be_version
amxb_be_info_t amxb_ubus_be_info
static uint32_t amxb_ubus_capabilities(UNUSED void *ctx)
static void amxb_ubus_watcher(UNUSED struct ubus_context *ctx, struct ubus_event_handler *ev, UNUSED const char *type, struct blob_attr *msg)
static void amxb_ubus_config_changed(UNUSED const char *const sig_name, UNUSED const amxc_var_t *const data, void *const priv)
int amxb_be_ubus_clean(void)
static amxp_timer_t * wait_timer
int PRIVATE amxb_ubus_read(void *ctx)
static bool amxb_ubus_has(void *ctx, const char *object)
int amxb_be_ubus_init(void)
int PRIVATE amxb_ubus_get_fd(void *ctx)
const amxc_var_t * amxb_ubus_get_config_option(const char *name)
static void amxb_ubus_object_available(UNUSED amxp_timer_t *timer, UNUSED void *priv)
static void amxb_ubus_wait_watcher(UNUSED struct ubus_context *ctx, UNUSED struct ubus_event_handler *ev, UNUSED const char *type, struct blob_attr *msg)
void *PRIVATE amxb_ubus_connect(const char *host, const char *port, const char *path, amxp_signal_mngr_t *sigmngr)
static amxc_llist_t avaiable_paths
static amxb_be_funcs_t amxb_ubus_impl
static amxb_version_t sup_max_lib_version
static void amxb_ubus_wait_for_done(UNUSED const char *const sig_name, UNUSED const amxc_var_t *const d, void *const priv)
static amxb_version_t sup_min_lib_version
void PRIVATE amxb_ubus_obj_it_free(amxc_llist_it_t *it)
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_invoke(void *const ctx, amxb_invoke_t *invoke_ctx, amxc_var_t *args, amxb_request_t *request, int timeout)
int PRIVATE amxb_ubus_list(void *const bus_ctx, const char *object, uint32_t flags, uint32_t access, amxb_request_t *request)
int PRIVATE amxb_ubus_unsubscribe(void *const ctx, const char *object)
int PRIVATE amxb_ubus_subscribe(void *const ctx, const char *object)
int PRIVATE amxb_ubus_register(void *const ctx, amxd_dm_t *const dm)
int PRIVATE amxb_ubus_parse_blob_table(amxc_var_t *var, struct blob_attr *attr, int len)
int PRIVATE amxb_ubus_async_invoke(void *const ctx, amxb_invoke_t *invoke_ctx, amxc_var_t *args, amxb_request_t *request)
void PRIVATE amxb_ubus_cancel_requests(amxb_ubus_t *amxb_ubus_ctx)
amxp_timer_t * reactivate
struct ubus_subscriber sub
struct ubus_event_handler wait_watcher
amxc_htable_t subscribers
amxc_llist_t pending_reqs
struct ubus_event_handler watcher
amxc_llist_t registered_objs
struct ubus_context * ubus_ctx
amxp_signal_mngr_t * sigmngr
static amxp_signal_mngr_t * sigmngr
static amxb_bus_ctx_t * bus_ctx