libubus: add generic lookup code
This commit is contained in:
parent
480a3d66a7
commit
83a6386ede
3 changed files with 101 additions and 52 deletions
67
cli.c
67
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]);
|
||||
}
|
||||
|
|
68
libubus.c
68
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)
|
||||
{
|
||||
|
|
18
libubus.h
18
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 */
|
||||
|
|
Loading…
Reference in a new issue