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源码制作固件需要花费一点时间. 平台环境 ...
随机推荐
- Django debug page XSS漏洞(CVE-2017-12794)
影响版本:1.11.5之前的版本 访问http://your-ip:8000/create_user/?username=<script>alert(1)</script>创建 ...
- Dubbo 实现一个Route Factory(用于灰度发布)
Dubbo 可以实现的扩展很多, 官方文档在这: https://dubbo.apache.org/zh/docs/v2.7/dev/impls/ (太简单了....) 下面我们实现一个Route F ...
- Ghost ,博客系统代名词
Ghost 博客系统是前 WordPress 的一些优秀员工的创业项目.项目仍然采用 100% 开源,加上官方的收费托管的商业模式,目前已经发展成为一个非常的博客系统. 为了更好的方便读者理解 Gho ...
- AJAX的学习与使用>前端技术系列
目录 AJAX的学习与使用 什么是AJAX 为什么要使用AJAX AJAX接收服务器响应数据的3种格式 文本格式(重要) JSON格式(重要) 服务器端响应实体类JSON格式的3种方式 修改实体类的t ...
- Sqlserver 关于varchar(max) 笔记
看SQL server的版本,SQLserver2005以上 的nvarchar(max) 可以存放2G的内容,所以要是 SQL2005以上的nvarchar(max)足够你用的了.用nvarchar ...
- 本以为精通Android事件分发机制,没想到被面试官问懵了
文章中出现的源码均基于8.0 前言 事件分发机制不仅仅是核心知识点更是难点,并且还是View的一大难题滑动冲突解决方法的理论基础,因此掌握好View的事件分发机制是十分重要的. 一.基本认识 1. 事 ...
- k8s之Service详解-Service使用
实验环境准备 在使用service之前,首先利用deployment创建出3个pod,注意要为pod设置app=nginx-pod的标签 创建deployment.yaml,内容如下 apiVersi ...
- FreeRTOS-05-队列
说明 本文仅作为学习FreeRTOS的记录文档,作为初学者肯定很多理解不对甚至错误的地方,望网友指正. FreeRTOS是一个RTOS(实时操作系统)系统,支持抢占式.合作式和时间片调度.适用于微处理 ...
- 不懂Ribbon原理的可以进来看看哦,分析SpringBoot自动装配完成了Ribbon哪些核心操作
前面详细的给大家介绍了SpringBoot的核心内容,有了这部分的基础支持的话,我们再来分析SpringCloud中的相关组件就很容器了,本文我们来给大家开始介绍Ribbon的相关内容,首先来介绍 ...
- MySQL-07-information_schema/show
information_schema.tables视图 DESC information_schema.TABLES /** TABLE_SCHEMA ---->库名 TABLE_NAME -- ...