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

Sources/ubus/libubus.h

  1 /*
  2  * Copyright (C) 2011-2014 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 #ifndef __LIBUBUS_H
 15 #define __LIBUBUS_H
 16 
 17 #ifdef __cplusplus
 18 extern "C" {
 19 #endif
 20 
 21 #include <libubox/avl.h>
 22 #include <libubox/list.h>
 23 #include <libubox/blobmsg.h>
 24 #include <libubox/uloop.h>
 25 #include <stdint.h>
 26 #include "ubusmsg.h"
 27 #include "ubus_common.h"
 28 
 29 #define UBUS_MAX_NOTIFY_PEERS   16
 30 
 31 struct ubus_context;
 32 struct ubus_msg_src;
 33 struct ubus_object;
 34 struct ubus_request;
 35 struct ubus_request_data;
 36 struct ubus_object_data;
 37 struct ubus_event_handler;
 38 struct ubus_subscriber;
 39 struct ubus_notify_request;
 40 
 41 struct ubus_msghdr_buf {
 42         struct ubus_msghdr hdr;
 43         struct blob_attr *data;
 44 };
 45 
 46 typedef void (*ubus_lookup_handler_t)(struct ubus_context *ctx,
 47                                       struct ubus_object_data *obj,
 48                                       void *priv);
 49 typedef int (*ubus_handler_t)(struct ubus_context *ctx, struct ubus_object *obj,
 50                               struct ubus_request_data *req,
 51                               const char *method, struct blob_attr *msg);
 52 typedef void (*ubus_state_handler_t)(struct ubus_context *ctx, struct ubus_object *obj);
 53 typedef void (*ubus_remove_handler_t)(struct ubus_context *ctx,
 54                                       struct ubus_subscriber *obj, uint32_t id);
 55 typedef void (*ubus_event_handler_t)(struct ubus_context *ctx, struct ubus_event_handler *ev,
 56                                      const char *type, struct blob_attr *msg);
 57 typedef void (*ubus_data_handler_t)(struct ubus_request *req,
 58                                     int type, struct blob_attr *msg);
 59 typedef void (*ubus_fd_handler_t)(struct ubus_request *req, int fd);
 60 typedef void (*ubus_complete_handler_t)(struct ubus_request *req, int ret);
 61 typedef void (*ubus_notify_complete_handler_t)(struct ubus_notify_request *req,
 62                                                int idx, int ret);
 63 typedef void (*ubus_notify_data_handler_t)(struct ubus_notify_request *req,
 64                                            int type, struct blob_attr *msg);
 65 typedef void (*ubus_connect_handler_t)(struct ubus_context *ctx);
 66 typedef bool (*ubus_new_object_handler_t)(struct ubus_context *ctx, struct ubus_subscriber *sub, const char *path);
 67 
 68 #define UBUS_OBJECT_TYPE(_name, _methods)               \
 69         {                                               \
 70                 .name = _name,                          \
 71                 .id = 0,                                \
 72                 .methods = _methods,                    \
 73                 .n_methods = ARRAY_SIZE(_methods)       \
 74         }
 75 
 76 #define __UBUS_METHOD_BASE(_name, _handler, _mask, _tags)       \
 77         .name = _name,                                          \
 78         .handler = _handler,                                    \
 79         .mask = _mask,                                          \
 80         .tags = _tags
 81 
 82 #define __UBUS_METHOD_NOARG(_name, _handler, _mask, _tags)      \
 83         __UBUS_METHOD_BASE(_name, _handler, _mask, _tags),      \
 84         .policy = NULL,                                         \
 85         .n_policy = 0
 86 
 87 #define __UBUS_METHOD(_name, _handler, _mask, _policy, _tags)   \
 88         __UBUS_METHOD_BASE(_name, _handler, _mask, _tags),      \
 89         .policy = _policy,                                      \
 90         .n_policy = ARRAY_SIZE(_policy)
 91 
 92 #define UBUS_METHOD(_name, _handler, _policy)           \
 93         { __UBUS_METHOD(_name, _handler, 0, _policy, 0) }
 94 
 95 #define UBUS_METHOD_TAG(_name, _handler, _policy, _tags)\
 96         { __UBUS_METHOD(_name, _handler, 0, _policy, _tags) }
 97 
 98 #define UBUS_METHOD_MASK(_name, _handler, _policy, _mask) \
 99         { __UBUS_METHOD(_name, _handler, _mask, _policy, 0) }
100 
101 #define UBUS_METHOD_NOARG(_name, _handler)              \
102         { __UBUS_METHOD_NOARG(_name, _handler, 0, 0) }
103 
104 #define UBUS_METHOD_TAG_NOARG(_name, _handler, _tags)   \
105         { __UBUS_METHOD_NOARG(_name, _handler, 0, _tags) }
106 
107 #define UBUS_TAG_STATUS         (1ul << 0)
108 #define UBUS_TAG_ADMIN          (1ul << 1)
109 #define UBUS_TAG_PRIVATE        (1ul << 2)
110 
111 struct ubus_method {
112         const char *name;
113         ubus_handler_t handler;
114 
115         unsigned long mask;
116         unsigned long tags;
117         const struct blobmsg_policy *policy;
118         int n_policy;
119 };
120 
121 struct ubus_object_type {
122         const char *name;
123         uint32_t id;
124 
125         const struct ubus_method *methods;
126         int n_methods;
127 };
128 
129 struct ubus_object {
130         struct avl_node avl;
131 
132         const char *name;
133         uint32_t id;
134 
135         const char *path;
136         struct ubus_object_type *type;
137 
138         ubus_state_handler_t subscribe_cb;
139         bool has_subscribers;
140 
141         const struct ubus_method *methods;
142         int n_methods;
143 };
144 
145 struct ubus_subscriber {
146         struct list_head list;
147         struct ubus_object obj;
148 
149         ubus_handler_t cb;
150         ubus_remove_handler_t remove_cb;
151         ubus_new_object_handler_t new_obj_cb;
152 };
153 
154 struct ubus_event_handler {
155         struct ubus_object obj;
156 
157         ubus_event_handler_t cb;
158 };
159 
160 struct ubus_context {
161         struct list_head requests;
162         struct avl_tree objects;
163         struct list_head pending;
164 
165         struct uloop_fd sock;
166         struct uloop_timeout pending_timer;
167 
168         uint32_t local_id;
169         uint16_t request_seq;
170         bool cancel_poll;
171         int stack_depth;
172 
173         void (*connection_lost)(struct ubus_context *ctx);
174         void (*monitor_cb)(struct ubus_context *ctx, uint32_t seq, struct blob_attr *data);
175 
176         struct ubus_msghdr_buf msgbuf;
177         uint32_t msgbuf_data_len;
178         int msgbuf_reduction_counter;
179 
180         union {
181                 struct {
182                         struct list_head auto_subscribers;
183                         struct ubus_event_handler auto_subscribe_event_handler;
184                 };
185                 struct {
186                         ubus_handler_t request_handler;
187                 };
188         };
189 };
190 
191 struct ubus_object_data {
192         uint32_t id;
193         uint32_t type_id;
194         const char *path;
195         struct blob_attr *signature;
196 };
197 
198 struct ubus_acl_key {
199         const char *user;
200         const char *group;
201         const char *object;
202 };
203 
204 struct ubus_request_data {
205         uint32_t object;
206         uint32_t peer;
207         uint16_t seq;
208 
209         struct ubus_acl_key acl;
210 
211         /* internal use */
212         bool deferred;
213         int fd;
214         int req_fd; /* fd received from the initial request */
215 };
216 
217 struct ubus_request {
218         struct list_head list;
219 
220         struct list_head pending;
221         int status_code;
222         bool status_msg;
223         bool blocked;
224         bool cancelled;
225         bool notify;
226 
227         uint32_t peer;
228         uint16_t seq;
229 
230         ubus_data_handler_t raw_data_cb;
231         ubus_data_handler_t data_cb;
232         ubus_fd_handler_t fd_cb;
233         ubus_complete_handler_t complete_cb;
234 
235         int fd;
236 
237         struct ubus_context *ctx;
238         void *priv;
239 };
240 
241 struct ubus_notify_request {
242         struct ubus_request req;
243 
244         ubus_notify_complete_handler_t status_cb;
245         ubus_notify_complete_handler_t complete_cb;
246         ubus_notify_data_handler_t data_cb;
247 
248         uint32_t pending;
249         uint32_t id[UBUS_MAX_NOTIFY_PEERS + 1];
250 };
251 
252 struct ubus_auto_conn {
253         struct ubus_context ctx;
254         struct uloop_timeout timer;
255         const char *path;
256         ubus_connect_handler_t cb;
257 };
258 
259 struct ubus_context *ubus_connect(const char *path);
260 int ubus_connect_ctx(struct ubus_context *ctx, const char *path);
261 void ubus_auto_connect(struct ubus_auto_conn *conn);
262 int ubus_reconnect(struct ubus_context *ctx, const char *path);
263 int ubus_channel_connect(struct ubus_context *ctx, int fd,
264                          ubus_handler_t handler);
265 int ubus_channel_create(struct ubus_context *ctx, int *remote_fd,
266                         ubus_handler_t handler);
267 void ubus_flush_requests(struct ubus_context *ctx);
268 
269 static inline bool
270 ubus_context_is_channel(struct ubus_context *ctx)
271 {
272     return ctx->local_id == UBUS_CLIENT_ID_CHANNEL;
273 }
274 
275 /* call this only for struct ubus_context pointers returned by ubus_connect() */
276 void ubus_free(struct ubus_context *ctx);
277 
278 /* call this only for struct ubus_context pointers initialised by ubus_connect_ctx() */
279 void ubus_shutdown(struct ubus_context *ctx);
280 
281 static inline void ubus_auto_shutdown(struct ubus_auto_conn *conn)
282 {
283         uloop_timeout_cancel(&conn->timer);
284         ubus_shutdown(&conn->ctx);
285 }
286 
287 const char *ubus_strerror(int error);
288 
289 static inline void ubus_add_uloop(struct ubus_context *ctx)
290 {
291         uloop_fd_add(&ctx->sock, ULOOP_BLOCKING | ULOOP_READ);
292 }
293 
294 /* call this for read events on ctx->sock.fd when not using uloop */
295 static inline void ubus_handle_event(struct ubus_context *ctx)
296 {
297         ctx->sock.cb(&ctx->sock, ULOOP_READ);
298 }
299 
300 /* ----------- raw request handling ----------- */
301 
302 /* wait for a request to complete and return its status */
303 int ubus_complete_request(struct ubus_context *ctx, struct ubus_request *req,
304                           int timeout);
305 
306 /* complete a request asynchronously */
307 void ubus_complete_request_async(struct ubus_context *ctx,
308                                  struct ubus_request *req);
309 
310 /* abort an asynchronous request */
311 void ubus_abort_request(struct ubus_context *ctx, struct ubus_request *req);
312 
313 /* ----------- objects ----------- */
314 
315 int ubus_lookup(struct ubus_context *ctx, const char *path,
316                 ubus_lookup_handler_t cb, void *priv);
317 
318 int ubus_lookup_id(struct ubus_context *ctx, const char *path, uint32_t *id);
319 
320 /* make an object visible to remote connections */
321 int ubus_add_object(struct ubus_context *ctx, struct ubus_object *obj);
322 
323 /* remove the object from the ubus connection */
324 int ubus_remove_object(struct ubus_context *ctx, struct ubus_object *obj);
325 
326 /* add a subscriber notifications from another object */
327 int ubus_register_subscriber(struct ubus_context *ctx, struct ubus_subscriber *obj);
328 
329 static inline int
330 ubus_unregister_subscriber(struct ubus_context *ctx, struct ubus_subscriber *obj)
331 {
332         if (!list_empty(&obj->list))
333                 list_del_init(&obj->list);
334         return ubus_remove_object(ctx, &obj->obj);
335 }
336 
337 int ubus_subscribe(struct ubus_context *ctx, struct ubus_subscriber *obj, uint32_t id);
338 int ubus_unsubscribe(struct ubus_context *ctx, struct ubus_subscriber *obj, uint32_t id);
339 
340 int __ubus_monitor(struct ubus_context *ctx, const char *type);
341 
342 static inline int ubus_monitor_start(struct ubus_context *ctx)
343 {
344         return __ubus_monitor(ctx, "add");
345 }
346 
347 static inline int ubus_monitor_stop(struct ubus_context *ctx)
348 {
349         return __ubus_monitor(ctx, "remove");
350 }
351 
352 
353 /* ----------- acl ----------- */
354 
355 struct acl_object {
356         struct ubus_acl_key key;
357         struct avl_node avl;
358         struct blob_attr *acl;
359 };
360 
361 extern struct avl_tree acl_objects;
362 int ubus_register_acl(struct ubus_context *ctx);
363 
364 #define acl_for_each(o, m) \
365         if ((m)->object && (m)->user && (m)->group) \
366                 avl_for_element_range(avl_find_ge_element(&acl_objects, m, o, avl), avl_find_le_element(&acl_objects, m, o, avl), o, avl)
367 
368 /* ----------- rpc ----------- */
369 
370 /* invoke a method on a specific object */
371 int ubus_invoke_fd(struct ubus_context *ctx, uint32_t obj, const char *method,
372                 struct blob_attr *msg, ubus_data_handler_t cb, void *priv,
373                 int timeout, int fd);
374 static inline int
375 ubus_invoke(struct ubus_context *ctx, uint32_t obj, const char *method,
376             struct blob_attr *msg, ubus_data_handler_t cb, void *priv,
377             int timeout)
378 {
379         return ubus_invoke_fd(ctx, obj, method, msg, cb, priv, timeout, -1);
380 }
381 
382 /* asynchronous version of ubus_invoke() */
383 int ubus_invoke_async_fd(struct ubus_context *ctx, uint32_t obj, const char *method,
384                       struct blob_attr *msg, struct ubus_request *req, int fd);
385 static inline int
386 ubus_invoke_async(struct ubus_context *ctx, uint32_t obj, const char *method,
387                   struct blob_attr *msg, struct ubus_request *req)
388 {
389         return ubus_invoke_async_fd(ctx, obj, method, msg, req, -1);
390 }
391 
392 /* send a reply to an incoming object method call */
393 int ubus_send_reply(struct ubus_context *ctx, struct ubus_request_data *req,
394                     struct blob_attr *msg);
395 
396 static inline void ubus_defer_request(struct ubus_context *ctx,
397                                       struct ubus_request_data *req,
398                                       struct ubus_request_data *new_req)
399 {
400     (void) ctx;
401     memcpy(new_req, req, sizeof(*req));
402     req->deferred = true;
403 }
404 
405 static inline void ubus_request_set_fd(struct ubus_context *ctx,
406                                        struct ubus_request_data *req, int fd)
407 {
408     (void) ctx;
409     req->fd = fd;
410 }
411 
412 static inline int ubus_request_get_caller_fd(struct ubus_request_data *req)
413 {
414     int fd = req->req_fd;
415     req->req_fd = -1;
416     
417     return fd;
418 }
419 
420 void ubus_complete_deferred_request(struct ubus_context *ctx,
421                                     struct ubus_request_data *req, int ret);
422 
423 /*
424  * send a notification to all subscribers of an object
425  * if timeout < 0, no reply is expected from subscribers
426  */
427 int ubus_notify(struct ubus_context *ctx, struct ubus_object *obj,
428                 const char *type, struct blob_attr *msg, int timeout);
429 
430 int ubus_notify_async(struct ubus_context *ctx, struct ubus_object *obj,
431                       const char *type, struct blob_attr *msg,
432                       struct ubus_notify_request *req);
433 
434 
435 /* ----------- events ----------- */
436 
437 int ubus_send_event(struct ubus_context *ctx, const char *id,
438                     struct blob_attr *data);
439 
440 int ubus_register_event_handler(struct ubus_context *ctx,
441                                 struct ubus_event_handler *ev,
442                                 const char *pattern);
443 
444 static inline int ubus_unregister_event_handler(struct ubus_context *ctx,
445                                                 struct ubus_event_handler *ev)
446 {
447     return ubus_remove_object(ctx, &ev->obj);
448 }
449 
450 #ifdef __cplusplus
451 }
452 #endif
453 
454 #endif
455 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt