make the socket non-blocking, explicitly wait for data using poll()
[project/ubus.git] / libubus.c
1 /*
2  * Copyright (C) 2011 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 <sys/types.h>
15 #include <sys/uio.h>
16 #include <sys/socket.h>
17 #include <fcntl.h>
18 #include <unistd.h>
19 #include <poll.h>
20
21 #include <libubox/blob.h>
22 #include <libubox/blobmsg.h>
23 #include <libubox/usock.h>
24
25 #include "libubus.h"
26 #include "ubusmsg.h"
27
28 #define STATIC_IOV(_var) { .iov_base = (char *) &(_var), .iov_len = sizeof(_var) }
29
30 const char *__ubus_strerror[__UBUS_STATUS_LAST] = {
31         [UBUS_STATUS_OK] = "Success",
32         [UBUS_STATUS_INVALID_COMMAND] = "Invalid command",
33         [UBUS_STATUS_INVALID_ARGUMENT] = "Invalid argument",
34         [UBUS_STATUS_METHOD_NOT_FOUND] = "Method not found",
35         [UBUS_STATUS_NOT_FOUND] = "Not found",
36         [UBUS_STATUS_NO_DATA] = "No response",
37         [UBUS_STATUS_PERMISSION_DENIED] = "Permission denied",
38         [UBUS_STATUS_TIMEOUT] = "Request timed out",
39         [UBUS_STATUS_NOT_SUPPORTED] = "Operation not supported",
40         [UBUS_STATUS_UNKNOWN_ERROR] = "Unknown error",
41 };
42
43 static struct blob_buf b;
44
45 static const struct blob_attr_info ubus_policy[UBUS_ATTR_MAX] = {
46         [UBUS_ATTR_STATUS] = { .type = BLOB_ATTR_INT32 },
47         [UBUS_ATTR_OBJID] = { .type = BLOB_ATTR_INT32 },
48         [UBUS_ATTR_OBJPATH] = { .type = BLOB_ATTR_STRING },
49         [UBUS_ATTR_METHOD] = { .type = BLOB_ATTR_STRING },
50 };
51 static struct blob_attr *attrbuf[UBUS_ATTR_MAX];
52
53 struct ubus_pending_data {
54         struct list_head list;
55         int type;
56         struct blob_attr data[];
57 };
58
59 static int ubus_cmp_id(const void *k1, const void *k2, void *ptr)
60 {
61         const uint32_t *id1 = k1, *id2 = k2;
62
63         if (*id1 < *id2)
64                 return -1;
65         else
66                 return *id1 > *id2;
67 }
68
69 static struct blob_attr **ubus_parse_msg(struct blob_attr *msg)
70 {
71         blob_parse(msg, attrbuf, ubus_policy, UBUS_ATTR_MAX);
72         return attrbuf;
73 }
74
75 const char *ubus_strerror(int error)
76 {
77         static char err[32];
78
79         if (error < 0 || error >= __UBUS_STATUS_LAST)
80                 goto out;
81
82         if (!__ubus_strerror[error])
83                 goto out;
84
85         return __ubus_strerror[error];
86
87 out:
88         sprintf(err, "Unknown error: %d", error);
89         return err;
90 }
91
92 static void wait_data(int fd, bool write)
93 {
94         struct pollfd pfd = { .fd = fd };
95
96         pfd.events = write ? POLLOUT : POLLIN;
97         poll(&pfd, 1, 0);
98 }
99
100 static int writev_retry(int fd, struct iovec *iov, int iov_len)
101 {
102         int len = 0;
103
104         do {
105                 int cur_len = writev(fd, iov, iov_len);
106                 if (cur_len < 0) {
107                         switch(errno) {
108                         case EAGAIN:
109                                 wait_data(fd, true);
110                                 break;
111                         case EINTR:
112                                 break;
113                         default:
114                                 return -1;
115                         }
116                         continue;
117                 }
118                 len += cur_len;
119                 while (cur_len >= iov->iov_len) {
120                         cur_len -= iov->iov_len;
121                         iov_len--;
122                         iov++;
123                         if (!cur_len || !iov_len)
124                                 return len;
125                 }
126                 iov->iov_len -= cur_len;
127         } while (1);
128 }
129
130 static int ubus_send_msg(struct ubus_context *ctx, uint32_t seq,
131                          struct blob_attr *msg, int cmd, uint32_t peer)
132 {
133         struct ubus_msghdr hdr;
134         struct iovec iov[2] = {
135                 STATIC_IOV(hdr)
136         };
137
138         hdr.version = 0;
139         hdr.type = cmd;
140         hdr.seq = seq;
141         hdr.peer = peer;
142
143         if (!msg) {
144                 blob_buf_init(&b, 0);
145                 msg = b.head;
146         }
147
148         iov[1].iov_base = (char *) msg;
149         iov[1].iov_len = blob_raw_len(msg);
150
151         return writev_retry(ctx->sock.fd, iov, ARRAY_SIZE(iov));
152 }
153
154 static int ubus_start_request(struct ubus_context *ctx, struct ubus_request *req,
155                               struct blob_attr *msg, int cmd, uint32_t peer)
156 {
157         memset(req, 0, sizeof(*req));
158
159         if (msg && blob_pad_len(msg) > UBUS_MAX_MSGLEN)
160                 return -1;
161
162         INIT_LIST_HEAD(&req->list);
163         INIT_LIST_HEAD(&req->pending);
164         req->ctx = ctx;
165         req->peer = peer;
166         req->seq = ++ctx->request_seq;
167         return ubus_send_msg(ctx, req->seq, msg, cmd, peer);
168 }
169
170 static bool recv_retry(int fd, struct iovec *iov, bool wait)
171 {
172         int bytes;
173
174         while (iov->iov_len > 0) {
175                 if (wait)
176                         wait_data(fd, false);
177
178                 bytes = read(fd, iov->iov_base, iov->iov_len);
179                 if (bytes < 0) {
180                         bytes = 0;
181                         if (uloop_cancelled)
182                                 return false;
183                         if (errno == EINTR)
184                                 continue;
185
186                         if (errno != EAGAIN)
187                                 return false;
188                 }
189                 if (!wait && !bytes)
190                         return false;
191
192                 wait = true;
193                 iov->iov_len -= bytes;
194                 iov->iov_base += bytes;
195         }
196
197         return true;
198 }
199
200 static bool ubus_validate_hdr(struct ubus_msghdr *hdr)
201 {
202         if (hdr->version != 0)
203                 return false;
204
205         if (blob_raw_len(hdr->data) < sizeof(*hdr->data))
206                 return false;
207
208         if (blob_pad_len(hdr->data) > UBUS_MAX_MSGLEN)
209                 return false;
210
211         return true;
212 }
213
214 static bool get_next_msg(struct ubus_context *ctx)
215 {
216         struct iovec iov = STATIC_IOV(ctx->msgbuf.hdr);
217
218         /* receive header + start attribute */
219         iov.iov_len += sizeof(struct blob_attr);
220         if (!recv_retry(ctx->sock.fd, &iov, false))
221                 return false;
222
223         iov.iov_len = blob_len(ctx->msgbuf.hdr.data);
224         if (iov.iov_len > 0 && !recv_retry(ctx->sock.fd, &iov, true))
225                 return false;
226
227         return ubus_validate_hdr(&ctx->msgbuf.hdr);
228 }
229
230 static bool ubus_get_status(struct ubus_msghdr *hdr, int *ret)
231 {
232         ubus_parse_msg(hdr->data);
233
234         if (!attrbuf[UBUS_ATTR_STATUS])
235                 return false;
236
237         *ret = blob_get_u32(attrbuf[UBUS_ATTR_STATUS]);
238         return true;
239 }
240
241 static void req_data_cb(struct ubus_request *req, int type, struct blob_attr *data)
242 {
243         struct blob_attr **attr;
244
245         if (req->raw_data_cb)
246                 req->raw_data_cb(req, type, data);
247
248         if (!req->data_cb)
249                 return;
250
251         attr = ubus_parse_msg(data);
252         req->data_cb(req, type, attr[UBUS_ATTR_DATA]);
253 }
254
255 static void ubus_process_req_data(struct ubus_request *req)
256 {
257         struct ubus_pending_data *data;
258
259         while (!list_empty(&req->pending)) {
260                 data = list_first_entry(&req->pending,
261                         struct ubus_pending_data, list);
262                 list_del(&data->list);
263                 if (!req->cancelled)
264                         req_data_cb(req, data->type, data->data);
265                 free(data);
266         }
267 }
268
269 static void ubus_req_complete_cb(struct ubus_request *req)
270 {
271         ubus_complete_handler_t cb = req->complete_cb;
272
273         if (!cb)
274                 return;
275
276         req->complete_cb = NULL;
277         cb(req, req->status_code);
278 }
279
280 static int ubus_process_req_status(struct ubus_request *req, struct ubus_msghdr *hdr)
281 {
282         int ret = UBUS_STATUS_INVALID_ARGUMENT;
283
284         if (!list_empty(&req->list))
285                 list_del(&req->list);
286
287         ubus_get_status(hdr, &ret);
288         req->peer = hdr->peer;
289         req->status_msg = true;
290         req->status_code = ret;
291         if (!req->blocked)
292                 ubus_req_complete_cb(req);
293
294         return ret;
295 }
296
297 static void ubus_req_data(struct ubus_request *req, struct ubus_msghdr *hdr)
298 {
299         struct ubus_pending_data *data;
300         int len;
301
302         if (!req->blocked) {
303                 req->blocked = true;
304                 req_data_cb(req, hdr->type, hdr->data);
305                 ubus_process_req_data(req);
306                 req->blocked = false;
307
308                 if (req->status_msg)
309                         ubus_req_complete_cb(req);
310
311                 return;
312         }
313
314         len = blob_raw_len(hdr->data);
315         data = calloc(1, sizeof(*data) + len);
316         if (!data)
317                 return;
318
319         data->type = hdr->type;
320         memcpy(data->data, hdr->data, len);
321         list_add(&data->list, &req->pending);
322 }
323
324 static struct ubus_request *ubus_find_request(struct ubus_context *ctx, uint32_t seq, uint32_t peer)
325 {
326         struct ubus_request *req;
327
328         list_for_each_entry(req, &ctx->requests, list) {
329                 if (seq != req->seq || peer != req->peer)
330                         continue;
331
332                 return req;
333         }
334         return NULL;
335 }
336
337 static void ubus_process_invoke(struct ubus_context *ctx, struct ubus_msghdr *hdr)
338 {
339         struct ubus_request_data req;
340         struct ubus_object *obj;
341         uint32_t objid = 0;
342         int method;
343         int ret = 0;
344
345         ubus_parse_msg(hdr->data);
346
347         if (!attrbuf[UBUS_ATTR_OBJID])
348                 return;
349
350         objid = blob_get_u32(attrbuf[UBUS_ATTR_OBJID]);
351
352         if (!attrbuf[UBUS_ATTR_METHOD]) {
353                 ret = UBUS_STATUS_INVALID_ARGUMENT;
354                 goto send;
355         }
356
357         obj = avl_find_element(&ctx->objects, &objid, obj, avl);
358         if (!obj) {
359                 ret = UBUS_STATUS_NOT_FOUND;
360                 goto send;
361         }
362
363         for (method = 0; method < obj->n_methods; method++)
364                 if (!obj->methods[method].name ||
365                     !strcmp(obj->methods[method].name,
366                             blob_data(attrbuf[UBUS_ATTR_METHOD])))
367                         goto found;
368
369         /* not found */
370         ret = UBUS_STATUS_METHOD_NOT_FOUND;
371         goto send;
372
373 found:
374         req.object = objid;
375         req.peer = hdr->peer;
376         req.seq = hdr->seq;
377         ret = obj->methods[method].handler(ctx, obj, &req,
378                                            blob_data(attrbuf[UBUS_ATTR_METHOD]),
379                                            attrbuf[UBUS_ATTR_DATA]);
380
381 send:
382         blob_buf_init(&b, 0);
383         blob_put_int32(&b, UBUS_ATTR_STATUS, ret);
384         blob_put_int32(&b, UBUS_ATTR_OBJID, objid);
385         ubus_send_msg(ctx, hdr->seq, b.head, UBUS_MSG_STATUS, hdr->peer);
386 }
387
388 static void ubus_process_msg(struct ubus_context *ctx, struct ubus_msghdr *hdr)
389 {
390         struct ubus_request *req;
391
392         switch(hdr->type) {
393         case UBUS_MSG_STATUS:
394                 req = ubus_find_request(ctx, hdr->seq, hdr->peer);
395                 if (!req)
396                         break;
397
398                 ubus_process_req_status(req, hdr);
399                 break;
400
401         case UBUS_MSG_DATA:
402                 req = ubus_find_request(ctx, hdr->seq, hdr->peer);
403                 if (req && (req->data_cb || req->raw_data_cb))
404                         ubus_req_data(req, hdr);
405                 break;
406
407         case UBUS_MSG_INVOKE:
408                 ubus_process_invoke(ctx, hdr);
409                 break;
410         }
411 }
412
413 void ubus_abort_request(struct ubus_context *ctx, struct ubus_request *req)
414 {
415         if (!list_empty(&req->list))
416                 return;
417
418         req->cancelled = true;
419         ubus_process_req_data(req);
420         list_del(&req->list);
421 }
422
423 void ubus_complete_request_async(struct ubus_context *ctx, struct ubus_request *req)
424 {
425         if (!list_empty(&req->list))
426                 return;
427
428         list_add(&req->list, &ctx->requests);
429 }
430
431 static void ubus_handle_data(struct uloop_fd *u, unsigned int events)
432 {
433         struct ubus_context *ctx = container_of(u, struct ubus_context, sock);
434         struct ubus_msghdr *hdr = &ctx->msgbuf.hdr;
435
436         while (get_next_msg(ctx)) {
437                 ubus_process_msg(ctx, hdr);
438                 if (uloop_cancelled)
439                         break;
440         }
441
442         if (u->eof)
443                 ctx->connection_lost(ctx);
444 }
445
446 static void ubus_sync_req_cb(struct ubus_request *req, int ret)
447 {
448         req->status_msg = true;
449         req->status_code = ret;
450         uloop_end();
451 }
452
453 struct ubus_sync_req_cb {
454         struct uloop_timeout timeout;
455         struct ubus_request *req;
456 };
457
458 static void ubus_sync_req_timeout_cb(struct uloop_timeout *timeout)
459 {
460         struct ubus_sync_req_cb *cb;
461
462         cb = container_of(timeout, struct ubus_sync_req_cb, timeout);
463         ubus_sync_req_cb(cb->req, UBUS_STATUS_TIMEOUT);
464 }
465
466 int ubus_complete_request(struct ubus_context *ctx, struct ubus_request *req,
467                           int timeout)
468 {
469         struct ubus_sync_req_cb cb;
470         ubus_complete_handler_t complete_cb = req->complete_cb;
471         bool registered = ctx->sock.registered;
472         bool cancelled = uloop_cancelled;
473         int status = UBUS_STATUS_NO_DATA;
474
475         if (!registered) {
476                 uloop_init();
477                 ubus_add_uloop(ctx);
478         }
479
480         if (timeout) {
481                 memset(&cb, 0, sizeof(cb));
482                 cb.req = req;
483                 cb.timeout.cb = ubus_sync_req_timeout_cb;
484                 uloop_timeout_set(&cb.timeout, timeout);
485         }
486
487         ubus_complete_request_async(ctx, req);
488         req->complete_cb = ubus_sync_req_cb;
489
490         uloop_run();
491
492         if (timeout)
493                 uloop_timeout_cancel(&cb.timeout);
494
495         if (req->status_msg)
496                 status = req->status_code;
497
498         req->complete_cb = complete_cb;
499         if (req->complete_cb)
500                 req->complete_cb(req, status);
501
502         uloop_cancelled = cancelled;
503         if (!registered)
504                 uloop_fd_delete(&ctx->sock);
505
506         return status;
507 }
508
509 struct ubus_lookup_request {
510         struct ubus_request req;
511         ubus_lookup_handler_t cb;
512 };
513
514 static void ubus_lookup_cb(struct ubus_request *ureq, int type, struct blob_attr *msg)
515 {
516         struct ubus_lookup_request *req;
517         struct ubus_object_data obj;
518         struct blob_attr **attr;
519
520         req = container_of(ureq, struct ubus_lookup_request, req);
521         attr = ubus_parse_msg(msg);
522
523         if (!attr[UBUS_ATTR_OBJID] || !attr[UBUS_ATTR_OBJPATH] ||
524             !attr[UBUS_ATTR_OBJTYPE])
525                 return;
526
527         memset(&obj, 0, sizeof(obj));
528         obj.id = blob_get_u32(attr[UBUS_ATTR_OBJID]);
529         obj.path = blob_data(attr[UBUS_ATTR_OBJPATH]);
530         obj.type_id = blob_get_u32(attr[UBUS_ATTR_OBJTYPE]);
531         obj.signature = attr[UBUS_ATTR_SIGNATURE];
532         req->cb(ureq->ctx, &obj, ureq->priv);
533 }
534
535 int ubus_lookup(struct ubus_context *ctx, const char *path,
536                 ubus_lookup_handler_t cb, void *priv)
537 {
538         struct ubus_lookup_request lookup;
539
540         blob_buf_init(&b, 0);
541         if (path)
542                 blob_put_string(&b, UBUS_ATTR_OBJPATH, path);
543
544         if (ubus_start_request(ctx, &lookup.req, b.head, UBUS_MSG_LOOKUP, 0) < 0)
545                 return UBUS_STATUS_INVALID_ARGUMENT;
546
547         lookup.req.raw_data_cb = ubus_lookup_cb;
548         lookup.req.priv = priv;
549         lookup.cb = cb;
550         return ubus_complete_request(ctx, &lookup.req, 0);
551 }
552
553 static void ubus_lookup_id_cb(struct ubus_request *req, int type, struct blob_attr *msg)
554 {
555         struct blob_attr **attr;
556         uint32_t *id = req->priv;
557
558         attr = ubus_parse_msg(msg);
559
560         if (!attr[UBUS_ATTR_OBJID])
561                 return;
562
563         *id = blob_get_u32(attr[UBUS_ATTR_OBJID]);
564 }
565
566 int ubus_lookup_id(struct ubus_context *ctx, const char *path, uint32_t *id)
567 {
568         struct ubus_request req;
569
570         blob_buf_init(&b, 0);
571         if (path)
572                 blob_put_string(&b, UBUS_ATTR_OBJPATH, path);
573
574         if (ubus_start_request(ctx, &req, b.head, UBUS_MSG_LOOKUP, 0) < 0)
575                 return UBUS_STATUS_INVALID_ARGUMENT;
576
577         req.raw_data_cb = ubus_lookup_id_cb;
578         req.priv = id;
579
580         return ubus_complete_request(ctx, &req, 0);
581 }
582
583 int ubus_send_reply(struct ubus_context *ctx, struct ubus_request_data *req,
584                     struct blob_attr *msg)
585 {
586         int ret;
587
588         blob_buf_init(&b, 0);
589         blob_put_int32(&b, UBUS_ATTR_OBJID, req->object);
590         blob_put(&b, UBUS_ATTR_DATA, blob_data(msg), blob_len(msg));
591         ret = ubus_send_msg(ctx, req->seq, b.head, UBUS_MSG_DATA, req->peer);
592         if (ret < 0)
593                 return UBUS_STATUS_NO_DATA;
594
595         return 0;
596 }
597
598 int ubus_invoke_async(struct ubus_context *ctx, uint32_t obj, const char *method,
599                        struct blob_attr *msg, struct ubus_request *req)
600 {
601         blob_buf_init(&b, 0);
602         blob_put_int32(&b, UBUS_ATTR_OBJID, obj);
603         blob_put_string(&b, UBUS_ATTR_METHOD, method);
604         if (msg)
605                 blob_put(&b, UBUS_ATTR_DATA, blob_data(msg), blob_len(msg));
606
607         if (ubus_start_request(ctx, req, b.head, UBUS_MSG_INVOKE, obj) < 0)
608                 return UBUS_STATUS_INVALID_ARGUMENT;
609
610         return 0;
611 }
612
613 int ubus_invoke(struct ubus_context *ctx, uint32_t obj, const char *method,
614                 struct blob_attr *msg, ubus_data_handler_t cb, void *priv,
615                 int timeout)
616 {
617         struct ubus_request req;
618
619         ubus_invoke_async(ctx, obj, method, msg, &req);
620         req.data_cb = cb;
621         req.priv = priv;
622         return ubus_complete_request(ctx, &req, timeout);
623 }
624
625 static void ubus_add_object_cb(struct ubus_request *req, int type, struct blob_attr *msg)
626 {
627         struct ubus_object *obj = req->priv;
628
629         ubus_parse_msg(msg);
630
631         if (!attrbuf[UBUS_ATTR_OBJID])
632                 return;
633
634         obj->id = blob_get_u32(attrbuf[UBUS_ATTR_OBJID]);
635
636         if (attrbuf[UBUS_ATTR_OBJTYPE])
637                 obj->type->id = blob_get_u32(attrbuf[UBUS_ATTR_OBJTYPE]);
638
639         obj->avl.key = &obj->id;
640         avl_insert(&req->ctx->objects, &obj->avl);
641 }
642
643 static void ubus_push_method_data(const struct ubus_method *m)
644 {
645         void *mtbl;
646         int i;
647
648         mtbl = blobmsg_open_table(&b, m->name);
649
650         for (i = 0; i < m->n_policy; i++)
651                 blobmsg_add_u32(&b, m->policy[i].name, m->policy[i].type);
652
653         blobmsg_close_table(&b, mtbl);
654 }
655
656 static bool ubus_push_object_type(const struct ubus_object_type *type)
657 {
658         void *s;
659         int i;
660
661         s = blob_nest_start(&b, UBUS_ATTR_SIGNATURE);
662
663         for (i = 0; i < type->n_methods; i++)
664                 ubus_push_method_data(&type->methods[i]);
665
666         blob_nest_end(&b, s);
667
668         return true;
669 }
670
671 static int __ubus_add_object(struct ubus_context *ctx, struct ubus_object *obj)
672 {
673         struct ubus_request req;
674         int ret;
675
676         blob_buf_init(&b, 0);
677
678         if (obj->name && obj->type) {
679                 blob_put_string(&b, UBUS_ATTR_OBJPATH, obj->name);
680
681                 if (obj->type->id)
682                         blob_put_int32(&b, UBUS_ATTR_OBJTYPE, obj->type->id);
683                 else if (!ubus_push_object_type(obj->type))
684                         return UBUS_STATUS_INVALID_ARGUMENT;
685         }
686
687         if (ubus_start_request(ctx, &req, b.head, UBUS_MSG_ADD_OBJECT, 0) < 0)
688                 return UBUS_STATUS_INVALID_ARGUMENT;
689
690         req.raw_data_cb = ubus_add_object_cb;
691         req.priv = obj;
692         ret = ubus_complete_request(ctx, &req, 0);
693         if (ret)
694                 return ret;
695
696         if (!obj->id)
697                 return UBUS_STATUS_NO_DATA;
698
699         return 0;
700 }
701
702 int ubus_add_object(struct ubus_context *ctx, struct ubus_object *obj)
703 {
704         if (!obj->name || !obj->type)
705                 return UBUS_STATUS_INVALID_ARGUMENT;
706
707         return __ubus_add_object(ctx, obj);
708 }
709
710 static void ubus_remove_object_cb(struct ubus_request *req, int type, struct blob_attr *msg)
711 {
712         struct ubus_object *obj = req->priv;
713
714         ubus_parse_msg(msg);
715
716         if (!attrbuf[UBUS_ATTR_OBJID])
717                 return;
718
719         obj->id = 0;
720
721         if (attrbuf[UBUS_ATTR_OBJTYPE] && obj->type)
722                 obj->type->id = 0;
723
724         avl_delete(&req->ctx->objects, &obj->avl);
725 }
726
727 int ubus_remove_object(struct ubus_context *ctx, struct ubus_object *obj)
728 {
729         struct ubus_request req;
730         int ret;
731
732         blob_buf_init(&b, 0);
733         blob_put_int32(&b, UBUS_ATTR_OBJID, obj->id);
734
735         if (ubus_start_request(ctx, &req, b.head, UBUS_MSG_REMOVE_OBJECT, 0) < 0)
736                 return UBUS_STATUS_INVALID_ARGUMENT;
737
738         req.raw_data_cb = ubus_remove_object_cb;
739         req.priv = obj;
740         ret = ubus_complete_request(ctx, &req, 0);
741         if (ret)
742                 return ret;
743
744         if (obj->id)
745                 return UBUS_STATUS_NO_DATA;
746
747         return 0;
748 }
749
750 static int ubus_event_cb(struct ubus_context *ctx, struct ubus_object *obj,
751                          struct ubus_request_data *req,
752                          const char *method, struct blob_attr *msg)
753 {
754         struct ubus_event_handler *ev;
755
756         ev = container_of(obj, struct ubus_event_handler, obj);
757         ev->cb(ctx, ev, method, msg);
758         return 0;
759 }
760
761 static const struct ubus_method event_method = {
762         .name = NULL,
763         .handler = ubus_event_cb,
764 };
765
766 int ubus_register_event_handler(struct ubus_context *ctx,
767                                 struct ubus_event_handler *ev,
768                                 const char *pattern)
769 {
770         struct ubus_object *obj = &ev->obj;
771         struct blob_buf b2;
772         int ret;
773
774         if (!obj->id) {
775                 obj->methods = &event_method;
776                 obj->n_methods = 1;
777
778                 if (!!obj->name ^ !!obj->type)
779                         return UBUS_STATUS_INVALID_ARGUMENT;
780
781                 ret = __ubus_add_object(ctx, obj);
782                 if (ret)
783                         return ret;
784         }
785
786         /* use a second buffer, ubus_invoke() overwrites the primary one */
787         memset(&b2, 0, sizeof(b2));
788         blob_buf_init(&b2, 0);
789         blobmsg_add_u32(&b2, "object", obj->id);
790         if (pattern)
791                 blobmsg_add_string(&b2, "pattern", pattern);
792
793         return ubus_invoke(ctx, UBUS_SYSTEM_OBJECT_EVENT, "register", b2.head,
794                           NULL, NULL, 0);
795 }
796
797 int ubus_send_event(struct ubus_context *ctx, const char *id,
798                     struct blob_attr *data)
799 {
800         struct ubus_request req;
801         void *s;
802
803         blob_buf_init(&b, 0);
804         blob_put_int32(&b, UBUS_ATTR_OBJID, UBUS_SYSTEM_OBJECT_EVENT);
805         blob_put_string(&b, UBUS_ATTR_METHOD, "send");
806         s = blob_nest_start(&b, UBUS_ATTR_DATA);
807         blobmsg_add_string(&b, "id", id);
808         blobmsg_add_field(&b, BLOBMSG_TYPE_TABLE, "data", blob_data(data), blob_len(data));
809         blob_nest_end(&b, s);
810
811         if (ubus_start_request(ctx, &req, b.head, UBUS_MSG_INVOKE, UBUS_SYSTEM_OBJECT_EVENT) < 0)
812                 return UBUS_STATUS_INVALID_ARGUMENT;
813
814         return ubus_complete_request(ctx, &req, 0);
815 }
816
817 static void ubus_default_connection_lost(struct ubus_context *ctx)
818 {
819         if (ctx->sock.registered)
820                 uloop_end();
821 }
822
823 struct ubus_context *ubus_connect(const char *path)
824 {
825         struct ubus_context *ctx;
826         struct {
827                 struct ubus_msghdr hdr;
828                 struct blob_attr data;
829         } hdr;
830         struct blob_attr *buf;
831
832         if (!path)
833                 path = UBUS_UNIX_SOCKET;
834
835         ctx = calloc(1, sizeof(*ctx));
836         if (!ctx)
837                 goto error;
838
839         ctx->sock.fd = usock(USOCK_UNIX, path, NULL);
840         if (ctx->sock.fd < 0)
841                 goto error_free;
842
843         ctx->sock.cb = ubus_handle_data;
844
845         if (read(ctx->sock.fd, &hdr, sizeof(hdr)) != sizeof(hdr))
846                 goto error_close;
847
848         if (!ubus_validate_hdr(&hdr.hdr))
849                 goto error_close;
850
851         if (hdr.hdr.type != UBUS_MSG_HELLO)
852                 goto error_close;
853
854         buf = calloc(1, blob_raw_len(&hdr.data));
855         if (!buf)
856                 goto error_close;
857
858         memcpy(buf, &hdr.data, sizeof(hdr.data));
859         if (read(ctx->sock.fd, blob_data(buf), blob_len(buf)) != blob_len(buf))
860                 goto error_free_buf;
861
862         ctx->local_id = hdr.hdr.peer;
863         free(buf);
864
865         ctx->connection_lost = ubus_default_connection_lost;
866
867         INIT_LIST_HEAD(&ctx->requests);
868         avl_init(&ctx->objects, ubus_cmp_id, false, NULL);
869
870         if (!ctx->local_id)
871                 goto error_close;
872
873         fcntl(ctx->sock.fd, F_SETFL, fcntl(ctx->sock.fd, F_GETFL) | O_NONBLOCK);
874
875         return ctx;
876
877 error_free_buf:
878         free(buf);
879 error_close:
880         close(ctx->sock.fd);
881 error_free:
882         free(ctx);
883 error:
884         return NULL;
885 }
886
887 void ubus_free(struct ubus_context *ctx)
888 {
889         close(ctx->sock.fd);
890         free(ctx);
891 }