ubus框架编译与验证
ubus框架编译与验证
一、运行环境库编译安装
为了和项目同步,ubox能ubus包从项目sdk中分离,平台采用x64 Ubuntu 22验证,后期如果有其它linux架构,直接在编译的做交叉编译即可。
- libubox
mkdir build cd build cmake .. make sudo make install 安装到系统目录 sudo make install DESTDIR=/home/user/Projects/libubox-75a3b870cace1171faf57bd55e5a9a2f1564f757-br1/libubox-75a3b870cace1171faf57bd55e5a9a2f1564f757/install 安装到指定目录,方便后期移植



- ubus
mkdir build cd build cmake .. make sudo make install sudo make install DESTDIR=/xxx


二、启动ubusd
mkdir -p /tmp/run sudo ubusd -s /tmp/run/ubus.sock & #启动ubus,路径可以自定义,默认为/var/run/ubus.sock ps -ef|grep ubusd #检查启动是否成功

三、ubus 常用命令
sudo ubusd -s /tmp/run/ubus.sock & #启动ubusd服务
sudo ubus -s /tmp/run/ubus.sock list #查看ubus服务提供列表
sudo ubus -s /tmp/run/ubus.sock listen tbox.info
sudo ubus -s /tmp/run/ubus.sock send tbox.info '{"text":"hello"}'


四、程序验证
#include <stdio.h>
#include <libubus.h>
#include <time.h>
#include <libubox/blobmsg.h>
#include <libubox/blobmsg_json.h>
#include <libubox/utils.h> // ARRAY_SIZE
static struct ubus_context *ctx;
static struct uloop_timeout test_timer;
static int minimal_handler(struct ubus_context *ctx, struct ubus_object *obj, truct ubus_request_data *req, const char *method, struct blob_attr *msg) {
fprintf(stderr, "[minimal] handler called\n");
fflush(stderr);
struct blob_buf b = {};
blob_buf_init(&b, 0);
blobmsg_add_string(&b, "status", "ok");
ubus_send_reply(ctx, req, b.head);
blob_buf_free(&b);
return 0;
}
static const struct ubus_method minimal_methods[] = {
UBUS_METHOD_NOARG("info", minimal_handler),
};
static struct ubus_object_type minimal_type =
UBUS_OBJECT_TYPE("tbox.info", minimal_methods);
static struct ubus_object tbox_object = {
.name = "tbox.info",
.type = &minimal_type,
/* 本版本 libubus 的方法派发读的是对象自身的 methods/n_methods,
* 而 ubus_add_object 不会从 type 同步过来,必须在此显式填写,
* 否则 obj->n_methods==0,call 会返回 METHOD_NOT_FOUND。
* 这个点卡了很久,切记
*/
.methods = minimal_methods,
.n_methods = ARRAY_SIZE(minimal_methods),
};
static void test_timer_cb(struct uloop_timeout *t)
{
fprintf(stderr, "[uloop] timer fired\n");
uloop_timeout_set(t, 2000);
}
int main(void)
{
printf("Hello, World!\n");
// if (uloop_init() < 0) {
//
// fprintf(stderr, "[main] uloop_init failed\n");
//
// return -1;
//
// }
int ret;
ctx = ubus_connect("/tmp/run/ubus.sock");
if (!ctx) {
fprintf(stderr, "ubus connect failed\n");
uloop_done();
return -1;
}
fprintf(stderr, "[main] ubus connected, ctx=%p\n", (void *)ctx);
fflush(stderr);
// 1. 先 add_object,向ubusd发送注册报文(同步)
ret = ubus_add_object(ctx, &tbox_object);
if (ret) {
fprintf(stderr, "add tbox object failed: %s\n", ubus_strerror(ret));
ubus_free(ctx);
uloop_done();
return -1;
}
fprintf(stderr, "[debug] object id = %u\n", tbox_object.id);
fprintf(stderr, "[debug] type = %p, type->methods = %p, type->n_methods = %u\n",
(void*)tbox_object.type,
(void*)(tbox_object.type ? tbox_object.type->methods : NULL),
tbox_object.type ? tbox_object.type->n_methods : 0);
if (tbox_object.type && tbox_object.type->methods) {
fprintf(stderr, "[debug] method[0].name = %s, handler = %p\n",
tbox_object.type->methods[0].name,
(void*)tbox_object.type->methods[0].handler);
}
fflush(stderr);
// 加这一行
fprintf(stderr, "add_object returned %d, object id = %u\n", ret, tbox_object.id);
fflush(stderr);
printf("tbox ubus service ready\n");
// 2. 注册uloop,交给事件循环处理后续消息
ubus_add_uloop(ctx);
fprintf(stderr, "[main] ubus_add_uloop ok\n");
fflush(stderr);
test_timer.cb = test_timer_cb;
uloop_timeout_set(&test_timer, 1000);
fprintf(stderr, "[main] enter uloop_run\n");
fflush(stderr);
uloop_run();
fprintf(stderr, "[main] uloop_run exited\n");
fflush(stderr);
ubus_free(ctx);
uloop_done();
return 0;
}
gcc main.c -o ZkUbus -lubus -lubox -blobmsg_json -json-c #编译 sudo ./ZkUbus sudo ubus -s /tmp/run/ubus.sock list sudo ubus -s /tmp/run/ubus.sock list tbox.info sudo ubus -s /tmp/run/ubus.sock list tbox.info -v sudo ubus -s /tmp/run/ubus.sock call tbox.info info




浙公网安备 33010602011771号