X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=libubus-sub.c;h=80d1f1ac542469aa782d35f690c5b5d68b3d10e0;hb=HEAD;hp=8793133ad05ec54802be86860e032aa10186a99c;hpb=47b38c98ae1690c3a4430b7850f207a4b9294896;p=project%2Fubus.git diff --git a/libubus-sub.c b/libubus-sub.c index 8793133..80d1f1a 100644 --- a/libubus-sub.c +++ b/libubus-sub.c @@ -31,14 +31,72 @@ const struct ubus_method watch_method __hidden = { .handler = ubus_subscriber_cb, }; +static void +ubus_auto_sub_event_handler_cb(struct ubus_context *ctx, struct ubus_event_handler *ev, + const char *type, struct blob_attr *msg) +{ + enum { + EVENT_ID, + EVENT_PATH, + __EVENT_MAX + }; + + static const struct blobmsg_policy event_policy[__EVENT_MAX] = { + [EVENT_ID] = { .name = "id", .type = BLOBMSG_TYPE_INT32 }, + [EVENT_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, + }; + + struct blob_attr *tb[__EVENT_MAX]; + struct ubus_subscriber *s; + const char *path; + int id; + + blobmsg_parse(event_policy, __EVENT_MAX, tb, blob_data(msg), blob_len(msg)); + + if (!tb[EVENT_ID] || !tb[EVENT_PATH]) + return; + + path = blobmsg_get_string(tb[EVENT_PATH]); + id = blobmsg_get_u32(tb[EVENT_ID]); + + list_for_each_entry(s, &ctx->auto_subscribers, list) + if (s->new_obj_cb(ctx, s, path)) + ubus_subscribe(ctx, s, id); +} + +static void +ubus_auto_sub_lookup(struct ubus_context *ctx, struct ubus_object_data *obj, + void *priv) +{ + struct ubus_subscriber *s = priv; + + if (s->new_obj_cb(ctx, s, obj->path)) + ubus_subscribe(ctx, s, obj->id); +} + int ubus_register_subscriber(struct ubus_context *ctx, struct ubus_subscriber *s) { struct ubus_object *obj = &s->obj; + int ret; + INIT_LIST_HEAD(&s->list); obj->methods = &watch_method; obj->n_methods = 1; - return ubus_add_object(ctx, obj); + ret = ubus_add_object(ctx, obj); + if (ret) + return ret; + + if (s->new_obj_cb) { + struct ubus_event_handler *ev = &ctx->auto_subscribe_event_handler; + list_add(&s->list, &ctx->auto_subscribers); + ev->cb = ubus_auto_sub_event_handler_cb; + if (!ev->obj.id) + ubus_register_event_handler(ctx, ev, "ubus.object.add"); + ubus_lookup(ctx, NULL, ubus_auto_sub_lookup, s); + } + + return 0; } static int