ubus說明
更新記錄
item | note |
---|---|
20160726 | 第一版 |
20161129 | 增加: ubus範例 ,ubusd & ubus程序 |
20170206 | 增加usbd內容 |
目錄
Ubus
- OpenWrt micro bus architecture
- To provide communication between various daemons and applications in OpenWrt an ubus project has been developed
Ubus Source
- ubus.git
OpenWrt system message/RPC bus
source
- OpenWrt Chaos Calmer 15.05.1 r49118
item | version | download |
---|---|---|
ubus | build_dir/target-mips_34kc_uClibc-0.9.33.2/ubus-2015-05-25 | ubus-f361bfa.tar.gz |
json-c | build_dir/target-mips_34kc_uClibc-0.9.33.2/json-c-0.12 | json-c-0.12-20140410.tar.gz |
libubox | build_dir/target-mips_34kc_uClibc-0.9.33.2/libubox-2015-11-08 | |
build_dir/target-mips_34kc_uClibc-0.9.33.2/lua-5.1.5 | lua-5.1.5.tar.gz |
ubus相依下例tools
- json-c
- lua
- libubox
json-c cross compile
1
2./configure --prefix=$(ROOTFS_DIR) --build=i686-pc-linux-gnu --host=arm-hisiv200-linux --target=arm-hisiv200-linux CC=arm-hisiv200-linux-gcc
make & make install
ubus範例
openwrt
ubus list
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15root@OpenWrt:~# ubus list
dhcp
log
network
network.device
network.interface
network.interface.lan
network.interface.loopback
network.interface.wan
network.interface.wan6
network.wireless
service
session
system
uciubus list -v network.interface.lan
1
2
3
4
5
6
7
8
9
10
11
12root@OpenWrt:~# ubus list -v network.interface.lan
'network.interface.lan' @3656e47f
"up":{}
"down":{}
"status":{}
"prepare":{}
"dump":{}
"add_device":{"name":"String","link-ext":"Boolean"}
"remove_device":{"name":"String","link-ext":"Boolean"}
"notify_proto":{}
"remove":{}
"set_data":{}
ubus command
- ubus command
1
2
3
4
5
6
7
8
9
10
11
12
13
14root@OpenWrt:~# ubus
Usage: ubus [<options>] <command> [arguments...]
Options:
-s <socket>: Set the unix domain socket to connect to
-t <timeout>: Set the timeout (in seconds) for a command to complete
-S: Use simplified output (for scripts)
-v: More verbose output
Commands:
- list [<path>] List objects
- call <path> <method> [<message>] Call an object method
- listen [<path>...] Listen for events
- send <type> [<message>] Send an event
- wait_for <object> [<object>...] Wait for multiple objects to appear on ubus
ubus example
ubus
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18/ubus-ex # ./server
Watching object 4f90a5c1: Success
Object 4f90a5c1 went away
/ubus-ex # ./client
Avg time per iteration: 39 usec
Subscribers active: 1
Got fd from the server, watching...
completed request, ret: 0
Avg time per iteration: 51 usec
Got line: msg1: test received a message: blah
Sending count up to '100100'; string has length '592926'
Server validated our count up to '100100'
Avg time per iteration: 48 usec
Avg time per iteration: 46 usec
~ # ubus list
testserver test
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16~ # ubus list -v
'test' @69f7a210
"hello":{"id":"Integer","msg":"String"}
"watch":{"id":"Integer","counter":"Integer"}
"count":{"to":"Integer","string":"String"}
~ # ubus call test hello '{"id":1, "msg":"t11"}'
{
"message": "test received a message: t11"
}
~ #
~ # ubus call test count '{"to":5, "string":"5"}'
{
"rc": 5
}
server
test_object
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15static const struct ubus_method test_methods[] = {
UBUS_METHOD("hello", test_hello, hello_policy),
UBUS_METHOD("watch", test_watch, watch_policy),
UBUS_METHOD("count", test_count, count_policy),
};
static struct ubus_object_type test_object_type =
UBUS_OBJECT_TYPE("test", test_methods);
static struct ubus_object test_object = {
.name = "test",
.type = &test_object_type,
.methods = test_methods,
.n_methods = ARRAY_SIZE(test_methods),
};ubus list
1
2~ # ubus list
testubus list -v
1
2
3
4
5~ # ubus list -v
'test' @47a0bfd5
"hello":{"id":"Integer","msg":"String"}
"watch":{"id":"Integer","counter":"Integer"}
"count":{"to":"Integer","string":"String"}
client
- test_client_object
1
2
3
4
5
6
7
8static void test_client_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj)
{
fprintf(stderr, "Subscribers active: %d\n", obj->has_subscribers);
}
static struct ubus_object test_client_object = {
.subscribe_cb = test_client_subscribe_cb,
};
ubusd & ubus程序
ubusd由下例組成
1
2ADD_EXECUTABLE(ubusd ubusd.c ubusd_id.c ubusd_obj.c ubusd_proto.c ubusd_event.c)
TARGET_LINK_LIBRARIES(ubusd ubox)ubus由下例組成
1
2cli.c
libubus.so -lubox -lblobmsg_json libjson-c.solibubus.so由下例組成
1
2ADD_LIBRARY(ubus SHARED libubus.c libubus-io.c libubus-obj.c libubus-sub.c libubus-req.c)
TARGET_LINK_LIBRARIES(ubus ubox m)
ubusd
- server_fd
1
2
3static struct uloop_fd server_fd = {
.cb = server_cb,
};
- ubusd
在ubusd在執行main之前會先執行ubusd_obj_init- ubusd_obj_init
- 初始化avl_tree的3個變數:objects, obj_type, path
- ubusd_event_init,初始化event_obj
1 | static void __constructor ubusd_obj_init(void) |
libubus
libubus 數據結構
- ubus_event_handler
- ubus_context
- sock: client sock
- local_id
- strcut avl_tree object : client端object鏈表頭
libubus 接口說明
ubus_context
struct ubus_context ubus_connect(const char *path);
初始化client端context結構,開啟連接ubusdubus_add_object
int ubus_add_object(struct ubus_context ctx, struct ubus_object obj);
make an object visible to remote connectionsubus_register_subscriber
add a subscriber notifications from another object
ubus_msg_type | note |
---|---|
UBUS_MSG_DATA | data message response |
ex. ubus_send_reply | UBUS_ATTR_OBJID |
ubus_send_msg (UBUS_MSG_DATA) |
ubus_msg_attr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23enum ubus_msg_attr {
UBUS_ATTR_UNSPEC,
UBUS_ATTR_STATUS,
UBUS_ATTR_OBJPATH,
UBUS_ATTR_OBJID,
UBUS_ATTR_METHOD,
UBUS_ATTR_OBJTYPE,
UBUS_ATTR_SIGNATURE,
UBUS_ATTR_DATA,
UBUS_ATTR_TARGET,
UBUS_ATTR_ACTIVE,
UBUS_ATTR_NO_REPLY,
UBUS_ATTR_SUBSCRIBERS,
/* must be last */
UBUS_ATTR_MAX,
};ubus_msg_status
1
2
3
4
5
6
7
8
9
10
11
12
13
14enum ubus_msg_status {
UBUS_STATUS_OK,
UBUS_STATUS_INVALID_COMMAND,
UBUS_STATUS_INVALID_ARGUMENT,
UBUS_STATUS_METHOD_NOT_FOUND,
UBUS_STATUS_NOT_FOUND,
UBUS_STATUS_NO_DATA,
UBUS_STATUS_PERMISSION_DENIED,
UBUS_STATUS_TIMEOUT,
UBUS_STATUS_NOT_SUPPORTED,
UBUS_STATUS_UNKNOWN_ERROR,
UBUS_STATUS_CONNECTION_FAILED,
__UBUS_STATUS_LAST
};
ubusd程序如下
來源:ubus 1
新client连接时 创建struct ubus_client数据结构
初始化client fd回调函数client_cb,并加入到全局clients avl_tree中进行维护client_cb
- ubusd_proto_receive_message
- ubus_msg_send
- ubusd_proto_receive_message
1 | struct ubus_msg_buf { |
hdr.type 定義如下 :
UBUS_MSG_ADD_OBJECT
创建内部object,回应一个类型为UBUS_MSG_DATA的报文,报文内容有由ubusd生成的UBUS_ATTR_OBJIDUBUS_MSG_LOOKUP
查询object,根据请求报文UBUS_ATTR_OBJPATH查找对应的object
使用ubusd_send_obj()函数把查询出object内容回应给查询请求者UBUS_MSG_SUBSCRIBE
订阅object,使用ubus_subscribe()函数订阅指定object
當ubusd收到event處理
ubusd處理下例兩種event
- register
- Register注册某个object事件,使用ubusd_alloc_event_pattern()函数创建事件对象并加入到全局patterns队列中
- event內容如下
1 | static struct blobmsg_policy evr_policy[] = { |
- send
- Send转发某个事件内容,使用ubusd_forward_event()函数把指定事件内容转发给此事件所属的object拥有者 事件报文内容
- event內容如下
1 | static struct blobmsg_policy ev_policy[] = { |
- The kevent() system call is used to register events with the queue, and return any pending events to the user.