【轉】openwrt中ubus

參考連接:html

openwrt中ubus的具體使用
編程

openwrt ubus的wiki
json

[openwrt] 使用ubus實現進程通訊segmentfault

[openwrt] ubus實現進程間通訊舉例
服務器

openwrt ubus簡介以及libubus開發說明
session

ubus [1] - ubusd數據結構

ubus [2] - libubus多線程

ubus [3] - cliapp

libubox組件(1)——usockless

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服務的應用

path Description Package
dhcp dhcp server odhcpd
file file rpcd
hostapd acesspoints wpad/hostapd
iwinfo wireless informations rpcd iwinfo
log logging procd
mdns mdns avahi replacement mdnsd
network network netifd
service init/service procd
session Session management rpcd
system system misc procd
uci Unified Configuration Interface rpcd

 

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。若是不得不這樣作,須要在調用過程當中避免全局變量的重用問題。

相關文章
相關標籤/搜索