ubus[2]-libus
11037 ワード
libus
データ構造
インターフェースの説明
データ構造
データ構造
データ構造
新しいobjectをubusdに登録します.
objectを定義する方法:
イベントトリガのコールバック方法を指定します.
コマンドの折り返し方法を指定します.
データ構造
struct ubus_event_handler {
struct ubus_object obj;
ubus_event_handler_t cb;
};
struct ubus_context {
struct list_head requests;
struct avl_tree objects; /** client object */
struct list_head pending;
struct uloop_fd sock; /** client sock */
uint32_t local_id; /** ubusd client id */
uint16_t request_seq;
int stack_depth;
/** */
void (*connection_lost)(struct ubus_context *ctx);
struct {
struct ubus_msghdr hdr;
char data[UBUS_MAX_MSGLEN];
} 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;
uint16_t seq;
/* internal use */
bool deferred;
int fd;
};
struct ubus_request {
struct list_head list;
struct list_head pending;
int status_code;
bool status_msg;
bool blocked;
bool cancelled;
bool notify;
uint32_t peer;
uint16_t seq;
ubus_data_handler_t raw_data_cb;
ubus_data_handler_t data_cb;
ubus_fd_handler_t fd_cb;
ubus_complete_handler_t complete_cb;
struct ubus_context *ctx;
void *priv;
};
struct ubus_notify_request {
struct ubus_request req;
ubus_notify_complete_handler_t status_cb;
ubus_notify_complete_handler_t complete_cb;
uint32_t pending;
uint32_t id[UBUS_MAX_NOTIFY_PEERS + 1];
};
struct ubus_auto_conn {
struct ubus_context ctx;
struct uloop_timeout timer;
const char *path;
ubus_connect_handler_t cb;
};
インターフェースの説明/**
* client context , ubusd
*/
struct ubus_context *ubus_connect(const char *path)
/**
* ubus_connect() ,
*/
void ubus_auto_connect(struct ubus_auto_conn *conn)
/**
*
*/
int ubus_register_event_handler(struct ubus_context *ctx,
struct ubus_event_handler *ev,
const char *pattern)
/**
*
*/
int ubus_send_event(struct ubus_context *ctx, const char *id,
struct blob_attr *data)
/**
* ubusd UBUS_ATTR_OBJPATH
* ubus_lookup_handler_t
*/
int ubus_lookup(struct ubus_context *ctx, const char *path,
ubus_lookup_handler_t cb, void *priv)
/**
* ubusd UBUS_ATTR_OBJPATH ID
*/
int ubus_lookup_id(struct ubus_context *ctx, const char *path, uint32_t *id)
libus-iインターフェースの説明
/**
* libubus
*/
static const struct blob_attr_info ubus_policy[UBUS_ATTR_MAX] = {
[UBUS_ATTR_STATUS] = { .type = BLOB_ATTR_INT32 },
[UBUS_ATTR_OBJID] = { .type = BLOB_ATTR_INT32 },
[UBUS_ATTR_OBJPATH] = { .type = BLOB_ATTR_STRING },
[UBUS_ATTR_METHOD] = { .type = BLOB_ATTR_STRING },
[UBUS_ATTR_ACTIVE] = { .type = BLOB_ATTR_INT8 },
[UBUS_ATTR_NO_REPLY] = { .type = BLOB_ATTR_INT8 },
[UBUS_ATTR_SUBSCRIBERS] = { .type = BLOB_ATTR_NESTED },
};
/**
* libubus blob_attr
*/
__hidden struct blob_attr **ubus_parse_msg(struct blob_attr *msg)
/**
*
*
* @param ctx - client
* @param seq - hdr.seq
* @param msg -
* @param cmd - hdr.type
* @param perr -
* @param fd - , -1
*/
int __hidden ubus_send_msg(struct ubus_context *ctx, uint32_t seq,
struct blob_attr *msg, int cmd, uint32_t peer, int fd)
/**
* client fd
*/
void __hidden ubus_handle_data(struct uloop_fd *u, unsigned int events)
/**
* client fd
*/
void __hidden ubus_poll_data(struct ubus_context *ctx, int timeout)
/**
* client ubusd server
*/
int ubus_reconnect(struct ubus_context *ctx, const char *path)
libus-objデータ構造
struct ubus_object {
struct avl_node avl; /** struct ubus_context objects */
const char *name; /** UBUS_ATTR_OBJPATH */
uint32_t id; /** ubusd server obj id */
const char *path;
struct ubus_object_type *type;
/** 1 1 */
ubus_state_handler_t subscribe_cb;
bool has_subscribers; /** */
const struct ubus_method *methods; /** */
int n_methods; /** */
};
struct ubus_object_type {
const char *name;
uint32_t id; /** ubusd server obj type id */
const struct ubus_method *methods; /** */
int n_methods; /** */
};
struct ubus_method {
const char *name; /** */
ubus_handler_t handler; /** */
unsigned long mask; /** */
const struct blobmsg_policy *policy; /** */
int n_policy; /** */
};
インターフェースの説明/**
* client ubusd server object
*/
int ubus_add_object(struct ubus_context *ctx, struct ubus_object *obj)
/**
* client ubusd server object
*/
int ubus_remove_object(struct ubus_context *ctx, struct ubus_object *obj)
/**
* object
*/
void __hidden ubus_process_obj_msg(struct ubus_context *ctx,
struct ubus_msghdr *hdr)
/**
* UBUS_MSG_INVOKE
*/
static void
ubus_process_invoke(struct ubus_context *ctx, struct ubus_msghdr *hdr,
struct ubus_object *obj, struct blob_attr **attrbuf)
/**
* UBUS_MSG_UNSUBSCRIBE
*/
static void
ubus_process_unsubscribe(struct ubus_context *ctx, struct ubus_msghdr *hdr,
struct ubus_object *obj, struct blob_attr **attrbuf)
/**
* UBUS_MSG_NOTIFY
*/
static void
ubus_process_notify(struct ubus_context *ctx, struct ubus_msghdr *hdr,
struct ubus_object *obj, struct blob_attr **attrbuf)
libus-subデータ構造
struct ubus_subscriber {
struct ubus_object obj;
ubus_handler_t cb;
ubus_remove_handler_t remove_cb;
};
インターフェースの説明/**
*
*/
int ubus_register_subscriber(struct ubus_context *ctx, struct ubus_subscriber *s)
/**
*
*/
int ubus_subscribe(struct ubus_context *ctx, struct ubus_subscriber *obj,
uint32_t id)
/**
*
*/
int ubus_unsubscribe(struct ubus_context *ctx, struct ubus_subscriber *obj,
uint32_t id)
libus-reqデータ構造
struct ubus_request_data {
uint32_t object;
uint32_t peer;
uint16_t seq;
/* internal use */
bool deferred;
int fd;
};
struct ubus_request {
struct list_head list;
struct list_head pending;
int status_code;
bool status_msg;
bool blocked;
bool cancelled;
bool notify;
uint32_t peer;
uint16_t seq;
ubus_data_handler_t raw_data_cb;
ubus_data_handler_t data_cb;
ubus_fd_handler_t fd_cb;
ubus_complete_handler_t complete_cb;
struct ubus_context *ctx;
void *priv;
};
struct ubus_notify_request {
struct ubus_request req;
ubus_notify_complete_handler_t status_cb;
ubus_notify_complete_handler_t complete_cb;
uint32_t pending;
uint32_t id[UBUS_MAX_NOTIFY_PEERS + 1];
};
インターフェースの説明/**
* , UBUS_MSG_DATA
*/
int ubus_send_reply(struct ubus_context *ctx, struct ubus_request_data *req,
struct blob_attr *msg)
/**
* object
*/
int ubus_invoke_async(struct ubus_context *ctx, uint32_t obj, const char *method,
struct blob_attr *msg, struct ubus_request *req)
/**
* object
*/
int ubus_invoke(struct ubus_context *ctx, uint32_t obj, const char *method,
struct blob_attr *msg, ubus_data_handler_t cb, void *priv,
int timeout)
/**
*
*/
int ubus_notify_async(struct ubus_context *ctx, struct ubus_object *obj,
const char *type, struct blob_attr *msg,
struct ubus_notify_request *req)
/**
*
*/
int ubus_notify(struct ubus_context *ctx, struct ubus_object *obj,
const char *type, struct blob_attr *msg, int timeout)
例新しいobjectをubusdに登録します.
objectを定義する方法:
enum {
OBJ_SET_ARG1,
OBJ_SET_ARG2,
__OBJ_SET_ATTR_MAX
};
/** set */
static const struct blobmsg_policy obj_set_attrs[__OBJ_SET_ATTR_MAX] = {
[OBJ_SET_ARG1] = { .name = "arg1", .type = BLOBMSG_TYPE_STRING },
[OBJ_SET_ARG2 ] = { .name = "arg2", .type = BLOBMSG_TYPE_STRING },
};
static struct ubus_method obj_methods[] = {
{ .name = "enable", .handler = obj_enable },
UBUS_METHOD("set", obj_set, obj_set_attrs),
{ .name = "dump", .handler = obj_dump },
};
objectのタイプを定義しますstatic struct ubus_object_type obj_type =
UBUS_OBJECT_TYPE("my_obj", obj_methods);
定義object:static struct ubus_object obj = {
.name = "myobj",
.type = &obj_type,
.methods = obj_methods,
.n_methods = ARRAR_SIZE(obj_methods),
};
新しいobjectを登録する: uloop_init();
struct ubus_context *ubus_ctx = ubus_connect(NULL);
ubus_add_uloop(ubus_ctx);
ubus_add_object(ubus_ctx, &obj);
uloop_run();
ubusd登録イベントの傍受イベントトリガのコールバック方法を指定します.
static void
event_receive_cb(struct ubus_context *ctx, struct ubus_event_handler *ev,
const char *type, struct blob_attr *msg)
{
enum {
EV_ACTION,
EV_IFNAME,
__EV_MAX
};
static const struct blobmsg_policy ev_policy[__EV_MAX] = {
[EV_ACTION] = { .name = "action", .type = BLOBMSG_TYPE_STRING },
[EV_IFNAME] = { .name = "interface", .type = BLOBMSG_TYPE_STRING },
};
struct blob_attr *tb[__EV_MAX];
blobmsg_parse(ev_policy, __EV_MAX, tb, blob_data(msg), blob_len(msg));
/* do something */
}
登録傍受イベントstatic void
event_listen(void)
{
static struct ubus_event_handler listener;
memset(&listener, 0, sizeof(listener));
/** netwrok.interface */
ubus_register_event_handler(ubus_ctx, &listener, "network.interface");
}
ubusdにコマンドを送信します.コマンドの折り返し方法を指定します.
static void
command_cb(struct ubus_request *req, int type, struct blob_attr *msg)
{
if (!msg)
return;
enum {
ADDR_IPV4,
__ADDR_MAX,
};
static const struct blobmsg_policy policy[__ADDR_MAX] = {
[ADDR_IPV4] = { .name = "ipv4-address", .type = BLOBMSG_TYPE_ARRAY },
};
struct blob_attr *tb[__ADDR_MAX];
blobmsg_parse(policy, __ADDR_MAX, tb, blobmsg_data(msg), blobmsg_len(msg));
/** do something */
}
コマンドを送信:static void
invoke_command(char *net)
{
uint32_t id;
char path[64] = {0};
sprintf(path, "network.interface.%s", net);
/** lookup `network.interface.%s` object id */
ubus_lookup_id(ubus_ctx, path, &id);
/** invoke command `status` */
ubus_invoke(ubus_ctx, id, "status", NULL, command_cb, NULL, 500);
}