summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2011-02-05 01:29:52 +0100
committerFelix Fietkau <nbd@openwrt.org>2011-02-05 01:29:52 +0100
commitfa989780bda3ad10fcbb637390d59afe2b32ba81 (patch)
tree4f5f12616f7507ce1cbf30ace71da7f14175edba
parentd80ebf55afcde808265e4702c162d6b40d649260 (diff)
downloadubus-fa989780bda3ad10fcbb637390d59afe2b32ba81.tar.gz
add some stub functionality for the ubus event switch
-rw-r--r--CMakeLists.txt2
-rw-r--r--cli.c3
-rw-r--r--ubusd.h3
-rw-r--r--ubusd_event.c45
-rw-r--r--ubusd_id.c10
-rw-r--r--ubusd_id.h1
-rw-r--r--ubusd_obj.c14
-rw-r--r--ubusd_obj.h4
-rw-r--r--ubusd_proto.c4
9 files changed, 77 insertions, 9 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 928712b..cdf0350 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,7 +6,7 @@ ADD_DEFINITIONS(-Os -Wall -Werror --std=gnu99 -g3)
ADD_LIBRARY(ubus SHARED libubus.c)
TARGET_LINK_LIBRARIES(ubus ubox)
-ADD_EXECUTABLE(ubusd ubusd.c ubusd_id.c ubusd_obj.c ubusd_proto.c)
+ADD_EXECUTABLE(ubusd ubusd.c ubusd_id.c ubusd_obj.c ubusd_proto.c ubusd_event.c)
TARGET_LINK_LIBRARIES(ubusd ubox)
ADD_EXECUTABLE(cli cli.c)
diff --git a/cli.c b/cli.c
index c0521fa..59e62ed 100644
--- a/cli.c
+++ b/cli.c
@@ -34,6 +34,7 @@ static int usage(char *prog)
"Commands:\n"
" - list [<path>] List objects\n"
" - call <path> <method> [<message>] Call an object method\n"
+ " - listen [<path>...] Listen for events\n"
"\n", prog);
return 1;
}
@@ -70,6 +71,8 @@ int main(int argc, char **argv)
ret = ubus_lookup_id(ctx, argv[2], &id);
if (!ret)
ret = ubus_invoke(ctx, id, argv[3], NULL, receive_data, NULL);
+ } else if (!strcmp(cmd, "listen")) {
+ ret = ubus_invoke(ctx, UBUS_SYSTEM_OBJECT_EVENT, "listen", NULL, receive_data, NULL);
} else {
return usage(argv[0]);
}
diff --git a/ubusd.h b/ubusd.h
index c0b02f5..c82896c 100644
--- a/ubusd.h
+++ b/ubusd.h
@@ -60,5 +60,8 @@ bool ubusd_send_hello(struct ubus_client *cl);
struct blob_attr **ubus_parse_msg(struct blob_attr *msg);
+void ubusd_event_init(void);
+void ubusd_event_cleanup_object(struct ubus_object *obj);
+
#endif
diff --git a/ubusd_event.c b/ubusd_event.c
new file mode 100644
index 0000000..da0aed8
--- /dev/null
+++ b/ubusd_event.c
@@ -0,0 +1,45 @@
+#include "ubusd.h"
+
+static struct avl_tree patterns;
+static struct ubus_object *event_obj;
+
+struct event_pattern {
+ struct avl_node avl;
+
+ struct ubus_object *obj;
+ struct list_head list;
+
+ const char *path;
+};
+
+static void ubusd_delete_event_pattern(struct event_pattern *ev)
+{
+ list_del(&ev->list);
+ avl_delete(&patterns, &ev->avl);
+ free(ev);
+}
+
+void ubusd_event_cleanup_object(struct ubus_object *obj)
+{
+ struct event_pattern *ev;
+
+ while (!list_empty(&obj->event_patterns)) {
+ ev = list_first_entry(&obj->event_patterns,
+ struct event_pattern, list);
+ ubusd_delete_event_pattern(ev);
+ }
+}
+
+static int ubusd_event_recv(struct ubus_client *cl, const char *method, struct blob_attr *msg)
+{
+ fprintf(stderr, "event: call to method '%s'\n", method);
+ return 0;
+}
+
+void ubusd_event_init(void)
+{
+ ubus_init_string_tree(&patterns, true);
+ event_obj = ubusd_create_object_internal(NULL, UBUS_SYSTEM_OBJECT_EVENT);
+ event_obj->recv_msg = ubusd_event_recv;
+}
+
diff --git a/ubusd_id.c b/ubusd_id.c
index 44b509e..a9cfeae 100644
--- a/ubusd_id.c
+++ b/ubusd_id.c
@@ -18,6 +18,16 @@ static int ubus_cmp_id(const void *k1, const void *k2, void *ptr)
return *id1 > *id2;
}
+static int ubus_cmp_str(const void *k1, const void *k2, void *ptr)
+{
+ return strcmp(k1, k2);
+}
+
+void ubus_init_string_tree(struct avl_tree *tree, bool dup)
+{
+ avl_init(tree, ubus_cmp_str, dup, NULL);
+}
+
void ubus_init_id_tree(struct avl_tree *tree)
{
if (random_fd < 0) {
diff --git a/ubusd_id.h b/ubusd_id.h
index 2b4cb6d..740e5d6 100644
--- a/ubusd_id.h
+++ b/ubusd_id.h
@@ -10,6 +10,7 @@ struct ubus_id {
};
void ubus_init_id_tree(struct avl_tree *tree);
+void ubus_init_string_tree(struct avl_tree *tree, bool dup);
bool ubus_alloc_id(struct avl_tree *tree, struct ubus_id *id, uint32_t val);
static inline void ubus_free_id(struct avl_tree *tree, struct ubus_id *id)
diff --git a/ubusd_obj.c b/ubusd_obj.c
index 7fc7951..a6be182 100644
--- a/ubusd_obj.c
+++ b/ubusd_obj.c
@@ -98,7 +98,8 @@ struct ubus_object *ubusd_create_object_internal(struct ubus_object_type *type,
obj->type = type;
INIT_LIST_HEAD(&obj->list);
- type->refcount++;
+ if (type)
+ type->refcount++;
return obj;
@@ -156,18 +157,15 @@ void ubusd_free_object(struct ubus_object *obj)
if (!list_empty(&obj->list))
list_del(&obj->list);
ubus_free_id(&objects, &obj->id);
- ubus_unref_object_type(obj->type);
+ if (obj->type)
+ ubus_unref_object_type(obj->type);
free(obj);
}
-static int ubus_cmp_path(const void *k1, const void *k2, void *ptr)
-{
- return strcmp(k1, k2);
-}
-
static void __init ubusd_obj_init(void)
{
ubus_init_id_tree(&objects);
ubus_init_id_tree(&obj_types);
- avl_init(&path, ubus_cmp_path, false, NULL);
+ ubus_init_string_tree(&path, false);
+ ubusd_event_init();
}
diff --git a/ubusd_obj.h b/ubusd_obj.h
index 2064084..6e5c2c9 100644
--- a/ubusd_obj.h
+++ b/ubusd_obj.h
@@ -26,13 +26,17 @@ struct ubus_object {
struct ubus_id id;
struct list_head list;
+ struct list_head event_patterns;
+
struct ubus_object_type *type;
struct avl_node path;
struct ubus_client *client;
+ int (*recv_msg)(struct ubus_client *client, const char *method, struct blob_attr *msg);
};
struct ubus_object *ubusd_create_object(struct ubus_client *cl, struct blob_attr **attr);
+struct ubus_object *ubusd_create_object_internal(struct ubus_object_type *type, uint32_t id);
void ubusd_free_object(struct ubus_object *obj);
#endif
diff --git a/ubusd_proto.c b/ubusd_proto.c
index 1b3216f..07bb9fa 100644
--- a/ubusd_proto.c
+++ b/ubusd_proto.c
@@ -176,6 +176,10 @@ static int ubusd_handle_invoke(struct ubus_client *cl, struct ubus_msg_buf *ub,
obj = container_of(id, struct ubus_object, id);
method = blob_data(attr[UBUS_ATTR_METHOD]);
+
+ if (!obj->client)
+ return obj->recv_msg(cl, method, attr[UBUS_ATTR_DATA]);
+
blob_buf_init(&b, 0);
blob_put_int32(&b, UBUS_ATTR_OBJID, obj->id.id);
blob_put_string(&b, UBUS_ATTR_METHOD, method);