libubox組件(2)——blob/blobmsg (轉載 https://segmentfault.com/a/1190000002391970)

一:blob相關接口css

1.數據結構html

 1: struct blob_attr {
 2:     uint32_t id_len;    /** 高1位爲extend標誌,高7位存儲id,
 3:  * 低24位存儲data的內存大小+結構大小(blob_attr) */
 4:     char data[];
 5: } __packed;
 6:  實際使用中每一個blob_attr的長度包含:結構長度(4)+數據長度+對齊特性= id_len+pad_len
 7: struct blob_attr_info {
 8:     unsigned int type;
 9:     unsigned int minlen;
 10:     unsigned int maxlen;
 11:     bool (*validate)(const struct blob_attr_info *, struct blob_attr *);
 12: };
 13:  
 14: struct blob_buf {
 15:     struct blob_attr *head;
 16:     bool (*grow)(struct blob_buf *buf, int minlen);
 17:     int buflen;
 18:     void *buf;
 19: };

2. 存儲結構數組

3.獲取BLOB屬性信息cookie

 1: /**
 2:  * 返回指向BLOB屬性數據區指針
 3:  */
 4: static inline void * blob_data(const struct blob_attr *attr)
 5:  
 6: /**
 7:  * 返回BLOB屬性ID
 8:  */
 9: static inline unsigned int blob_id(const struct blob_attr *attr)
 10:  
 11: /**
 12:  * 判斷BLOB屬性擴展標誌是否爲真
 13:  */
 14: static inline bool blob_is_extended(const struct blob_attr *attr)
 15:  
 16: /**
 17:  * 返回BLOB屬性有效存儲空間大小
 18:  */
 19: static inline unsigned int blob_len(const struct blob_attr *attr)
 20:  
 21: /*
 22:  * 返回BLOB屬性徹底存儲空間大小(包括頭部)
 23:  */
 24: static inline unsigned int blob_raw_len(const struct blob_attr *attr)
 25:  
 26: /*
 27:  * 返回BLOB屬性填補後存儲空間大小(包括頭部)
 28:  */
 29: static inline unsigned int blob_pad_len(const struct blob_attr *attr)
 
4.獲取BLOB數據信息
 1: static inline uint8_t blob_get_u8(const struct blob_attr *attr)
 2:  
 3: static inline uint16_t blob_get_u16(const struct blob_attr *attr)
 4:  
 5: static inline uint32_t blob_get_u32(const struct blob_attr *attr)
 6:  
 7: static inline uint64_t blob_get_u64(const struct blob_attr *attr)
 8:  
 9: static inline int8_t blob_get_int8(const struct blob_attr *attr)
 10:  
 11: static inline int16_t blob_get_int16(const struct blob_attr *attr)
 12:  
 13: static inline int32_t blob_get_int32(const struct blob_attr *attr)
 14:  
 15: static inline int64_t blob_get_int64(const struct blob_attr *attr)
 16:  
 17: static inline const char * blob_get_string(const struct blob_attr *attr)
 
 
5.設置BLOB數據信息
 1: static inline struct blob_attr *
 2: blob_put_string(struct blob_buf *buf, int id, const char *str)
 3:  
 4: static inline struct blob_attr *
 5: blob_put_u8(struct blob_buf *buf, int id, uint8_t val)
 6:  
 7: static inline struct blob_attr *
 8: blob_put_u16(struct blob_buf *buf, int id, uint16_t val)
 9:  
 10: static inline struct blob_attr *
 11: blob_put_u32(struct blob_buf *buf, int id, uint32_t val)
 12:  
 13: static inline struct blob_attr *
 14: blob_put_u64(struct blob_buf *buf, int id, uint64_t val)
 15:  
 16: #define blob_put_int8   blob_put_u8
 17: #define blob_put_int16  blob_put_u16
 18: #define blob_put_int32  blob_put_u32
 19: #define blob_put_int64  blob_put_u64
 20:  
 21: struct blob_attr *
 22: blob_put(struct blob_buf *buf, int id, const void *ptr, unsigned int len)
 23:  
 24: /**
 25:  * ptr - 指向struct blob_attr
 26:  */
 27: struct blob_attr *
 28: blob_put_raw(struct blob_buf *buf, const void *ptr, unsigned int len)

6. 遍歷數據結構

#define __blob_for_each_attr(pos, attr, rem) #define blob_for_each_attr(pos, attr, rem)
 
7. 複製
struct blob_attr * blob_memdup(struct blob_attr *attr)

8. 數據類型判斷ui

 1: enum {
 2:     BLOB_ATTR_UNSPEC,
 3:     BLOB_ATTR_NESTED,  /** 嵌套 */
 4:     BLOB_ATTR_BINARY,
 5:     BLOB_ATTR_STRING,
 6:     BLOB_ATTR_INT8,
 7:     BLOB_ATTR_INT16,
 8:     BLOB_ATTR_INT32,
 9:     BLOB_ATTR_INT64,
 10:     BLOB_ATTR_LAST
 11: };
 12: bool blob_check_type(const void *ptr, unsigned int len, int type)

9.嵌套操做spa

 1: void * blob_nest_start(struct blob_buf *buf, int id)
 2: Void blob_nest_end(struct blob_buf *buf, void *cookie)

10.判斷指針

bool blob_attr_equal(const struct blob_attr *a1, const struct blob_attr *a2)

11.初始/銷燬,解析code

 1: /**
 2:  * 初始化BLOB buffer
 3:  */
 4: int blob_buf_init(struct blob_buf *buf, int id)
 5:  
 6: /**
 7:  * 銷燬BLOB buffer
 8:  */
 9: void blob_buf_free(struct blob_buf *buf)
 10:  
 11: /**
 12:  * 從attr串中根據info策略過濾,獲得的結果存儲在data屬性數組中
 13:  *
 14:  * @param attr 輸入BLOB屬性串
 15:  * @param data 輸出BLOB屬性數組
 16:  * @param info 屬性過濾策略
 17:  * @param max data數組大小
 18:  */
 19: int blob_parse(struct blob_attr *attr, struct blob_attr **data, 
 20:                const struct blob_attr_info *info, int max)
 
 
二:blobmsg相關接口
1.數據結構
 1: struct blobmsg_hdr {
 2:     uint16_t namelen;
 3:     uint8_t name[];
 4: } __packed;
 5:  
 6: struct blobmsg_policy {
 7:     const char *name;
 8:     enum blobmsg_type type;
 9: };
 
2.存儲結構
3.消息類型
 1: enum blobmsg_type {
 2:     BLOBMSG_TYPE_UNSPEC,
 3:     BLOBMSG_TYPE_ARRAY,
 4:     BLOBMSG_TYPE_TABLE,
 5:     BLOBMSG_TYPE_STRING,
 6:     BLOBMSG_TYPE_INT64,
 7:     BLOBMSG_TYPE_INT32,
 8:     BLOBMSG_TYPE_INT16,
 9:     BLOBMSG_TYPE_INT8,
 10:     __BLOBMSG_TYPE_LAST,
 11:     BLOBMSG_TYPE_LAST = __BLOBMSG_TYPE_LAST - 1,
 12:     BLOBMSG_TYPE_BOOL = BLOBMSG_TYPE_INT8,
 13: };

4.基本操做orm

 1: /**
 2:  * 根據BLOB消息名字長度計算出blobmsg頭部大小
 3:  */
 4: static inline int blobmsg_hdrlen(unsigned int namelen)
 5:  
 6: /**
 7:  * 獲取BLOB消息名字
 8:  */
 9: static inline const char *blobmsg_name(const struct blob_attr *attr)
 10:  
 11: /**
 12:  * 獲取BLOB消息類型
 13:  */
 14: static inline int blobmsg_type(const struct blob_attr *attr)
 15:  
 16: /**
 17:  * 獲取BLOB消息數據內容
 18:  */
 19: static inline void *blobmsg_data(const struct blob_attr *attr)
 20:  
 21: /**
 22:  * 獲取BLOB消息數據內容大小
 23:  */
 24: static inline int blobmsg_data_len(const struct blob_attr *attr)
 25: static inline int blobmsg_len(const struct blob_attr *attr)
 26: 數據類型判斷
 27:  
 28: /**
 29:  * 判斷BLOBMSG屬性類型是否合法
 30:  */
 31: bool blobmsg_check_attr(const struct blob_attr *attr, bool name)
 32: 設置
 33:  
 34: int blobmsg_add_field(struct blob_buf *buf, int type, const char *name,
 35:                       const void *data, unsigned int len)
 36:  
 37: static inline int
 38: blobmsg_add_u8(struct blob_buf *buf, const char *name, uint8_t val)
 39:  
 40: static inline int
 41: blobmsg_add_u16(struct blob_buf *buf, const char *name, uint16_t val)
 42:  
 43: static inline int
 44: blobmsg_add_u32(struct blob_buf *buf, const char *name, uint32_t val)
 45:  
 46: static inline int
 47: blobmsg_add_u64(struct blob_buf *buf, const char *name, uint64_t val)
 48:  
 49: static inline int
 50: blobmsg_add_string(struct blob_buf *buf, const char *name, const char *string)
 51:  
 52: static inline int
 53: blobmsg_add_blob(struct blob_buf *buf, struct blob_attr *attr)
 54:  
 55: /**
 56:  * 格式化設備BLOGMSG
 57:  */
 58: void blobmsg_printf(struct blob_buf *buf, const char *name, const char *format, ...)
 59: 獲取
 60:  
 61: static inline uint8_t blobmsg_get_u8(struct blob_attr *attr)
 62: static inline bool blobmsg_get_bool(struct blob_attr *attr)
 63: static inline uint16_t blobmsg_get_u16(struct blob_attr *attr)
 64: static inline uint32_t blobmsg_get_u32(struct blob_attr *attr)
 65: static inline uint64_t blobmsg_get_u64(struct blob_attr *attr)
 66: static inline char *blobmsg_get_string(struct blob_attr *attr)
 67: 建立
 68:  
 69: /**
 70:  * 建立BLOBMSG,返回數據區開始地址
 71:  */
 72: void *blobmsg_alloc_string_buffer(struct blob_buf *buf, const char *name, 
 73: unsigned int maxlen)
 74:  
 75: /**
 76:  * 擴大BLOGMSG,返回數據區開始地址
 77:  */
 78: void *blobmsg_realloc_string_buffer(struct blob_buf *buf, unsigned int maxlen)
 79:  
 80: void blobmsg_add_string_buffer(struct blob_buf *buf)
 81: 遍歷
 82:  
 83: #define blobmsg_for_each_attr(pos, attr, rem)
 84: 嵌套
 85:  
 86: static inline void * blobmsg_open_array(struct blob_buf *buf, const char *name)
 87: static inline void blobmsg_close_array(struct blob_buf *buf, void *cookie)
 88:  
 89: static inline void *blobmsg_open_table(struct blob_buf *buf, const char *name)
 90: static inline void blobmsg_close_table(struct blob_buf *buf, void *cookie)
 91: 解析BLOGMSG
 92:  
 93: /**
 94:  * 從data BLOGMSG串中根據policy策略過濾,獲得的結果存儲在tb BLOGATTR數組中
 95:  *
 96:  * @param policy 過濾策略
 97:  * @param policy_len 策略個數
 98:  * @param tb 返回屬性數據
 99:  * @param len data屬性個數
 100:  */
 101: int blobmsg_parse(const struct blobmsg_policy *policy, int policy_len,
 102:                   struct blob_attr **tb, void *data, unsigned int len)
 
 
三:實例操做
把UCI轉化爲BLOB

UCI配置文件:
/etc/config/test

config policy test option name 'test' option enable '1' option dns '1.1.1.1 2.2.2.2'
 
 
 1: 定義參數列表:
 2:  
 3: enum {
 4:     POLICY_ATTR_NAME,       /** name */
 5:     POLICY_ATTR_ENABLE,     /** enable */
 6:     POLICY_ATTR_DNS,        /** dns */
 7:     __POLICY_ATTR_MAX
 8: };
 9:  
 10: static const struct blobmsg_policy policy_attrs[__POLICY_ATTR_MAX] = {
 11:     [POLICY_ATTR_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING },
 12:     [POLICY_ATTR_ENABLE] = { .name = "enable", .type = BLOBMSG_TYPE_BOOL },
 13:     [POLICY_ATTR_DNS] = { .name = "dns", .type = BLOBMSG_TYPE_ARRAY },
 14: };
 15:  
 16: /** 定義BLOBMSG_TYPE_ARRAY類型參數的實際數據類型 */
 17: static const struct uci_blob_param_info policy_attr_info[__POLICY_ATTR_MAX] = {
 18:     [POLICY_ATTR_DNS] = { .type = BLOBMSG_TYPE_STRING },
 19: };
 20:  
 21: static const struct uci_blob_param_list policy_attr_list = {
 22:     .n_params = __POLICY_ATTR_MAX,
 23:     .params = policy_attrs,
 24:     .info = policy_attr_info,
 25: };
 26: 轉化爲BLOB:
 27:  
 28: static struct uci_context *g_uci_ctx;
 29: static struct blob_buf *b;
 30:  
 31: void
 32: transform(const char *config)
 33: {
 34:     struct uci_context *ctx = g_uci_ctx;
 35:     struct uci_package *p = NULL;
 36:  
 37:     if (!ctx) {
 38:         ctx = uci_alloc_context();
 39:         g_uci_ctx = ctx;
 40:         uci_set_confdir(ctx, NULL);
 41:     } else {
 42:         p = uci_lookup_package(ctx, config);
 43:         if (p)
 44:             uci_unload(ctx, p);
 45:     }
 46:  
 47:     if (uci_load(ctx, config, &p))
 48:         return;    
 49:  
 50:     struct uci_element *e;
 51:     struct blob_attr *config = NULL;
 52:     uci_foreach_element(&p->sectons, e) {
 53:         struct uci_section *s = uci_to_section(e);
 54:  
 55:         blob_buf_init(&b, 0);
 56:         uci_to_blob(&b, s, &policy_attr_list);
 57:         config = blob_memdup(b.head);
 58:  
 59:         /**
 60:  * do something with `config` 
 61:  * free(config), when not use it
 62:  */
 63:     }
 64: }
 65: 使用轉化後的blob_attr
 66:  
 67: void
 68: foo(blob_attr *confg)
 69: {
 70:     struct blob_attr *tb[__POLICY_ATTR_MAX];
 71:  
 72:     blobmsg_parse(policy_attrs, __POLICY_ATTR_MAX, tb,
 73:             blob_data(config), blob_len(config));
 74:  
 75:     /**
 76:  * do something with *tb[] 
 77:  */
 78: }
相關文章
相關標籤/搜索