libubox 库学习之---剖析 blobmsg_buf

最近一个项目需要使用到 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

按照如下代码流程,逐段分析 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);

1、blob_buf_init(&g_swgwd_devinfo_buff, 0);

  • (&g_swgwd_devinfo_buff)->brow = blob_buffer_grow,默认扩容函数
  • 使用默认的扩容函数 calloc 了 256 字节空间,赋值给 (&g_swgwd_devinfo_buff)->buf
  • (&g_swgwd_devinfo_buff)->buflen = 256
  • new 一个 struct blob_attr blob_attr1,只使用了 .d_len
  • (&g_swgwd_devinfo_buff)->head = (&g_swgwd_devinfo_buff)->buf

2、msgtab = blobmsg_open_table(&g_swgwd_devinfo_buff, "swgwd.devinfo");

  • 找到 (&g_swgwd_devinfo_buff)->head->data 作为插入位置 pos
  • new 一个 struct blob_attr blob_attr2,填充 .d_len 和 .data
  • 更新 (&g_swgwd_devinfo_buff)->head 指向 blob_attr2
  • 返回值 msgtab 用于后面的 blobmsg_open_close(msgtab) 时找到 blob_attr1 位置,然后更新其 .d_len。(msgtab 就是 buf->head - buf->buf 的 offsets,再加上 blob_cookie)

3、blobmsg_add_string(&g_swgwd_devinfo_buff, "ipaddr", “192.168.1.1”);

  • 找到 (&g_swgwd_devinfo_buff)->head->data 作为插入位置 pos
  • new 一个 struct blob_attr blob_attr3,填充 .d_len 和 .data
  • 更新 (&g_swgwd_devinfo_buff)->head->d_len,也就是 blob_attr2->d_len

4、blobmsg_add_string(&g_swgwd_devinfo_buff, "mac", “aa:bb:cc:11:22:33”);

  • 找到 (&g_swgwd_devinfo_buff)->head->data 作为插入位置 pos
  • new 一个 struct blob_attr blob_attr4,填充 .d_len 和 .data
  • 更新 (&g_swgwd_devinfo_buff)->head->d_len,也就是 blob_attr2->d_len

5、blobmsg_close_table(&g_swgwd_devinfo_buff, msgtab);

  • 根据 msgtab 找到 "swgwd.devinfo" 的前一个 attr,即 blob_attr1。更新其 .d_len
  • (&g_swgwd_devinfo_buff) -> head 指向 blob_attr1

6、补充

最后补充一点。到这时,
blob_attr1 -> data 数据部分为(绿色+紫色)部分。即一个 table
blob_attr2 -> data 数据部分为(紫色)部分。即两个 string
msg = blob_memdup( blobmsg_data(blob_attr1) 取到的数据是整个 table 的数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值