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!\n");
char tmp[100];
unsigned short tmplen;
int rc = config_get("netconf", "serverip", tmp, &tmplen);
printf("serverip is %s --%d --%d\n", tmp, tmplen, rc); rc = config_get("netconf", "serverport", tmp, &tmplen);
printf("serverport is %s --%d --%d\n", tmp, tmplen, rc); rc = config_set("netconf", "serverport", "8000", &tmplen);
printf("serverport set --%d\n", rc); rc = config_get("netconf", "serverport", tmp, &tmplen);
printf("serverport is %s --%d --%d\n", tmp, tmplen, rc); rc = uci_get_str("gateway.netconf.serverport", tmp);
printf("serverport is %s --%d\n", tmp, rc); rc = uci_set_str("gateway.netconf.serverport=9000");
printf("serverport set --%d\n", rc); rc = uci_get_str("gateway.netconf.serverport", tmp);
printf("serverport is %s --%d\n", 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
)

openwrt开发笔记三:uci移植及API调用的更多相关文章

  1. Django开发笔记三

    Django开发笔记一 Django开发笔记二 Django开发笔记三 Django开发笔记四 Django开发笔记五 Django开发笔记六 1.基于类的方式重写登录:views.py: from ...

  2. ABP开发框架前后端开发系列---(10)Web API调用类的简化处理

    在较早期的随笔<ABP开发框架前后端开发系列---(5)Web API调用类在Winform项目中的使用>已经介绍了Web API调用类的封装处理,虽然这些调用类我们可以使用代码生成工具快 ...

  3. ABP开发框架前后端开发系列---(5)Web API调用类在Winform项目中的使用

    在前面几篇随笔介绍了我对ABP框架的改造,包括对ABP总体的介绍,以及对各个业务分层的简化,Web API 客户端封装层的设计,使得我们基于ABP框架的整体方案越来越清晰化, 也越来越接近实际的项目开 ...

  4. ArcGIS API for javascript开发笔记(四)——GP服务调用之GP模型的规范化制作详解

    感谢一路走来默默陪伴和支持的你~~~ -------------------欢迎来访,拒绝转载------------------- 在之前的利用Python分析GP服务运行结果的输出路径 & ...

  5. ArcGIS API for javascript开发笔记(五)——GP服务调用之GP模型的发布及使用详解

    感谢一路走来默默陪伴和支持的你~~~ ----------------欢迎来访,拒绝转载---------------- 关于GP模型的制作请点我! 一.GP发布 ArcGIS Desktop可以作为 ...

  6. ABP开发框架前后端开发系列---(4)Web API调用类的封装和使用

    在前面随笔介绍ABP应用框架的项目组织情况,以及项目中领域层各个类代码组织,以及简化了ABP框架的各个层的内容,使得我们项目结构更加清晰.上篇随笔已经介绍了字典模块中应用服务层接口的实现情况,并且通过 ...

  7. 安卓开发笔记①:利用高德地图API进行定位、开发电子围栏、天气预报、轨迹记录、搜索周边(位置)

    高德地图开发时需要导入的包在下面的网盘链接中:(由于高德地图api更新得太快,官网上最新的包使用起来没有之前的方便,所以以下提供最全面的原始包) 链接:http://pan.baidu.com/s/1 ...

  8. Vue-cli开发笔记三----------引入外部插件

    (一)绝对路径直接引入: (1)主入口页面index.html中头部script标签引入: <script type="text/javascript" src=" ...

  9. openwrt开发笔记二:树莓派刷openwrt

    前言及准备 本笔记适用于第一次给树莓派刷openwrt系统的玩家,对刷机过程及注意事项进行了记录,刷机之后对openwrt进行一些简单配置. 使用openwrt源码制作固件需要花费一点时间. 平台环境 ...

随机推荐

  1. Linux从头学05-系统启动过程中的几个神秘地址,你知道是什么意思吗?

    作 者:道哥,10+年的嵌入式开发老兵. 公众号:[IOT物联网小镇],专注于:C/C++.Linux操作系统.应用程序设计.物联网.单片机和嵌入式开发等领域. 公众号回复[书籍],获取 Linux. ...

  2. 升级到Spring 5.3.x之后,GC次数急剧增加,我TM人傻了

    最近我们项目升级到了 Spring Boot 2.4.6 + Spring Cloud 2020.0.x,通过我的另一系列即可看出:Spring Cloud 升级之路.但是升级后,我们发现 Young ...

  3. 记录21.07.24 —— Vue的组件与路由

    VUE组件 作用:复用性 创建组件的三种方式 第一种:使用extends搭配component方法 第二种:直接使用component方法 只有用vue声明且命名的才称之为创建组件 注意:templa ...

  4. [考试总结]noip模拟33

    连炸两场... 伤心... 第一个题目首先因为有期望坐镇,然后跳过... 然后第二个题目发现题目挺绕的,然后转化了一句话题意,然后..... \(\huge{\text{转化错了!!!!}}\) 然而 ...

  5. DNS服务器(一)正向解析

    一.DNS简介 在日常生活中人们习惯便用域名访问服务器,但机器间互相只认IP地址,域名与1P地址之间是多对一的关系,一个ip地址不一定只对应一个域名,且一个域名只可以对应一个ip地址,它们之间的转换工 ...

  6. Javac 编译器

    编译过程 Javac 编译过程大致可以分为1个准备过程和3个处理过程: 准备过程:初始化插入式注解处理器. 解析与填充符号表过程,包括: 词法.语法分析,将源代码的字符流转变为标记集合,构造出抽象语法 ...

  7. C作用域

    任何一种编程中,作用域是程序中定义的变量所存在的区域,超过该区域变量就不能被访问.C 语言中有三个地方可以声明变量: 在函数或块内部的局部变量 在所有函数外部的全局变量 在形式参数的函数参数定义中 局 ...

  8. UVa120 煎饼(选择排序思想)

    题目背景 给你一迭薄煎饼,请你写一个程式来指出要如何安排才能使这些薄煎饼由上到下依薄煎饼的半径由小到大排好.所有的薄煎饼半径均不相同. 要把薄煎饼排好序需要对这些薄煎饼做翻面(flip)的动作.方法是 ...

  9. 第6篇-Java方法新栈帧的创建

    在 第2篇-JVM虚拟机这样来调用Java主类的main()方法 介绍JavaCalls::call_helper()函数的实现时提到过如下一句代码: address entry_point = me ...

  10. xv6学习笔记(3):中断处理和系统调用

    xv6学习笔记(3):中断处理和系统调用 1. tvinit函数 这个函数位于main函数内 表明了就是设置idt表 void tvinit(void) { int i; for(i = 0; i & ...