1.uci编译安装、移植
安装依赖 libubox
#安装cmake
sudo apt-get install cmake
#下载依赖库libubox
git clone http://git.nbd.name/luci2/libubox.git
git clone https://git.openwrt.org/project/libubox.git
#安装libubox,先安装到ubuntu同时制作一份安装库
cd libubox
mkdir build install
cd build
cmake .. -DBUILD_LUA=off -DBUILD_EXAMPLES=off
sudo make install
#ubuntu库安装完毕,开始制作目标库
#删除build目录所有文件,指定交叉编译工具和安装目录
sudo rm -rf *
cmake .. -DBUILD_LUA=off -DBUILD_EXAMPLES=off -DCMAKE_INSTALL_PREFIX=../install -DCMAKE_C_COMPILER=/home/wangh/workspace/openwrt/PandoraBox-SDK-qualcomm-ipq40xx_gcc-4.9-linaro_uClibc-1.0.x_eabi.Linux-x86_64/staging_dir/toolchain-arm_cortex-a7+neon-vfpv4_gcc-4.9-linaro_uClibc-1.0.x_eabi/bin/arm-openwrt-linux-gcc
#安装到交叉编译库中
sudo rm -rf *
cmake .. -DBUILD_LUA=off -DBUILD_EXAMPLES=off -DCMAKE_INSTALL_PREFIX=/home/wangh/workspace/openwrt/PandoraBox-SDK-qualcomm-ipq40xx_gcc-4.9-linaro_uClibc-1.0.x_eabi.Linux-x86_64/staging_dir/toolchain-arm_cortex-a7+neon-vfpv4_gcc-4.9-linaro_uClibc-1.0.x_eabi/usr -DCMAKE_C_COMPILER=/home/wangh/workspace/openwrt/PandoraBox-SDK-qualcomm-ipq40xx_gcc-4.9-linaro_uClibc-1.0.x_eabi.Linux-x86_64/staging_dir/toolchain-arm_cortex-a7+neon-vfpv4_gcc-4.9-linaro_uClibc-1.0.x_eabi/bin/arm-openwrt-linux-gcc
make install
安装uci
#下载uci源码
git clone https://git.openwrt.org/project/uci.git
#安装libubox,先安装到ubuntu同时制作一份安装库
cd uci
mkdir build install
cd build
cmake .. -DBUILD_LUA=off
sudo make install
#ubuntu库安装完毕,开始制作目标库
#删除build目录所有文件,指定交叉编译工具和安装目录
sudo rm -rf *
cmake .. -DBUILD_LUA=off -DCMAKE_INSTALL_PREFIX=../install -DCMAKE_C_COMPILER=/home/wangh/workspace/openwrt/PandoraBox-SDK-qualcomm-ipq40xx_gcc-4.9-linaro_uClibc-1.0.x_eabi.Linux-x86_64/staging_dir/toolchain-arm_cortex-a7+neon-vfpv4_gcc-4.9-linaro_uClibc-1.0.x_eabi/bin/arm-openwrt-linux-gcc
#交叉编译安装到交叉编译库目录
sudo rm -rf *
cmake .. -DBUILD_LUA=off -DCMAKE_INSTALL_PREFIX=/home/wangh/workspace/openwrt/PandoraBox-SDK-qualcomm-ipq40xx_gcc-4.9-linaro_uClibc-1.0.x_eabi.Linux-x86_64/staging_dir/toolchain-arm_cortex-a7+neon-vfpv4_gcc-4.9-linaro_uClibc-1.0.x_eabi/usr -DCMAKE_C_COMPILER=/home/wangh/workspace/openwrt/PandoraBox-SDK-qualcomm-ipq40xx_gcc-4.9-linaro_uClibc-1.0.x_eabi.Linux-x86_64/staging_dir/toolchain-arm_cortex-a7+neon-vfpv4_gcc-4.9-linaro_uClibc-1.0.x_eabi/bin/arm-openwrt-linux-gcc
2.C调用uci
配置示例文件 /etc/config/gateway
config interface 'netconf'
option serverurl '10.99.20.33/gateway'
option loaclip '192.168.11.3'
option netmask '255.255.255.0'
option gateway '192.168.11.1'
option proto 'static'
option dns '10.55.33.2'
option serverip '10.99.20.100'
option serverport '8000'
config device
option devstate '0'
option devid '001'
option devtype '网关'
option devmodel 'GW-001'
option devposition '武汉'
option enable 'yes'
config rs485
option name 'COM1'
option baudrate '9600'
option databit '8'
option stopbit '1'
option parity 'n'
option enable 'yes'
config device
option devstate '0'
option devid '002'
option devtype '单灯控制器'
option devmodel 'LIGHT-001'
option devposition '武汉'
option enable 'yes'
config device
option devstate '0'
option devid '003'
option devtype '单灯控制器'
option devmodel 'LIGHT-001'
option devposition '武汉'
option enable 'yes'
代码示例
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include "uci.h"
#include "config.h"
#define UCI_CONFIG_FILE "/etc/config/gateway"
/**
* @brief 获取配置信息
* @param section 配置段名称
* @param option 配置项
* @param pdata 获取的配置内容
* @param plen 获取的配置内容长度
* @return int 成功返回UCI_OK, 失败返回其它值
*/
int config_get(char *section, char *option, unsigned char *pdata, unsigned short *plen)
{
int ret = UCI_OK;
struct uci_package * pkg = NULL;
const char *value;
ctx = uci_alloc_context(); // 申请一个UCI上下文.
if (!ctx) {
return UCI_ERR_MEM;
}
ret = uci_load(ctx, UCI_CONFIG_FILE, &pkg); // 加载并解析配置文件
if(ret != UCI_OK)
{
uci_free_context(ctx);
return ret;
}
struct uci_section *s = uci_lookup_section(ctx, pkg, section);
if(s != NULL)
{
if (NULL != (value = uci_lookup_option_string(ctx, s, option)))
{
// pdata = (unsigned char *)strdup(value);
strncpy(pdata, value, 100);
*plen = strlen(pdata);
}
else
{
uci_unload(ctx, pkg);
uci_free_context(ctx);
ctx = NULL;
return UCI_ERR_NOTFOUND;
}
}
else
{
uci_unload(ctx, pkg);
uci_free_context(ctx);
ctx = NULL;
return UCI_ERR_NOTFOUND;
}
uci_unload(ctx, pkg);
uci_free_context(ctx);
ctx = NULL;
return ret;
}
/**
* @brief 设置配置信息
* @param section 配置段名称
* @param option 配置项
* @param pdata 获取的配置内容
* @param plen 获取的配置内容长度
* @return int 成功返回UCI_OK, 失败返回其它值
*/
int config_set(char *section, char *option, unsigned char *pdata, unsigned short *plen)
{
struct uci_package * pkg = NULL;
struct uci_element *e;
int ret = UCI_OK;
ctx = uci_alloc_context();
if (!ctx) {
return UCI_ERR_MEM;
}
struct uci_ptr ptr ={
.package = "gateway",
.section = section,
.option = option,
.value = pdata,
};
ret = uci_set(ctx, &ptr); //写入配置
if(ret != UCI_OK)
{
uci_free_context(ctx);
return ret;
}
ret = uci_save(ctx, ptr.p); //保存更改
if(ret != UCI_OK)
{
uci_free_context(ctx);
return ret;
}
ret = uci_commit(ctx, &ptr.p, false); //提交更改
if(ret != UCI_OK)
{
uci_free_context(ctx);
return ret;
}
// system("/etc/init.d/network restart"); //配置应用示例
uci_free_context(ctx);
return ret;
}
/**
* @brief 获取配置项值
* @param o 配置项
* @param out 获取的配置内容
* @return int 成功返回UCI_OK, 失败返回其它值
*/
static int uci_get_value(struct uci_option *o, char *out)
{
struct uci_element *e;
const char *delimiter = " "; //值为列表时的分隔符
bool sep = false;
switch(o->type) {
case UCI_TYPE_STRING:
strcpy(out, o->v.string);
break;
case UCI_TYPE_LIST:
uci_foreach_element(&o->v.list, e) {
if(sep)
strcat(out, delimiter);
strcat(out, e->name);
sep = true;
}
break;
default:
return UCI_ERR_INVAL;
break;
}
return UCI_OK;
}
/**
* @brief 获取uci配置项
* @param arg 获取该参数下的值
* eg: gateway.@interface[0]
* gateway.interface0.serverport
* @param out 获取的值存储区
* @return int 成功返回UCI_OK, 失败返回其它值
*/
int uci_get_str(const char *arg, char *out)
{
struct uci_context *ctx;
struct uci_element *e;
struct uci_ptr ptr;
int ret = UCI_OK;
char *name = NULL;
if(arg == NULL || out == NULL) return UCI_ERR_INVAL;
name = strdup(arg);
if(name == NULL) return UCI_ERR_INVAL;
ctx = uci_alloc_context();
if (!ctx) {
free(name);
return UCI_ERR_MEM;
}
if (uci_lookup_ptr(ctx, &ptr, name, true) != UCI_OK) {
uci_free_context(ctx);
free(name);
return UCI_ERR_NOTFOUND;
}
if(UCI_LOOKUP_COMPLETE & ptr.flags)
{
e = ptr.last;
switch(e->type)
{
case UCI_TYPE_SECTION:
ret = UCI_ERR_INVAL;
break;
case UCI_TYPE_OPTION:
ret = uci_get_value(ptr.o, out);
break;
default:
ret = UCI_ERR_NOTFOUND;
break;
}
}
else
ret = UCI_ERR_NOTFOUND;
uci_free_context(ctx);
free(name);
return ret;
}
/**
* @brief 设置uci配置项 , 保存并且提交更改到文件
* @param arg 设置参数
* eg: gateway.@interface[0]=wifi-iface
* gateway.interface0.serverip=10.99.20.100
* gateway.interface0.serverport=8000
* @return int 成功返回UCI_OK, 失败返回其它值
*/
int uci_set_str(const char *arg)
{
struct uci_context *ctx;
struct uci_element *e;
struct uci_ptr ptr;
int ret = UCI_OK;
char *name = NULL;
if(arg == NULL) return UCI_ERR_INVAL;
name = strdup(arg);
if(name == NULL) return UCI_ERR_MEM;
ctx = uci_alloc_context();
if (!ctx) {
free(name);
return UCI_ERR_MEM;
}
if (uci_lookup_ptr(ctx, &ptr, name, true) != UCI_OK) {
uci_free_context(ctx);
free(name);
return UCI_ERR_NOTFOUND;
}
ret = uci_set(ctx, &ptr);
if(ret != UCI_OK)
{
uci_free_context(ctx);
free(name);
return ret;
}
ret = uci_save(ctx, ptr.p);
if(ret != UCI_OK)
{
uci_free_context(ctx);
free(name);
return ret;
}
ret = uci_commit(ctx, &ptr.p, false);
if(ret != UCI_OK)
{
uci_free_context(ctx);
free(name);
return ret;
}
uci_free_context(ctx);
free(name);
return ret;
}
测试用例 config_test.c
int main(void)
{
printf("Hello World!
");
char tmp[100];
unsigned short tmplen;
int rc = config_get("netconf", "serverip", tmp, &tmplen);
printf("serverip is %s --%d --%d
", tmp, tmplen, rc);
rc = config_get("netconf", "serverport", tmp, &tmplen);
printf("serverport is %s --%d --%d
", tmp, tmplen, rc);
rc = config_set("netconf", "serverport", "8000", &tmplen);
printf("serverport set --%d
", rc);
rc = config_get("netconf", "serverport", tmp, &tmplen);
printf("serverport is %s --%d --%d
", tmp, tmplen, rc);
rc = uci_get_str("gateway.netconf.serverport", tmp);
printf("serverport is %s --%d
", tmp, rc);
rc = uci_set_str("gateway.netconf.serverport=9000");
printf("serverport set --%d
", rc);
rc = uci_get_str("gateway.netconf.serverport", tmp);
printf("serverport is %s --%d
", tmp, rc);
return 0;
}
用例 Makefile
TOOLCHAIN_DIR = "/home/wangh/workspace/openwrt/PandoraBox-SDK-qualcomm-ipq40xx_gcc-4.9-linaro_uClibc-1.0.x_eabi.Linux-x86_64/staging_dir/toolchain-arm_cortex-a7+neon-vfpv4_gcc-4.9-linaro_uClibc-1.0.x_eabi"
BIN := config_test
OBJS := config_test.o
OBJS += config.o
all:$(OBJS) $(BIN)
$(OBJS):%.o:%.c
$(CC) $(CFLAGS) -I $(TOOLCHAIN_DIR)/usr/include/ -c $^ -o $@
$(BIN):$(OBJS)
$(CC) -o $@ $^ $(LDFLAGS) -L $(TOOLCHAIN_DIR)/usr/lib -luci
clean:
rm -f *.o $(BIN)
3.lua调用uci
#!usr/bin/lua
require("uci")
-- uci测试
x = uci.cursor() --uci上下文
local serverip = x:get("gateway", "netconf", "serverip")
print(serverip)
x:foreach(
"gateway",
"device",
function(s)
if s.devid == "002" then
print("------------------")
for key, value in pairs(s) do
print(key .. ": " .. tostring(value))
end
end
end
)