OpenWrt源码分析之libubox
来源:互联网 发布:芈月怎么玩 知乎 编辑:程序博客网 时间:2024/06/05 03:24
json
OpenWrt支持c、shell、lua三种语言的进程通过ubus进行进程间通讯,ubus通讯的消息格式遵循json格式。
json(JavaScript object Notation)是一种轻量级的数据交换格式,易于人读写,也易于机器解析和生成。json是一种独立于编程语言之外的文本格式,兼容多种编程语言,如c、c++、Java、JavaScript、perl、Python等。
json由两种格式组成:
string
格式是key:value,value为字符串;
object是一个name/vale对,格式是{name:value},相当于c语言中的结构体、哈希表等。number
格式是key:value,value为整数;boolean
格式是key:value,value为1或者0;object
object相当于c语言中中的结构体,格式是key:{key1:value1,key2:value2,…},value可以是string、number、boolean、object或者array;array
array相当于c语言中的数组,格式是key:[value1,value2,…],value可以是string、number、boolean、object或者array。
OpenWrt shell程序中用到了命令jshn和脚本jshn.sh;
下面是一个shell程序中使用json的例子:
. /usr/share/libubox/jshn.sh# generating json datajson_initjson_add_string "str" "Hello, world!"json_add_object "obj"json_add_int "num" "100"json_add_boolean "bool" "0"json_close_objectjson_add_array "array"json_add_string "arraystr" "array string"json_add_int "" "110"json_add_boolean "" "1"json_close_arrayMSG=`json_dump`echo ${MSG}# parsing json datajson_load "$MSG"json_get_var varstr strjson_select objjson_get_var varnum numjson_get_var varbool booljson_select ..json_select arrayjson_get_var array1 "1"json_get_var array2 "2"json_get_var array3 "3"cat << EOF{ msg : $varstr, obj: { num : $varnum, bool : $varbool }, array: [ $array1, $array2, $array3 ]}
执行结果为:
root@OpenWrt:/# ./jsontest.sh{ "str": "Hello, world!", "obj": { "num": 100, "bool": false }, "array": [ "array string", 110, true ] }{ msg : Hello, world!, obj: { num : 100, bool : 0 }, array: [ array string, 110, 1 ]}
shell json相关的api函数有:
json_cleanup 初始化json环境
清空json环境 json_add_string 添加string类型的element json_add_int 添加int类型的element json_add_boolean 添加boolean类型的element json_add_table
json_close_table 添加table类型的element json_add_array
json_close_array 添加array类型的element json_load 从字符串中导入到json格式 json_select 进入到某个element,必须有是table或array才能使用json_select json_get_keys 获取所有element的key json_get_values 获取所有element的value json_get_var 根据key获取value json_get_type 获取element的类型
blob & blobmsg
ubus之间传递的消息在程序中使用blob或者blobmsg的形式组织,blob是一种二进制字节序列,在libubox中,blob使用结构体struct blob_attr表示,如下所示:
struct blob_attr { uint32_t id_len; char data[];};
在内存中,一个blob数据的格式如下所示:
blob是符合TLV格式的,TLV表示Type-Length-Value,上图中,ID即使Type,Len即是Length,Payload即是Value。
blobmsg是在blob的基础上扩展出来的,blobmsg的格式如下图所示:
blobmsg中扩展标准位extended等于1,payload拆分出key和value两个字段,ID表示blogmsg的类型,类型包括BLOBMSG_TYPE_STRING、BLOBMSG_TYPE_INT、BLOBMSG_TYPE_BOOL、BLOBMSG_TYPE_TABLE、BLOBMSG_TYPE_ARRAY。
string、int、bool类型blobmsg
类似于json,string类型的blobmsg的格式如下:
string类型的blobmsg的value为string,int和bool类型的blobmsg的value为对应类型的值。table、array类型blobmsg
类似于json,table类型的blobmsg相当于object类型的json,相当于c语言中的结构体,array相当于c语言中的数组;
table类型的blobmsg格式如下图所示:
array类型的blobmsg格式如下图所示:
array和table十分相似,区别在于array的元素是不需要key名字的。
一般使用结构体blob_buf来表示blobmsg链表,blob_buf的head和buf(之所以要用两个指针是因为在加到blobmsg长度时,重新申请连续内存指针会发生改变)都指向一个table类型的blobmsg,buflen等于总长度;
格式如下所示:
blob或者blobmsg常用的api如下所示:
string
blobmsg_add_string
blobmsg_get_stringint
blobmsg_add_u8
blobmsg_add_u16
blobmsg_add_u32
blobmsg_add_u64
blobmsg_get_u8
blobmsg_get_u16
blobmsg_get_u32
blobmsg_get_u64bool
bool转换成u8的0或者1table
blobmsg_open_table
blobmsg_close_table
/* * Example: * * table_key : { * string_key : "this is a string", * int_key : 100, * bool_key : true */}static struct blob_buf buf;blobmsg_buf_init(&buf);void *tbl = blobmsg_open_table(buf, "table_key");blobmsg_add_string(buf, "string_key", "this is a string");blobmsg_add_u8(buf, "int_key", 100);blobmsg_add_u8(buf, "bool_key", 1);blobmsg_close_table(buf, tbl);
- array
blobmsg_open_array
blobmsg_close_array
/* * Example: * * array_key : [ "this is a string", 100, true ] */static struct blob_buf buf;blobmsg_buf_init(&buf);void *array = blobmsg_open_array(buf, "array_key");blobmsg_add_string(buf, NULL, "this is a string");blobmsg_add_u8(buf, NULL, 100);blobmsg_add_u8(buf, NULL, 1);blobmsg_close_array(buf, array);
- parse
blobmsg_parse
//上面两个例子中添加table和array到buf中去,下面将其取出来enum { FOO_TABLE, FOO_ARRAY};static const struct blobmsg_policy pol[] = { [FOO_TABLE] = { .name = "table_key", .type = BLOBMSG_TYPE_TABLE, }, [FOO_ARRAY] = { .name = "array_key", .type = BLOBMSG_TYPE_ARRAY, },};struct blob_attr *tb[ARRAY_SIZE(pol)];blobmsg_parse(pol, ARRAY_SIZE(pol), tb, blob_data(buf->head); //parse/* after parse * tb[FOO_TABLE] is table blobmsg * tb[FOO_ARRAY] is array blobmsg * blobmsg_data(tb[FOO_TABLE] get table element head * __blob_for_each_attr(attr, head, len) get every element * /
- OpenWrt源码分析之libubox
- OpenWrt源码分析之ubus
- OpenWrt源码分析之netifd
- OpenWrt源码分析之编译系统
- openwrt libubox 移植到ARM上
- libubox
- Openwrt 之 Makefile框架分析
- [OpenWrt] openwrt结构分析
- Openwrt启动之preinit流程分析
- openwrt 之dhcp客户端调用分析
- Openwrt.wifi.脚本分析之/sbin/wifi
- [OpenWrt] openwrt启动脚本分析
- [OpenWrt] OpenWrt启动过程分析
- Openwrt研习笔记三之源码的下载和编译
- Openwrt研习笔记三之源码的下载和编译
- openwrt之WIFI驱动结构的一点简单分析
- duilib之源码分析
- duilib之源码分析
- 算法总结三
- 源码安装setuptools和pip
- “调皮“的栈帧和与define的众多比较
- python学习笔记--堆(heap)
- Hibernate学习
- OpenWrt源码分析之libubox
- HDOJ2028
- 线程调度、优先级和关联性(7)
- Java中的运算符
- [高等数学]函数与极限(1)—映射和函数
- 链表 队列 栈的比较
- 使用Java Swing绘制随鼠标拖拽可见轨迹的矩形(不会一直绘制矩形,而是类似ps中的矩形工具)
- bzoj5055 膜法师
- Java如何实现对存储过程的调用