add some stub functionality for the ubus event switch
This commit is contained in:
parent
d80ebf55af
commit
fa989780bd
9 changed files with 77 additions and 9 deletions
|
@ -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
cli.c
3
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
ubusd.h
3
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
ubusd_event.c
Normal file
45
ubusd_event.c
Normal file
|
@ -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
ubusd_id.c
10
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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
10
ubusd_obj.c
10
ubusd_obj.c
|
@ -98,6 +98,7 @@ struct ubus_object *ubusd_create_object_internal(struct ubus_object_type *type,
|
|||
|
||||
obj->type = type;
|
||||
INIT_LIST_HEAD(&obj->list);
|
||||
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);
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue