【转】openwrt中ubus

参考链接:

openwrt中ubus的具体使用

openwrt ubus的wiki

[openwrt] 使用ubus实现进程通信

[openwrt] ubus实现进程间通信举例

openwrt ubus简介以及libubus开发说明

ubus [1] - ubusd

ubus [2] - libubus

ubus [3] - cli

libubox组件(1)——usock

libubox组件(2)——blob/blobmsg

libubox组件(3)——uloop

ubus数据结构和接口介绍

 

ubus简介

ubus是为了OpenWrt中守护进程和应用程序之间通讯开发的,类似桌面的DBus,设计理念上与DBus基本保持一致,区别是简化的API和简练的模型,以适应embeddedrouter的特殊环境。与DBus一样也是使用socket实现。


核心部分是ubusd守护进程,它提供了其他守护进程将自己注册以及发送消息的接口。因为这个,接口通过使用Unixsocket来实现,并使用TLV(type-length-value)消息,ubus内部使用Blob_buf,Blob_attr等结构来表示。


ubus有两种调用,一个是method调用,一个是notification,其中method包括等待函数返回和不用等待返回,notification是广播和DBus的signal类似。ubus使用是先建立连接,然后把连接加入epollset中。

 

下面是它的一些调用API。
uloop_init(); 创建epoll句柄,最多监听32个fd
ubus_connect(); 创建ubus连接
ubus_add_uloop(); 把创建的ubus连接注册到epoll中。
ubus_add_object(); 注册对象到的ubus连接。
uloop_run(); 等待I/O事件发生,调用相对应的对象的功能函数。
ubus_free(); 关闭ubus连接
uloop_done(); 关闭epoll句柄

 

ubusd启动

属于procd启动的一项:

/etc/preinit --> /sbin/init --> /sbin/procd --> /sbin/ubusd

 

注册ubus服务的应用

pathDescriptionPackage
dhcpdhcp serverodhcpd
filefilerpcd
hostapdacesspointswpad/hostapd
iwinfowireless informationsrpcd iwinfo
logloggingprocd
mdnsmdns avahi replacementmdnsd
networknetworknetifd
serviceinit/serviceprocd
sessionSession managementrpcd
systemsystem miscprocd
uciUnified Configuration Interfacerpcd

 

ubus客户端

ubus调试有一个命令行工具叫ubus,ubus可以和ubusd服务器交互(和当前所有已经注册的服务).它对研究和调试注册的命名空间以及编写脚本非常有用。

可以调用带参数和返回信息的方法,它使用友好的JSON格式。

ubus命令使用说明

    ubus命令用于控制调试相关ubus接口,主要命令说明如下:

     - 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 list [-v] 该命令用于显示当前ubus中注册的接口,其中-v参数用以显示各个接口的详细信息。示例如下:       

root@uplink:~# ubus list
network
network.device
network.interface.lan
network.interface.loopback
network.interface.wan

root@uplink:~# ubus -v list network.interface.lan
'network.interface.lan' @099f0c8b
	"up": {  }
	"down": {  }
	"status": {  }
	"prepare": {  }
	"add_device": { "name": "String" }
	"remove_device": { "name": "String" }
	"notify_proto": {  }
	"remove": {  }
	"set_data": {  }

    ubus call 该命令用于调用ubus中当前注册的接口。示例如下:

调用无参方法
root@uplink:~# ubus call network.interface.wan status { "up": true, "pending": false, "available": true, "autostart": true, "uptime": 86017, "l3_device": "eth1", "device": "eth1", "address": [ { "address": "178.25.65.236", "mask": 21 } ], "route": [ { "target": "0.0.0.0", "mask": 0, "nexthop": "178.25.71.254" } ], "data": { } }
  调用有参方法
root@uplink:~# ubus call network.device status '{ "name": "eth0" }'
{
	"type": "Network device",
	"up": true,
	"link": true,
	"mtu": 1500,
	"macaddr": "c6:3d:c7:90:aa:da",
	"txqueuelen": 1000,
	"statistics": {
		"collisions": 0,
		"rx_frame_errors": 0,
		"tx_compressed": 0,
		"multicast": 0,
		"rx_length_errors": 0,
		"tx_dropped": 0,
		"rx_bytes": 0,
		"rx_missed_errors": 0,
		"tx_errors": 0,
		"rx_compressed": 0,
		"rx_over_errors": 0,
		"tx_fifo_errors": 0,
		"rx_crc_errors": 0,
		"rx_packets": 0,
		"tx_heartbeat_errors": 0,
		"rx_dropped": 0,
		"tx_aborted_errors": 0,
		"tx_packets": 184546,
		"rx_errors": 0,
		"tx_bytes": 17409452,
		"tx_window_errors": 0,
		"rx_fifo_errors": 0,
		"tx_carrier_errors": 0
	}
}
 

    ubus listen 用于监听ubus相关事件,如果不指定事件名则监听所有事件。(支持通配符*)

root@uplink:~# ubus listen &
root@uplink:~# ubus call network.interface.wan down
{ "network.interface": { "action": "ifdown", "interface": "wan" } }
root@uplink:~# ubus call network.interface.wan up
{ "network.interface": { "action": "ifup", "interface": "wan" } }
{ "network.interface": { "action": "ifdown", "interface": "he" } }
{ "network.interface": { "action": "ifdown", "interface": "v6" } }
{ "network.interface": { "action": "ifup", "interface": "he" } }
{ "network.interface": { "action": "ifup", "interface": "v6" } }

    ubus send 用于发送事件

root@uplink:~# ubus listen &
root@uplink:~# ubus send foo '{ "bar": "baz" }'
{ "foo": { "bar": "baz" } }

    ubus wait_for 用于等待指定项的注册到ubus中。

 

libubus使用

使用ubus时需要引用一些动态库,主要包括:

libubus.so:ubus向外部提供的编程接口,例如创建socket,进行监听和连接,发送消息等接口函数。
libubox.so:ubus向外部提供的编程接口,例如等待和读取消息。
libblobmsg_json.so,libjson.so:提供了封装和解析json数据的接口,编程时使用libblobmsg_json.so提供的更灵活的接口函数。

 

ubus的应用场景和局限性

ubus可用于两个进程之间的通信,并以类似json格式进行数据交互。ubus的常见场景为:

1)“客户端--服务器”形式的交互,即进程A注册一系列的服务,进程B去调用这些服务。
2)ubus支持以“订阅 -- 通知”的方式进行进程通信,即进程A提供订阅服务,其他进程可以选择订阅或退订该服务,进程A可以向所有订阅者发送消息。


由于ubus实现方式的限制,在一些场景中不适宜使用ubus:

1)ubus用于少量数据的传输,如果数据量很大或是数据交互很频繁,则不宜用ubus。经过测试,当ubus一次传输数据量超过60KB,就不能正常工作了。
2)ubus对多线程支持的不好,例如在多个线程中去请求同一个服务,就有可能出现不可预知的结果。
3)不建议递归调用ubus,例如进程A去调用进程B的服务,而B的该服务需要调用进程C的服务,之后C将结果返回给B,然后B将结果返回给A。如果不得不这样做,需要在调用过程中避免全局变量的重用问题。

 

转载于:https://www.cnblogs.com/cxt-janson/p/11532158.html

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenWrt ubus 是一种进程间通信系统,它允许应用程序之间进行简单的、安全的通信。它基于 Unix 套接字和 JSON-RPC 协议,并且是 OpenWrt 的一个重要组成部分,因为它提供了许多 OpenWrt 的核心功能。 在本教程,我们将介绍如何使用 ubusOpenWrt 进行进程间通信。 ## 安装 ubus 首先,我们需要在 OpenWrt 安装 ubus。可以通过以下命令来安装: ``` opkg update opkg install ubus ``` ## 使用 ubus ### ubus 命令行工具 ubus 命令行工具提供了一个简单的方式来与 ubus 服务进行交互。以下是一些常用的 ubus 命令: - `ubus call`:调用一个 ubus 方法。 - `ubus list`:列出所有可用的 ubus 方法。 - `ubus monitor`:监听 ubus 事件。 例如,要列出所有可用的 ubus 方法,可以运行以下命令: ``` ubus list ``` 你将看到一份所有可用的 ubus 方法的列表。 ### ubus 库 如果你希望在应用程序使用 ubus,可以使用 ubus 库。ubus 库是一个 C 库,允许应用程序通过编程方式调用 ubus 方法。 要使用 ubus 库,需要包含 `libubus.h` 头文件,并链接 `libubus` 库。以下是一个简单的例子: ```c #include <libubus.h> int main() { struct ubus_context *ctx = ubus_connect(NULL); if (!ctx) { printf("Failed to connect to ubus\n"); return 1; } struct blob_buf buf; blob_buf_init(&buf, 0); blobmsg_add_string(&buf, "message", "Hello, world!"); struct ubus_request req; ubus_request_init(ctx, &req, "example_method", &buf.head); if (ubus_invoke(ctx, &req)) { printf("Failed to invoke ubus method\n"); return 1; } return 0; } ``` 在这个例子,我们连接到 ubus 服务,并调用了一个名为 `example_method` 的 ubus 方法,传递了一个包含 `message` 字段的 blob 对象。当 ubus 方法被调用时,它会收到这个包含消息的 blob 对象,并且可以进行相应的操作。 ### ubus 事件 除了调用 ubus 方法之外,ubus 还支持事件。应用程序可以向 ubus 注册事件,并在事件发生时接收通知。以下是一个简单的例子: ```c #include <libubus.h> static void event_handler(struct ubus_context *ctx, struct ubus_event_handler *ev, const char *type, struct blob_attr *msg) { printf("Received event: %s\n", type); } int main() { struct ubus_context *ctx = ubus_connect(NULL); if (!ctx) { printf("Failed to connect to ubus\n"); return 1; } struct ubus_event_handler handler = { .cb = event_handler, }; ubus_register_event_handler(ctx, &handler, "example_event"); while (1) { ubus_handle_event(ctx); } return 0; } ``` 在这个例子,我们向 ubus 注册了一个名为 `example_event` 的事件,并在事件发生时打印出了事件的类型。 ## 总结 在本教程,我们介绍了 OpenWrt ubus 进程间通信系统,并且演示了如何使用 ubus 命令行工具和 ubus 库进行进程间通信。此外,我们还展示了如何使用 ubus 事件来接收通知。ubusOpenWrt 的一个重要组成部分,可以让应用程序之间进行简单的、安全的通信。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值