blobmsg-ex

記錄libubox裡面blobmsg使用範例


更新記錄

item note
20160812 第一版

目錄


BLOB

  • 二進位大型物件(英语:binary large object ,或英语:basic large object,縮寫為Blob、BLOB、BLOb)

BlobMsg

blobmsg裡面的是是由許多組(name+data)
所以name是唯一的
若設定相同的iname,此時還是以第一次設定為主

1
2
blobmsg_add_string(buf, "message", "Hello, world!");
blobmsg_add_string(buf, "message", "Test Data");
[blob attr]

圖片出處:BLOB二进制对象

example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
static const struct blobmsg_policy pol[] = {
[FOO_MESSAGE] = {
.name = "message",
.type = BLOBMSG_TYPE_STRING,
},
[FOO_LIST] = {
.name = "list",
.type = BLOBMSG_TYPE_ARRAY,
},
[FOO_TESTDATA] = {
.name = "testdata",
.type = BLOBMSG_TYPE_TABLE,
},
};


static void dump_message(struct blob_buf *buf)
{

struct blob_attr *tb[ARRAY_SIZE(pol)];

if (blobmsg_parse(pol, ARRAY_SIZE(pol), tb, blob_data(buf->head), blob_len(buf->head)) != 0) {
fprintf(stderr, "Parse failed\n");
return;
}
if (tb[FOO_MESSAGE])
fprintf(stderr, "Message: %s\n", (char *) blobmsg_data(tb[FOO_MESSAGE]));

if (tb[FOO_LIST]) {
fprintf(stderr, "List: ");
dump_table(blobmsg_data(tb[FOO_LIST]), blobmsg_data_len(tb[FOO_LIST]), 0, true);
}
if (tb[FOO_TESTDATA]) {
fprintf(stderr, "Testdata: ");
dump_table(blobmsg_data(tb[FOO_TESTDATA]), blobmsg_data_len(tb[FOO_TESTDATA]), 0, false);
}
}
  • 建立blob資料
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
static void
fill_message(struct blob_buf *buf)
{

void *tbl;

blobmsg_add_string(buf, "message", "Hello, world!");

tbl = blobmsg_open_table(buf, "testdata");
blobmsg_add_u32(buf, "hello", 1);
blobmsg_add_string(buf, "world", "2");
blobmsg_close_table(buf, tbl);

tbl = blobmsg_open_array(buf, "list");
blobmsg_add_u32(buf, NULL, 0);
blobmsg_add_u32(buf, NULL, 1);
blobmsg_add_u32(buf, NULL, 2);
blobmsg_close_table(buf, tbl);
}

int main(int argc, char **argv)
{

static struct blob_buf buf;

blobmsg_buf_init(&buf);
fill_message(&buf);
dump_message(&buf);
..
}
  • 測試
1
2
3
4
5
6
7
8
9
10
11
12
13
gk350a :[~]# ./blobmsg-example 
Message: Hello, world!
List: {
0
1
2
}
Testdata: {
hello : 1
world : 2
}
json: {"message":"Hello, world!","testdata":{"hello":1,"world":"2"},"list":[0,1,2]}
gk350a :[~]#
  • struct blob
[BLOB]
  • blobmsg_buf_init(struct blob_buf *buf)
    • blob_buf_init(buf, BLOBMSG_TYPE_TABLE)
1
2
3
buf->grow = blob_buffer_grow
buf->head = buf->buf;
blob_add(buf, buf->buf, id, 0) // id = BLOBMSG_TYPE_TABLE
  • blob_buffer_grow(struct blob_buf *buf, int minlen)
  • 是realloc
1
2
3
4
new = realloc(buf->buf, buf->buflen + delta);
在buf->buf指標位置去要新的空間(大小由buf len決定) 對齊256byte
memset(buf->buf + buf->buflen, 0, delta);

buf->buflen += delta;
  • blob_add(struct blob_buf buf, struct blob_attr pos, int id, int payload)
1
2
blob_buf_grow(buf, required)  // buf->grow(buf, required)
blob_init(attr, id, payload + sizeof(struct blob_attr)); // 初始padload為0數值

blobmsg_add_string

blobmsg_add_string(struct blob_buf buf, const char name, const char *string)

  • blobmsg_add_field(buf, BLOBMSG_TYPE_STRING, name, string, strlen(string) + 1);
1
2
attr = blobmsg_new(buf, type, name, len, &data_dest);  // struct blob_attr *attr;
memcpy(data_dest, data, len);

blobmsg_open_table

blobmsg_open_table(struct blob_buf buf, const char name)

  • blobmsg_open_nested(buf, name, false);
1
2
3
struct blob_attr *head;
int type = array ? BLOBMSG_TYPE_ARRAY : BLOBMSG_TYPE_TABLE;
head = blobmsg_new(buf, type, name, 0, &data);

blobmsg_add_u32

blobmsg_add_u32(struct blob_buf buf, const char name, uint32_t val)

1
2
val = cpu_to_be32(val);
return blobmsg_add_field(buf, BLOBMSG_TYPE_INT32, name, &val, 4);

blobmsg_parse

int blobmsg_parse(const struct blobmsg_policy policy, int policy_len,
struct blob_attr **tb, void
data, unsigned int len)

參考來源