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