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"
|
#include "libubus.h"
|
||||||
|
|
||||||
static struct blob_buf b;
|
static void receive_lookup(struct ubus_context *ctx, struct ubus_object_data *obj, void *priv)
|
||||||
static struct ubus_context *ctx;
|
|
||||||
static uint32_t objid;
|
|
||||||
|
|
||||||
static void receive_lookup(struct ubus_request *req, int type, struct blob_attr *msg)
|
|
||||||
{
|
{
|
||||||
struct blob_attr **attr, *cur;
|
struct blob_attr *cur;
|
||||||
char *s;
|
char *s;
|
||||||
int rem;
|
int rem;
|
||||||
|
|
||||||
attr = ubus_parse_msg(msg);
|
fprintf(stderr, "'%s' @%08x\n", obj->path, obj->id);
|
||||||
if (!attr[UBUS_ATTR_OBJID] || !attr[UBUS_ATTR_OBJPATH])
|
|
||||||
|
if (!obj->signature)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fprintf(stderr, "'%s' @%08x\n",
|
blob_for_each_attr(cur, obj->signature, rem) {
|
||||||
(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) {
|
|
||||||
s = blobmsg_format_json(cur, false);
|
s = blobmsg_format_json(cur, false);
|
||||||
fprintf(stderr, "\t%s\n", s);
|
fprintf(stderr, "\t%s\n", s);
|
||||||
free(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));
|
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)
|
static int usage(char *prog)
|
||||||
{
|
{
|
||||||
|
@ -74,7 +40,7 @@ static int usage(char *prog)
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct ubus_request req;
|
static struct ubus_context *ctx;
|
||||||
char *cmd;
|
char *cmd;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -89,24 +55,21 @@ int main(int argc, char **argv)
|
||||||
return usage(argv[0]);
|
return usage(argv[0]);
|
||||||
|
|
||||||
if (!strcmp(cmd, "list")) {
|
if (!strcmp(cmd, "list")) {
|
||||||
blob_buf_init(&b, 0);
|
const char *path = NULL;
|
||||||
|
|
||||||
if (argc == 3)
|
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);
|
ret = ubus_lookup(ctx, path, receive_lookup, NULL);
|
||||||
req.raw_data_cb = receive_lookup;
|
|
||||||
ret = ubus_complete_request(ctx, &req);
|
|
||||||
} else if (!strcmp(cmd, "call")) {
|
} else if (!strcmp(cmd, "call")) {
|
||||||
|
uint32_t id;
|
||||||
|
|
||||||
if (argc < 4 || argc > 5)
|
if (argc < 4 || argc > 5)
|
||||||
return usage(argv[0]);
|
return usage(argv[0]);
|
||||||
|
|
||||||
if (get_object(argv[2]) == 0) {
|
ret = ubus_lookup_id(ctx, argv[2], &id);
|
||||||
fprintf(stderr, "Object not found\n");
|
if (!ret)
|
||||||
return 1;
|
ret = ubus_invoke(ctx, id, argv[3], NULL, receive_data, NULL);
|
||||||
}
|
|
||||||
|
|
||||||
ret = ubus_invoke(ctx, objid, argv[3], NULL, receive_data, NULL);
|
|
||||||
} else {
|
} else {
|
||||||
return usage(argv[0]);
|
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,
|
int ubus_send_reply(struct ubus_context *ctx, struct ubus_request_data *req,
|
||||||
struct blob_attr *msg)
|
struct blob_attr *msg)
|
||||||
{
|
{
|
||||||
|
|
18
libubus.h
18
libubus.h
|
@ -11,7 +11,11 @@ struct ubus_msg_src;
|
||||||
struct ubus_object;
|
struct ubus_object;
|
||||||
struct ubus_request;
|
struct ubus_request;
|
||||||
struct ubus_request_data;
|
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,
|
typedef int (*ubus_handler_t)(struct ubus_context *ctx, struct ubus_object *obj,
|
||||||
struct ubus_request_data *req,
|
struct ubus_request_data *req,
|
||||||
const char *method, struct blob_attr *msg);
|
const char *method, struct blob_attr *msg);
|
||||||
|
@ -88,6 +92,13 @@ struct ubus_context {
|
||||||
} msgbuf;
|
} msgbuf;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ubus_object_data {
|
||||||
|
uint32_t id;
|
||||||
|
uint32_t type_id;
|
||||||
|
const char *path;
|
||||||
|
struct blob_attr *signature;
|
||||||
|
};
|
||||||
|
|
||||||
struct ubus_request_data {
|
struct ubus_request_data {
|
||||||
uint32_t object;
|
uint32_t object;
|
||||||
uint32_t peer;
|
uint32_t peer;
|
||||||
|
@ -141,6 +152,13 @@ void ubus_complete_request_async(struct ubus_context *ctx,
|
||||||
/* abort an asynchronous request */
|
/* abort an asynchronous request */
|
||||||
void ubus_abort_request(struct ubus_context *ctx, struct ubus_request *req);
|
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 ----------- */
|
/* ----------- rpc ----------- */
|
||||||
|
|
||||||
/* invoke a method on a specific object */
|
/* invoke a method on a specific object */
|
||||||
|
|
Loading…
Add table
Reference in a new issue