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