最近一个项目需要使用到 libubox 开发,然而在开发过程中却遇到了几个问题,便有了学习libubox的契机,打算记录下来与大家一起分享交流。
目录
一、源码下载
二、熟悉结构体
三、剖析 blobmsg_buf
1、blob_buf_init(&g_swgwd_devinfo_buff, 0);
2、msgtab = blobmsg_open_table(&g_swgwd_devinfo_buff, "swgwd.devinfo");
3、blobmsg_add_string(&g_swgwd_devinfo_buff, "ipaddr", “192.168.1.1”);
4、blobmsg_add_string(&g_swgwd_devinfo_buff, "mac", “aa:bb:cc:11:22:33”);
5、blobmsg_close_table(&g_swgwd_devinfo_buff, msgtab);
6、补充
git clone https://github.com/yubo/libubox.git
从 blob.h、blobmsg.h 入手。
1、struct blob_attr 中的 d_len 占 32bits,分为三个域
高1位,31bit:是否为 extended。(当 data 包含头部 blobmsg_hdr 时为 1)
高7位,24 ~ 30 bits:id,或者说数据的类型(如 table,string,int ...)
低24位,0~23 bits:data 变长数组的长度
struct blob_attr {
uint32_t d_len;
char data[];
} __packed;
2、struct blob_buf 的 buf 便是多个 struct blob_attr 属性的连接与嵌套。
grow 为扩容函数,用于分配空间给 buf。
buflen 为 grow 分为空间的大小。
head 用于辅助操作,动态指向 buf 中的某个 struct blob_attr 节点。
struct blob_buf {
struct blob_attr *head;
bool (*grow)(struct blob_buf *buf, int minlen);
int buflen;
void *buf;
};
3、用于拓展 struct blob_attr 的 data。
比如:struct blob_attr *attr1 = xxx;
(struct blobmsg_hdr *)attr1 -> namelen = strlen("mac");
strcpy((struct blobmsg_hdr *)attr1 ->name, "mac");
strcpy(blobmsg_data(attr1), "aa:bb:cc:11:22:33");
这个时候 attr1 -> data 分为两部分,一部分是 struct blobmsg_hdr,另一部分是真实的数据。
struct blobmsg_hdr {
uint16_t namelen;
uint8_t name[];
} __packed;
按照如下代码流程,逐段分析 blobmsg_buf 的内存变化:
struct blob_buf g_swgwd_devinfo_buff = {0};
blob_buf_init(&g_swgwd_devinfo_buff, 0);
msgtab = blobmsg_open_table(&g_swgwd_devinfo_buff, "swgwd.devinfo");
blobmsg_add_string(&g_swgwd_devinfo_buff, "ipaddr", “192.168.1.1”);
blobmsg_add_string(&g_swgwd_devinfo_buff, "mac", “aa:bb:cc:11:22:33”);
blobmsg_close_table(&g_swgwd_devinfo_buff, msgtab);