f3e62f9050fdf3231afef0e16cace7df0433c5b2
[project/udebug.git] / lib.c
1 #include "udebug.h"
2
3 static struct blob_attr *
4 find_attr(struct blob_attr *attr, const char *name, enum blobmsg_type type)
5 {
6 struct blobmsg_policy policy = { name, type };
7 struct blob_attr *ret;
8
9 if (!attr)
10 return NULL;
11
12 blobmsg_parse_attr(&policy, 1, &ret, attr);
13 return ret;
14 }
15
16 static void
17 udebug_ubus_msg_cb(struct udebug_ubus *ctx, struct blob_attr *data)
18 {
19 struct blob_attr *en_attr;
20 bool enabled;
21
22 data = find_attr(data, "service", BLOBMSG_TYPE_TABLE);
23 data = find_attr(data, ctx->service, BLOBMSG_TYPE_TABLE);
24 if (!data)
25 return;
26
27 en_attr = find_attr(data, "enabled", BLOBMSG_TYPE_STRING);
28 enabled = en_attr && !!atoi(blobmsg_get_string(en_attr));
29 ctx->cb(ctx, data, enabled);
30 }
31
32 static int
33 udebug_ubus_notify_cb(struct ubus_context *ubus, struct ubus_object *obj,
34 struct ubus_request_data *req, const char *method,
35 struct blob_attr *msg)
36 {
37 struct udebug_ubus *ctx = container_of(obj, struct udebug_ubus, sub.obj);
38
39 if (!strcmp(method, "config"))
40 udebug_ubus_msg_cb(ctx, msg);
41
42 return 0;
43 }
44
45 static void
46 udebug_ubus_req_cb(struct ubus_request *req, int type, struct blob_attr *msg)
47 {
48 udebug_ubus_msg_cb(req->priv, msg);
49 }
50
51 static bool
52 udebug_ubus_new_obj_cb(struct ubus_context *ubus, struct ubus_subscriber *sub,
53 const char *path)
54 {
55 struct udebug_ubus *ctx = container_of(sub, struct udebug_ubus, sub);
56
57 if (strcmp(path, "udebug") != 0)
58 return false;
59
60 uloop_timeout_set(&ctx->t, 1);
61 return true;
62 }
63
64 static void udebug_ubus_get_config(struct uloop_timeout *t)
65 {
66 struct udebug_ubus *ctx = container_of(t, struct udebug_ubus, t);
67 uint32_t id;
68
69 if (ubus_lookup_id(ctx->ubus, "udebug", &id))
70 return;
71
72 ubus_invoke(ctx->ubus, id, "get_config", NULL, udebug_ubus_req_cb, ctx, 1000);
73 }
74
75 void udebug_ubus_init(struct udebug_ubus *ctx, struct ubus_context *ubus,
76 const char *service, udebug_config_cb cb)
77 {
78 ctx->ubus = ubus;
79 ctx->service = service;
80 ctx->cb = cb;
81 ctx->sub.new_obj_cb = udebug_ubus_new_obj_cb;
82 ctx->sub.cb = udebug_ubus_notify_cb;
83 ubus_register_subscriber(ubus, &ctx->sub);
84
85 ctx->t.cb = udebug_ubus_get_config;
86 }
87
88 void udebug_ubus_free(struct udebug_ubus *ctx)
89 {
90 if (!ctx->ubus)
91 return;
92
93 uloop_timeout_cancel(&ctx->t);
94 ubus_unregister_subscriber(ctx->ubus, &ctx->sub);
95 }