From 83a6386edea4c246b7514f90118cd31dac573eba Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 31 Jan 2011 18:26:24 +0100 Subject: [PATCH] libubus: add generic lookup code --- cli.c | 67 ++++++++++++------------------------------------------ libubus.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ libubus.h | 18 +++++++++++++++ 3 files changed, 101 insertions(+), 52 deletions(-) diff --git a/cli.c b/cli.c index 45addc6..54db4a2 100644 --- a/cli.c +++ b/cli.c @@ -1,27 +1,17 @@ #include "libubus.h" -static struct blob_buf b; -static struct ubus_context *ctx; -static uint32_t objid; - -static void receive_lookup(struct ubus_request *req, int type, struct blob_attr *msg) +static void receive_lookup(struct ubus_context *ctx, struct ubus_object_data *obj, void *priv) { - struct blob_attr **attr, *cur; + struct blob_attr *cur; char *s; int rem; - attr = ubus_parse_msg(msg); - if (!attr[UBUS_ATTR_OBJID] || !attr[UBUS_ATTR_OBJPATH]) + fprintf(stderr, "'%s' @%08x\n", obj->path, obj->id); + + if (!obj->signature) return; - fprintf(stderr, "'%s' @%08x\n", - (char *) blob_data(attr[UBUS_ATTR_OBJPATH]), - blob_get_int32(attr[UBUS_ATTR_OBJID])); - - if (!attr[UBUS_ATTR_SIGNATURE]) - return; - - blob_for_each_attr(cur, attr[UBUS_ATTR_SIGNATURE], rem) { + blob_for_each_attr(cur, obj->signature, rem) { s = blobmsg_format_json(cur, false); fprintf(stderr, "\t%s\n", s); free(s); @@ -36,30 +26,6 @@ static void receive_data(struct ubus_request *req, int type, struct blob_attr *m 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; - - attr = ubus_parse_msg(msg); - if (!attr[UBUS_ATTR_OBJID]) - return; - - objid = blob_get_int32(attr[UBUS_ATTR_OBJID]); -} - -static uint32_t get_object(const char *name) -{ - struct ubus_request req; - - 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.raw_data_cb = store_objid; - if (ubus_complete_request(ctx, &req)) - return 0; - - return objid; -} static int usage(char *prog) { @@ -74,7 +40,7 @@ static int usage(char *prog) int main(int argc, char **argv) { - struct ubus_request req; + static struct ubus_context *ctx; char *cmd; int ret; @@ -89,24 +55,21 @@ int main(int argc, char **argv) return usage(argv[0]); if (!strcmp(cmd, "list")) { - blob_buf_init(&b, 0); + const char *path = NULL; if (argc == 3) - blob_put_string(&b, UBUS_ATTR_OBJPATH, argv[2]); + path = argv[2]; - ubus_start_request(ctx, &req, b.head, UBUS_MSG_LOOKUP, 0); - req.raw_data_cb = receive_lookup; - ret = ubus_complete_request(ctx, &req); + ret = ubus_lookup(ctx, path, receive_lookup, NULL); } else if (!strcmp(cmd, "call")) { + uint32_t id; + if (argc < 4 || argc > 5) return usage(argv[0]); - if (get_object(argv[2]) == 0) { - fprintf(stderr, "Object not found\n"); - return 1; - } - - ret = ubus_invoke(ctx, objid, argv[3], NULL, receive_data, NULL); + ret = ubus_lookup_id(ctx, argv[2], &id); + if (!ret) + ret = ubus_invoke(ctx, id, argv[3], NULL, receive_data, NULL); } else { return usage(argv[0]); } diff --git a/libubus.c b/libubus.c index fa7f5ca..97cdfc8 100644 --- a/libubus.c +++ b/libubus.c @@ -423,6 +423,74 @@ skip: } } +struct ubus_lookup_request { + struct ubus_request req; + ubus_lookup_handler_t cb; +}; + +static void ubus_lookup_cb(struct ubus_request *ureq, int type, struct blob_attr *msg) +{ + struct ubus_lookup_request *req; + struct ubus_object_data obj; + struct blob_attr **attr; + + req = container_of(ureq, struct ubus_lookup_request, req); + attr = ubus_parse_msg(msg); + + if (!attr[UBUS_ATTR_OBJID] || !attr[UBUS_ATTR_OBJPATH] || + !attr[UBUS_ATTR_OBJTYPE]) + return; + + memset(&obj, 0, sizeof(obj)); + obj.id = blob_get_int32(attr[UBUS_ATTR_OBJID]); + obj.path = blob_data(attr[UBUS_ATTR_OBJPATH]); + obj.type_id = blob_get_int32(attr[UBUS_ATTR_OBJTYPE]); + obj.signature = attr[UBUS_ATTR_SIGNATURE]; + req->cb(ureq->ctx, &obj, ureq->priv); +} + +int ubus_lookup(struct ubus_context *ctx, const char *path, + ubus_lookup_handler_t cb, void *priv) +{ + struct ubus_lookup_request lookup; + + blob_buf_init(&b, 0); + if (path) + blob_put_string(&b, UBUS_ATTR_OBJPATH, path); + ubus_start_request(ctx, &lookup.req, b.head, UBUS_MSG_LOOKUP, 0); + lookup.req.raw_data_cb = ubus_lookup_cb; + lookup.req.priv = priv; + lookup.cb = cb; + return ubus_complete_request(ctx, &lookup.req); +} + +static void ubus_lookup_id_cb(struct ubus_request *req, int type, struct blob_attr *msg) +{ + struct blob_attr **attr; + uint32_t *id = req->priv; + + attr = ubus_parse_msg(msg); + + if (!attr[UBUS_ATTR_OBJID]) + return; + + *id = blob_get_int32(attr[UBUS_ATTR_OBJID]); +} + +int ubus_lookup_id(struct ubus_context *ctx, const char *path, uint32_t *id) +{ + struct ubus_request req; + + blob_buf_init(&b, 0); + if (path) + blob_put_string(&b, UBUS_ATTR_OBJPATH, path); + ubus_start_request(ctx, &req, b.head, UBUS_MSG_LOOKUP, 0); + req.raw_data_cb = ubus_lookup_id_cb; + req.priv = id; + + return ubus_complete_request(ctx, &req); +} + int ubus_send_reply(struct ubus_context *ctx, struct ubus_request_data *req, struct blob_attr *msg) { diff --git a/libubus.h b/libubus.h index 8658118..290b5c3 100644 --- a/libubus.h +++ b/libubus.h @@ -11,7 +11,11 @@ struct ubus_msg_src; struct ubus_object; struct ubus_request; struct ubus_request_data; +struct ubus_object_data; +typedef void (*ubus_lookup_handler_t)(struct ubus_context *ctx, + struct ubus_object_data *obj, + void *priv); 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); @@ -88,6 +92,13 @@ struct ubus_context { } msgbuf; }; +struct ubus_object_data { + uint32_t id; + uint32_t type_id; + const char *path; + struct blob_attr *signature; +}; + struct ubus_request_data { uint32_t object; uint32_t peer; @@ -141,6 +152,13 @@ void ubus_complete_request_async(struct ubus_context *ctx, /* abort an asynchronous request */ void ubus_abort_request(struct ubus_context *ctx, struct ubus_request *req); +/* ----------- objects ----------- */ + +int ubus_lookup(struct ubus_context *ctx, const char *path, + ubus_lookup_handler_t cb, void *priv); + +int ubus_lookup_id(struct ubus_context *ctx, const char *path, uint32_t *id); + /* ----------- rpc ----------- */ /* invoke a method on a specific object */