From 1a871e1e89055f8683793f1ca0d629ca2fa4d3be Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 31 Jan 2011 03:26:53 +0100 Subject: [PATCH] add working method calls --- libubus.c | 34 ++++++++++++++++++++++++++++++++-- libubus.h | 14 +++++++++++--- listener.c | 23 +++++++++++++++++++---- ubusmsg.h | 1 + 4 files changed, 63 insertions(+), 9 deletions(-) diff --git a/libubus.c b/libubus.c index e770ce3..93f9bac 100644 --- a/libubus.c +++ b/libubus.c @@ -24,6 +24,7 @@ const char *__ubus_strerror[__UBUS_STATUS_LAST] = { [UBUS_STATUS_OK] = "Success", [UBUS_STATUS_INVALID_COMMAND] = "Invalid command", [UBUS_STATUS_INVALID_ARGUMENT] = "Invalid argument", + [UBUS_STATUS_METHOD_NOT_FOUND] = "Method not found", [UBUS_STATUS_NOT_FOUND] = "Not found", [UBUS_STATUS_NO_DATA] = "No response", }; @@ -265,14 +266,43 @@ static struct ubus_request *ubus_find_request(struct ubus_context *ctx, uint32_t static void ubus_process_invoke(struct ubus_context *ctx, struct ubus_msghdr *hdr) { + struct ubus_request_data req; + struct ubus_object *obj; uint32_t objid = 0; + int method; int ret = 0; ubus_parse_msg(hdr->data); - if (attrbuf[UBUS_ATTR_OBJID]) - objid = blob_get_int32(attrbuf[UBUS_ATTR_OBJID]); + if (!attrbuf[UBUS_ATTR_METHOD] || !attrbuf[UBUS_ATTR_OBJID]) { + ret = UBUS_STATUS_INVALID_ARGUMENT; + goto send; + } + objid = blob_get_int32(attrbuf[UBUS_ATTR_OBJID]); + obj = avl_find_element(&ctx->objects, &objid, obj, avl); + if (!obj) { + ret = UBUS_STATUS_NOT_FOUND; + goto send; + } + + for (method = 0; method < obj->n_methods; method++) + if (!strcmp(obj->methods[method].name, + blob_data(attrbuf[UBUS_ATTR_METHOD]))) + goto found; + + /* not found */ + ret = UBUS_STATUS_METHOD_NOT_FOUND; + goto send; + +found: + req.object = objid; + req.peer = hdr->peer; + req.seq = hdr->seq; + ret = obj->methods[method].handler(obj, &req, obj->methods[method].name, + attrbuf[UBUS_ATTR_DATA]); + +send: blob_buf_init(&b, 0); blob_put_int32(&b, UBUS_ATTR_STATUS, ret); blob_put_int32(&b, UBUS_ATTR_OBJID, objid); diff --git a/libubus.h b/libubus.h index 2e2f0c6..2662878 100644 --- a/libubus.h +++ b/libubus.h @@ -11,9 +11,9 @@ struct ubus_object; struct ubus_request; struct ubus_request_data; -typedef void (*ubus_handler_t)(struct ubus_object *obj, - struct ubus_request_data *req, - const char *method, struct blob_attr *msg); +typedef int (*ubus_handler_t)(struct ubus_object *obj, + struct ubus_request_data *req, + const char *method, struct blob_attr *msg); typedef void (*ubus_data_handler_t)(struct ubus_request *req, int type, struct blob_attr *msg); typedef void (*ubus_complete_handler_t)(struct ubus_request *req, int ret); @@ -52,6 +52,11 @@ struct ubus_object_type { const struct ubus_signature *signature; }; +struct ubus_method { + const char *name; + ubus_handler_t handler; +}; + struct ubus_object { struct avl_node avl; @@ -60,6 +65,9 @@ struct ubus_object { const char *path; struct ubus_object_type *type; + + const struct ubus_method *methods; + int n_methods; }; struct ubus_context { diff --git a/listener.c b/listener.c index 08b7c64..ffd8d6e 100644 --- a/listener.c +++ b/listener.c @@ -5,24 +5,39 @@ static struct ubus_context *ctx; static const struct ubus_signature test_object_sig[] = { UBUS_METHOD_START("hello"), UBUS_ARRAY("test"), - UBUS_TABLE_START(NULL), - UBUS_FIELD(INT32, "id"), - UBUS_FIELD(STRING, "msg"), - UBUS_TABLE_END(), + UBUS_TABLE_START(NULL), + UBUS_FIELD(INT32, "id"), + UBUS_FIELD(STRING, "msg"), + UBUS_TABLE_END(), UBUS_METHOD_END(), }; static struct ubus_object_type test_object_type = UBUS_OBJECT_TYPE("test", test_object_sig); +static int test_hello(struct ubus_object *obj, struct ubus_request_data *req, + const char *method, struct blob_attr *msg) +{ + fprintf(stderr, "Hello, world!\n"); + return 0; +} + +static const struct ubus_method test_methods[] = { + { .name = "hello", .handler = test_hello }, +}; + static struct ubus_object test_object = { .name = "test", .type = &test_object_type, + .methods = test_methods, + .n_methods = ARRAY_SIZE(test_methods), }; static struct ubus_object test_object2 = { .name = "test2", .type = &test_object_type, + .methods = test_methods, + .n_methods = ARRAY_SIZE(test_methods), }; int main(int argc, char **argv) diff --git a/ubusmsg.h b/ubusmsg.h index e62a393..3e10797 100644 --- a/ubusmsg.h +++ b/ubusmsg.h @@ -64,6 +64,7 @@ enum ubus_msg_status { UBUS_STATUS_OK, UBUS_STATUS_INVALID_COMMAND, UBUS_STATUS_INVALID_ARGUMENT, + UBUS_STATUS_METHOD_NOT_FOUND, UBUS_STATUS_NOT_FOUND, UBUS_STATUS_NO_DATA, __UBUS_STATUS_LAST