openwrt ubus简介以及libubus开发说明
简介
ubus是新openwrt引入的一个消息总线,主要作用是实现不同应用程序之间的信息交互。
ubus启动后会在后台运行ubusd进程,该进程监听一个unix套接字用于与其他应用程序通信。其他应用程序可基于libubox提供的接口(或自己实现)与其通信。
使用ubus的方式主要有:1、向其注册消息或控制接口。2、向其调用其他应用程序的消息或控制接口。3、向其注册监听关心的事件。4、向其发送事件消息。
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参数用以显示各个接口的详细信息。示例如下:
ubuslist-v'dhcp'@26b45f5d"ipv4leases":{}"ipv6leases":{}'hostapd.wlan0'@5e03d420"get_clients":{}"del_client":{"addr":"String","reason":"Integer","deauth":"Boolean","ban_time":"Integer"}
ubus call 该命令用于调用ubus中当前注册的接口。示例如下:
ubuscalldhcpipv6leases{"device":{"br-lan":{"leases":[{"duid":"0001000119660ee***4e543***3c70","iaid":3***72***5,"hostname":"*******-PC","assigned":3900,"length":128,"ipv6":["fd23:a6ed:f19b::f3c"],"valid":-38000}]}}}
ubus listen用于监听ubus相关事件,如果不指定事件名则监听所有事件。(支持通配符*)
ubus send 用于发送事件
ubuswait_for 用于等待指定项的注册到ubus中。
libubus开发说明
libubus与需要与libubox配合使用,先贴出调用libubus的实例代码。
ubus.h
#ifndefUBUS_H_#defineUBUS_H_#include<libubox/blob.h>intubus_send(constchar*type,structblob_attr*data);intubus_call(constchar*path,constchar*method,structblob_attr*data,structblob_attr**ret);intubus_init(void);voidubus_destory();#endif
ubus.c
#include<stdio.h>#include<errno.h>#include<unistd.h>#include<string.h>#include<sys/types.h>#include<sys/wait.h>#include<sys/stat.h>#include<fcntl.h>#include<libubus.h>#include<libubox/uloop.h>#include<libubox/blobmsg_json.h>#include<arpa/inet.h>#include"ubus.h"#include"test.h"#include"debug.h"#include"pubinfo.h"structubus_context*ubus_ctx=NULL;#defineARRAY_SIZE(arr)(sizeof(arr)/sizeof((arr)[0]))enum{GET_TYPE_FLOW,GET_TYPE_SPEED};#define_unused__attribute__((unused))#define_packed__attribute__((packed))staticstructblob_bufb;/***********************************************************************pubpolicy*********************************************************************/enum{UBUS_test_PUB_TOPIC,UBUS_test_PUB_MSG,__UBUS_test_PUB_MAX};staticconststructblobmsg_policytest_pub_policy[]={[UBUS_test_PUB_TOPIC]={.name="topic",.type=BLOBMSG_TYPE_STRING},[UBUS_test_PUB_MSG]={.name="msg",.type=BLOBMSG_TYPE_TABLE},};/***********************************************************************Statspolicy*********************************************************************/enum{UBUS_STATS_OBJS,__UBUS_STATS_MAX};staticconststructblobmsg_policystats_pub_policy[]={[UBUS_STATS_OBJS]={.name="obj",.type=BLOBMSG_TYPE_ARRAY},};/***********************************************************************subpolicy*********************************************************************/enum{UBUS_test_SUB_TOPICS,__UBUS_test_SUB_MAX};staticconststructblobmsg_policytest_sub_policy[]={[UBUS_test_SUB_TOPICS]={.name="topics",.type=BLOBMSG_TYPE_ARRAY},};/***********************************************************************subscribemethod:subscribealistoftopics*********************************************************************/staticintubus_test_sub(structubus_context*ctx,structubus_object*obj,structubus_request_data*req,constchar*method,structblob_attr*msg){unsignedret=0;structblob_attr*tb[__UBUS_test_SUB_MAX];blobmsg_parse(test_sub_policy,__UBUS_test_SUB_MAX,tb,blob_data(msg),blob_len(msg));if(!tb[UBUS_test_SUB_TOPICS]){debug(MSG_ERROR,"ubustestsub:noarguments!");gotoout;}update_test_topic_list(tb[UBUS_test_SUB_TOPICS]);ret=1;out:blob_buf_init(&b,0);blobmsg_add_u8(&b,"result",ret);ubus_send_reply(ctx,req,b.head);return0;}/***********************************************************************publishmethod:publishmessages*********************************************************************/staticintubus_test_pub(structubus_context*ctx,structubus_object*obj,structubus_request_data*req,constchar*method,structblob_attr*msg){intret=0;structblob_attr*tb[__UBUS_test_PUB_MAX];char*message="",*topic;blobmsg_parse(test_pub_policy,__UBUS_test_PUB_MAX,tb,blob_data(msg),blob_len(msg));if(!tb[UBUS_test_PUB_TOPIC]){gotoout;}topic=blobmsg_get_string(tb[UBUS_test_PUB_TOPIC]);if(tb[UBUS_test_PUB_MSG]!=NULL){message=(char*)blobmsg_data(tb[UBUS_test_PUB_MSG]);}test_pub_msg(topic,message);debug(MSG_INFO,"PUB:topic=%smsg=%s\n",topic,message);ret=1;out:blob_buf_init(&b,0);blobmsg_add_u8(&b,"result",ret);ubus_send_reply(ctx,req,b.head);return0;}/***********************************************************************publishmethod:simplepublishmessages*********************************************************************/staticintubus_test_spub(structubus_context*ctx,structubus_object*obj,structubus_request_data*req,constchar*method,structblob_attr*msg){intret=0;structblob_attr*tb[__UBUS_test_PUB_MAX];char*message="",*cmd;blobmsg_parse(test_pub_policy,__UBUS_test_PUB_MAX,tb,blob_data(msg),blob_len(msg));if(!tb[UBUS_test_PUB_TOPIC]){debug(MSG_ERROR,"ubuscallspubwithouttopic");gotoout;}cmd=blobmsg_get_string(tb[UBUS_test_PUB_TOPIC]);if(tb[UBUS_test_PUB_MSG]!=NULL){message=blobmsg_format_json(tb[UBUS_test_PUB_MSG],true);}simple_pub_msg(cmd,message,1);ret=1;out:blob_buf_init(&b,0);blobmsg_add_u8(&b,"result",ret);ubus_send_reply(ctx,req,b.head);return0;}/***********************************************************************listmethod:listcurrentsubscribetopic*********************************************************************/staticintubus_test_list(structubus_context*ctx,structubus_object*obj,structubus_request_data*req,constchar*method,structblob_attr*msg){get_topic_list(&b);ubus_send_reply(ctx,req,b.head);return0;}/***********************************************************************ubusmethod:ubus_pub_stats*********************************************************************/staticintubus_pub_stats(structubus_context*ctx,structubus_object*obj,structubus_request_data*req,constchar*method,structblob_attr*msg){intret=0;structblob_attr*tb[__UBUS_STATS_MAX];blobmsg_parse(stats_pub_policy,__UBUS_STATS_MAX,tb,blob_data(msg),blob_len(msg));if(tb[UBUS_STATS_OBJS]){pub_info(tb[UBUS_STATS_OBJS]);ret=1;}blob_buf_init(&b,0);blobmsg_add_u8(&b,"result",ret);ubus_send_reply(ctx,req,b.head);return0;}/***********************************************************************listmethod:listcurrentsubscribetopic*********************************************************************/staticintubus_test_test(structubus_context*ctx,structubus_object*obj,structubus_request_data*req,constchar*method,structblob_attr*msg){intstatus;get_topic_list(&b);debug(MSG_DEBUG,"==>beginwaitstatus");wait(&status);debug(MSG_DEBUG,"==>afterwaitstatus:%d",status);ubus_send_reply(ctx,req,b.head);return0;}/***********************************************************************testmethod*********************************************************************/staticconststructubus_methodtest_methods[]={UBUS_METHOD("pub",ubus_test_pub,test_pub_policy),UBUS_METHOD("spub",ubus_test_spub,test_pub_policy),UBUS_METHOD("sub",ubus_test_sub,test_sub_policy),UBUS_METHOD("pubstats",ubus_pub_stats,stats_pub_policy),UBUS_METHOD_NOARG("lsub",ubus_test_list),UBUS_METHOD_NOARG("test",ubus_test_test),};/***********************************************************************testobject*********************************************************************/staticstructubus_object_typetest_object_type=UBUS_OBJECT_TYPE("test",test_methods);staticstructubus_objecttest_object={.name="test",.type=&test_object_type,.methods=test_methods,.n_methods=ARRAY_SIZE(test_methods),};staticvoidubus_connect_handler(structubus_context*ctx){ubus_ctx=ctx;debug(MSG_DEBUG,"ubusnowconnected.");ubus_add_uloop(ctx);ubus_add_object(ctx,&test_object);return;}staticstructubus_auto_connconn;staticvoidreceive_ubus_data(structubus_request*req,inttype,structblob_attr*msg){structblob_attr**ret=(structblob_attr**)req->priv;*ret=blob_memdup(msg);}intubus_send(constchar*type,structblob_attr*data){if(!ubus_ctx||!type||!data){return-1;}returnubus_send_event(ubus_ctx,type,data);}intubus_call(constchar*path,constchar*method,structblob_attr*data,structblob_attr**ret){uint32_tid;int_ret;if(ubus_ctx==NULL){return-1;}_ret=ubus_lookup_id(ubus_ctx,path,&id);if(_ret){debug(MSG_ERROR,"lookupstatsiderror!");return-1;}returnubus_invoke(ubus_ctx,id,method,data,receive_ubus_data,ret,1000);}intubus_init(void){conn.cb=ubus_connect_handler;ubus_auto_connect(&conn);return0;}voidubus_destory(){/*ubus_remove_object(ubus,&main_object);ubus_free(ubus);*/}
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。