openwrt开发笔记三:uci移植及API调用
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调用的更多相关文章
- Django开发笔记三
Django开发笔记一 Django开发笔记二 Django开发笔记三 Django开发笔记四 Django开发笔记五 Django开发笔记六 1.基于类的方式重写登录:views.py: from ...
- ABP开发框架前后端开发系列---(10)Web API调用类的简化处理
在较早期的随笔<ABP开发框架前后端开发系列---(5)Web API调用类在Winform项目中的使用>已经介绍了Web API调用类的封装处理,虽然这些调用类我们可以使用代码生成工具快 ...
- ABP开发框架前后端开发系列---(5)Web API调用类在Winform项目中的使用
在前面几篇随笔介绍了我对ABP框架的改造,包括对ABP总体的介绍,以及对各个业务分层的简化,Web API 客户端封装层的设计,使得我们基于ABP框架的整体方案越来越清晰化, 也越来越接近实际的项目开 ...
- ArcGIS API for javascript开发笔记(四)——GP服务调用之GP模型的规范化制作详解
感谢一路走来默默陪伴和支持的你~~~ -------------------欢迎来访,拒绝转载------------------- 在之前的利用Python分析GP服务运行结果的输出路径 & ...
- ArcGIS API for javascript开发笔记(五)——GP服务调用之GP模型的发布及使用详解
感谢一路走来默默陪伴和支持的你~~~ ----------------欢迎来访,拒绝转载---------------- 关于GP模型的制作请点我! 一.GP发布 ArcGIS Desktop可以作为 ...
- ABP开发框架前后端开发系列---(4)Web API调用类的封装和使用
在前面随笔介绍ABP应用框架的项目组织情况,以及项目中领域层各个类代码组织,以及简化了ABP框架的各个层的内容,使得我们项目结构更加清晰.上篇随笔已经介绍了字典模块中应用服务层接口的实现情况,并且通过 ...
- 安卓开发笔记①:利用高德地图API进行定位、开发电子围栏、天气预报、轨迹记录、搜索周边(位置)
高德地图开发时需要导入的包在下面的网盘链接中:(由于高德地图api更新得太快,官网上最新的包使用起来没有之前的方便,所以以下提供最全面的原始包) 链接:http://pan.baidu.com/s/1 ...
- Vue-cli开发笔记三----------引入外部插件
(一)绝对路径直接引入: (1)主入口页面index.html中头部script标签引入: <script type="text/javascript" src=" ...
- openwrt开发笔记二:树莓派刷openwrt
前言及准备 本笔记适用于第一次给树莓派刷openwrt系统的玩家,对刷机过程及注意事项进行了记录,刷机之后对openwrt进行一些简单配置. 使用openwrt源码制作固件需要花费一点时间. 平台环境 ...
随机推荐
- Hadoop (8088)未授权访问
cd /vulhub/hadoop/unauthorized-yarn 加速下载环境 sudo vim /etc/docker/daemon.json 添加 {"registry-mirro ...
- 三层交换机和VLAN
目录 一.VLAN的概述及优势 二.VLAN的种类 三.静态VLAN的配置 四.Trunk介绍与配置 五.三层交换机转发原理 一.VLAN的概述及优势 分割广播域 物理分割 逻辑分割 VLAN的优势: ...
- HCNA Routing&Switching之STP基础
前文我们了解了VLAN动态注册协议GVRP相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15113770.html:今天我们来讨论下二层环路和STP相 ...
- C++ //构造函数的分类及调用 //分类 // 按照参数分类 无参构造函数(默认构造) 有参构造函数 //按照类型分类 普通构造 拷贝构造
1 //构造函数的分类及调用 2 //分类 3 // 按照参数分类 无参构造函数(默认构造) 有参构造函数 4 //按照类型分类 普通构造 拷贝构造 5 6 #include <iostream ...
- Android茫茫半年求职路,终于斩获三个大厂offer
前言 2019年底,公司出现危机,开始"优化",本组一个小兄弟被"优化",于是我也着手开始做准备,将来若轮到我被"优化",出去面试时也好打个 ...
- 通信协议,TCP/UDP对比:
通信协议 协议:约定,比如在中国约定说普通话 网络通信协议:速率,传输码率,代码结构,传输控制... 问题:非常复杂 大事化小:分层 TCP/IP协议簇:实际上是一组协议 重要: TCP:用户传输协议 ...
- tomcat服务监控分析及自启
#! /bin/bash # process-monitor.sh serverName="/usr/local/apache-tomcat-7.0.72-8080" #获取进程i ...
- 更换Swing界面中的窗口图标
Swing 窗口图标更换 因为需要,所以要更改窗口的图标,很简单 在代码中加上 Image icon = Toolkit.getDefaultToolkit().getImage("图片地址 ...
- 【Vulhub】Rsync未授权访问漏洞复现
Rsync未授权访问 Rsync简介 rsync,remote synchronize顾名思意就知道它是一款实现远程同步功能的软件,它在同步文件的同时,可以保持原来文件的权限.时间.软硬链接等附加信息 ...
- js随机显示图片
定义一个图片数组,生成一个随机数对应数据索引. window.onload = choosePic; function choosePic() { var myPix = new Array(&quo ...