• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/ubus/libubus-sub.c

  1 /*
  2  * Copyright (C) 2011-2012 Felix Fietkau <nbd@openwrt.org>
  3  *
  4  * This program is free software; you can redistribute it and/or modify
  5  * it under the terms of the GNU Lesser General Public License version 2.1
  6  * as published by the Free Software Foundation
  7  *
  8  * This program is distributed in the hope that it will be useful,
  9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 11  * GNU General Public License for more details.
 12  */
 13 
 14 #include "libubus.h"
 15 #include "libubus-internal.h"
 16 
 17 static int ubus_subscriber_cb(struct ubus_context *ctx, struct ubus_object *obj,
 18                          struct ubus_request_data *req,
 19                          const char *method, struct blob_attr *msg)
 20 {
 21         struct ubus_subscriber *s;
 22 
 23         s = container_of(obj, struct ubus_subscriber, obj);
 24         if (s->cb)
 25                 return s->cb(ctx, obj, req, method, msg);
 26         return 0;
 27 }
 28 
 29 const struct ubus_method watch_method __hidden = {
 30         .name = NULL,
 31         .handler = ubus_subscriber_cb,
 32 };
 33 
 34 static void
 35 ubus_auto_sub_event_handler_cb(struct ubus_context *ctx,  struct ubus_event_handler *ev,
 36                                const char *type, struct blob_attr *msg)
 37 {
 38         enum {
 39                 EVENT_ID,
 40                 EVENT_PATH,
 41                 __EVENT_MAX
 42         };
 43 
 44         static const struct blobmsg_policy event_policy[__EVENT_MAX] = {
 45                 [EVENT_ID] = { .name = "id", .type = BLOBMSG_TYPE_INT32 },
 46                 [EVENT_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING },
 47         };
 48 
 49         struct blob_attr *tb[__EVENT_MAX];
 50         struct ubus_subscriber *s;
 51         const char *path;
 52         int id;
 53 
 54         blobmsg_parse(event_policy, __EVENT_MAX, tb, blob_data(msg), blob_len(msg));
 55 
 56         if (!tb[EVENT_ID] || !tb[EVENT_PATH])
 57                 return;
 58 
 59         path = blobmsg_get_string(tb[EVENT_PATH]);
 60         id = blobmsg_get_u32(tb[EVENT_ID]);
 61 
 62         list_for_each_entry(s, &ctx->auto_subscribers, list)
 63                 if (s->new_obj_cb(ctx, s, path))
 64                         ubus_subscribe(ctx, s, id);
 65 }
 66 
 67 static void
 68 ubus_auto_sub_lookup(struct ubus_context *ctx, struct ubus_object_data *obj,
 69                      void *priv)
 70 {
 71         struct ubus_subscriber *s = priv;
 72 
 73         if (s->new_obj_cb(ctx, s, obj->path))
 74                 ubus_subscribe(ctx, s, obj->id);
 75 }
 76 
 77 int ubus_register_subscriber(struct ubus_context *ctx, struct ubus_subscriber *s)
 78 {
 79         struct ubus_object *obj = &s->obj;
 80         int ret;
 81 
 82         INIT_LIST_HEAD(&s->list);
 83         obj->methods = &watch_method;
 84         obj->n_methods = 1;
 85 
 86         ret = ubus_add_object(ctx, obj);
 87         if (ret)
 88                 return ret;
 89 
 90         if (s->new_obj_cb) {
 91                 struct ubus_event_handler *ev = &ctx->auto_subscribe_event_handler;
 92                 list_add(&s->list, &ctx->auto_subscribers);
 93                 ev->cb = ubus_auto_sub_event_handler_cb;
 94                 if (!ev->obj.id)
 95                         ubus_register_event_handler(ctx, ev, "ubus.object.add");
 96                 ubus_lookup(ctx, NULL, ubus_auto_sub_lookup, s);
 97         }
 98 
 99         return 0;
100 }
101 
102 static int
103 __ubus_subscribe_request(struct ubus_context *ctx, struct ubus_object *obj, uint32_t id, int type)
104 {
105         struct ubus_request req;
106 
107         blob_buf_init(&b, 0);
108         blob_put_int32(&b, UBUS_ATTR_OBJID, obj->id);
109         blob_put_int32(&b, UBUS_ATTR_TARGET, id);
110 
111         if (ubus_start_request(ctx, &req, b.head, type, 0) < 0)
112                 return UBUS_STATUS_INVALID_ARGUMENT;
113 
114         return ubus_complete_request(ctx, &req, 0);
115 
116 }
117 
118 int ubus_subscribe(struct ubus_context *ctx, struct ubus_subscriber *obj, uint32_t id)
119 {
120         return __ubus_subscribe_request(ctx, &obj->obj, id, UBUS_MSG_SUBSCRIBE);
121 }
122 
123 int ubus_unsubscribe(struct ubus_context *ctx, struct ubus_subscriber *obj, uint32_t id)
124 {
125         return __ubus_subscribe_request(ctx, &obj->obj, id, UBUS_MSG_UNSUBSCRIBE);
126 }
127 
128 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt