Browse Source

add some stub functionality for the ubus event switch

Felix Fietkau 13 years ago
parent
commit
fa989780bd
9 changed files with 77 additions and 9 deletions
  1. 1 1
      CMakeLists.txt
  2. 3 0
      cli.c
  3. 3 0
      ubusd.h
  4. 45 0
      ubusd_event.c
  5. 10 0
      ubusd_id.c
  6. 1 0
      ubusd_id.h
  7. 6 8
      ubusd_obj.c
  8. 4 0
      ubusd_obj.h
  9. 4 0
      ubusd_proto.c

+ 1 - 1
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)

+ 3 - 0
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]);
 	}

+ 3 - 0
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

+ 45 - 0
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;
+}
+

+ 10 - 0
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) {

+ 1 - 0
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)

+ 6 - 8
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();
 }

+ 4 - 0
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

+ 4 - 0
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);