From 1555e4610fe2f82419821a34d471dda874a8c885 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 31 Jan 2011 17:18:10 +0100 Subject: [PATCH] add support for data replies --- cli.c | 13 +++++++++++-- libubus.c | 42 ++++++++++++++++++++++++++++++++++++------ libubus.h | 8 ++++++-- listener.c | 10 +++++++--- 4 files changed, 60 insertions(+), 13 deletions(-) diff --git a/cli.c b/cli.c index e6b1278..a1c90fe 100644 --- a/cli.c +++ b/cli.c @@ -28,6 +28,14 @@ static void receive_lookup(struct ubus_request *req, int type, struct blob_attr } } +static void receive_data(struct ubus_request *req, int type, struct blob_attr *msg) +{ + if (!msg) + return; + + fprintf(stderr, "%s\n", blobmsg_format_json(msg, true)); +} + static void store_objid(struct ubus_request *req, int type, struct blob_attr *msg) { struct blob_attr **attr; @@ -46,7 +54,7 @@ static uint32_t get_object(const char *name) blob_buf_init(&b, 0); blob_put_string(&b, UBUS_ATTR_OBJPATH, name); ubus_start_request(ctx, &req, b.head, UBUS_MSG_LOOKUP, 0); - req.data_cb = store_objid; + req.raw_data_cb = store_objid; if (ubus_complete_request(ctx, &req)) return 0; @@ -87,7 +95,7 @@ int main(int argc, char **argv) blob_put_string(&b, UBUS_ATTR_OBJPATH, argv[2]); ubus_start_request(ctx, &req, b.head, UBUS_MSG_LOOKUP, 0); - req.data_cb = receive_lookup; + req.raw_data_cb = receive_lookup; } else if (!strcmp(cmd, "call")) { if (argc < 4 || argc > 5) return usage(argv[0]); @@ -101,6 +109,7 @@ int main(int argc, char **argv) blob_put_int32(&b, UBUS_ATTR_OBJID, objid); blob_put_string(&b, UBUS_ATTR_METHOD, argv[3]); ubus_start_request(ctx, &req, b.head, UBUS_MSG_INVOKE, objid); + req.data_cb = receive_data; } else { return usage(argv[0]); } diff --git a/libubus.c b/libubus.c index 64190f7..1342ba1 100644 --- a/libubus.c +++ b/libubus.c @@ -183,6 +183,20 @@ static bool ubus_get_status(struct ubus_msghdr *hdr, int *ret) return true; } +static void req_data_cb(struct ubus_request *req, int type, struct blob_attr *data) +{ + struct blob_attr **attr; + + if (req->raw_data_cb) + req->raw_data_cb(req, type, data); + + if (!req->data_cb) + return; + + attr = ubus_parse_msg(data); + req->data_cb(req, type, attr[UBUS_ATTR_DATA]); +} + static void ubus_process_req_data(struct ubus_request *req) { struct ubus_pending_data *data; @@ -192,7 +206,7 @@ static void ubus_process_req_data(struct ubus_request *req) struct ubus_pending_data, list); list_del(&data->list); if (!req->cancelled) - req->data_cb(req, data->type, data->data); + req_data_cb(req, data->type, data->data); free(data); } } @@ -232,7 +246,7 @@ static void ubus_req_data(struct ubus_request *req, struct ubus_msghdr *hdr) if (!req->blocked) { req->blocked = true; - req->data_cb(req, hdr->type, hdr->data); + req_data_cb(req, hdr->type, hdr->data); ubus_process_req_data(req); req->blocked = false; @@ -304,7 +318,8 @@ found: req.object = objid; req.peer = hdr->peer; req.seq = hdr->seq; - ret = obj->methods[method].handler(obj, &req, obj->methods[method].name, + ret = obj->methods[method].handler(ctx, obj, &req, + obj->methods[method].name, attrbuf[UBUS_ATTR_DATA]); send: @@ -329,7 +344,7 @@ static void ubus_process_msg(struct ubus_context *ctx, struct ubus_msghdr *hdr) case UBUS_MSG_DATA: req = ubus_find_request(ctx, hdr->seq, hdr->peer); - if (req && req->data_cb) + if (req && (req->data_cb || req->raw_data_cb)) ubus_req_data(req, hdr); break; @@ -396,7 +411,7 @@ int ubus_complete_request(struct ubus_context *ctx, struct ubus_request *req) case UBUS_MSG_STATUS: return ubus_process_req_status(req, hdr); case UBUS_MSG_DATA: - if (req->data_cb) + if (req->data_cb || req->raw_data_cb) ubus_req_data(req, hdr); continue; default: @@ -408,6 +423,21 @@ skip: } } +int ubus_send_reply(struct ubus_context *ctx, struct ubus_request_data *req, + struct blob_attr *msg) +{ + int ret; + + blob_buf_init(&b, 0); + blob_put_int32(&b, UBUS_ATTR_OBJID, req->object); + blob_put(&b, UBUS_ATTR_DATA, blob_data(msg), blob_len(msg)); + ret = ubus_send_msg(ctx, req->seq, b.head, UBUS_MSG_DATA, req->peer); + if (ret < 0) + return UBUS_STATUS_NO_DATA; + + return 0; +} + void ubus_invoke_async(struct ubus_context *ctx, uint32_t obj, const char *method, struct blob_attr *msg, struct ubus_request *req) { @@ -523,7 +553,7 @@ int ubus_publish(struct ubus_context *ctx, struct ubus_object *obj) return UBUS_STATUS_INVALID_ARGUMENT; ubus_start_request(ctx, &req, b.head, UBUS_MSG_PUBLISH, 0); - req.data_cb = ubus_publish_cb; + req.raw_data_cb = ubus_publish_cb; req.priv = obj; ret = ubus_complete_request(ctx, &req); if (ret) diff --git a/libubus.h b/libubus.h index b741e65..8658118 100644 --- a/libubus.h +++ b/libubus.h @@ -6,12 +6,13 @@ #include "ubusmsg.h" #include "ubus_common.h" +struct ubus_context; struct ubus_msg_src; struct ubus_object; struct ubus_request; struct ubus_request_data; -typedef int (*ubus_handler_t)(struct ubus_object *obj, +typedef int (*ubus_handler_t)(struct ubus_context *ctx, 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, @@ -105,6 +106,7 @@ struct ubus_request { uint32_t peer; uint32_t seq; + ubus_data_handler_t raw_data_cb; ubus_data_handler_t data_cb; ubus_complete_handler_t complete_cb; @@ -152,4 +154,6 @@ void ubus_invoke_async(struct ubus_context *ctx, uint32_t obj, const char *metho /* make an object visible to remote connections */ int ubus_publish(struct ubus_context *ctx, struct ubus_object *obj); - +/* send a reply to an incoming object method call */ +int ubus_send_reply(struct ubus_context *ctx, struct ubus_request_data *req, + struct blob_attr *msg); diff --git a/listener.c b/listener.c index ffd8d6e..188cda8 100644 --- a/listener.c +++ b/listener.c @@ -1,6 +1,7 @@ #include "libubus.h" static struct ubus_context *ctx; +struct blob_buf b; static const struct ubus_signature test_object_sig[] = { UBUS_METHOD_START("hello"), @@ -15,10 +16,13 @@ static const struct ubus_signature test_object_sig[] = { 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) +static int test_hello(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) { - fprintf(stderr, "Hello, world!\n"); + blob_buf_init(&b, 0); + blobmsg_add_string(&b, "message", "Hello, world!\n"); + ubus_send_reply(ctx, req, b.head); return 0; } -- 2.11.0