0
点赞
收藏
分享

微信扫一扫

TR069协议与商业应用2-EasyCwmp开源代码学习

辰鑫chenxin 2022-03-19 阅读 110

声明:原创作品,严禁用于商业目的。 如有任何问题,欢迎和我交流(微信号:15240377504)。

文章目录

1. 源码结构

1.1 EasyCwmp设计架构

EasyCwmp设计包括2个部分:
EasyCwmp Core:它包括 TR069 CWMP 引擎,并负责与ACS服务器的通信。使用C语言开发。
EasyCwmp DataModel:它包含 TR-06 的 DATAModel,并且符合某些 DataModel 标准,例如 TR-098,TR-181,TR-104 等。使用 shell 脚本开发,只支持部分协议模型,在开发和维护过程效率比较低。
EasyCwmp设计架构

1.2 EasyCwmp源码组成

源码组成

1.3 EasyCwmp文件依赖

(1)libuci (配置文件管理)
(2)libcurl (http 协议处理)
(3)json-c (JSON 数据处理)
(4)libubox (openwrt核心库之一,事件处理)
(5)libubus (openwrt消息总线,实现不同应用程序之间的信息交互)
(6)microxml: microxml is a fork of Mini-XML,it’s being used to parse XML blocks passed between ACS and the client , and it’s published by freecwmp guys

2. EasyCwmp执行流程

2.1 主函数

详细代码可参考 easycwmp.c 中 main 函数:
(1) 获取输入参数。
(2) 建立互斥文件锁,设置互斥文件属性,确认为root登录。
(3) 内存分配,链表初始化,uloop_init,xml备份初始化。
(4) 创建子进程、两个pipe管道负责父子进程进行通信,子进程交给/usr/sbin/easycwmp 脚本程序接管,准备处理JSON格式参数。
(5) 加载easycwpm配置文件,通过配置文件初始化设备信息(设备类型、设备厂商、设备编号、厂商唯一编号),初始化心跳timer。
(6) 测试通过管道发送命令/usr/sbin/easycwmp 脚本程序并使其退出。
(7) 根据输入参数添加EVENT_BOOT或EVENT_PERIODIC事件到evens列表,设定timer回调处理事件(启动连接事件)。
(8) netlink_init,http_server_init 本地服务初始化
(9) 进入uloop_run主循环,处理事件消息。
在这里插入图片描述

2.2 RPC Methods (CPE)

在 EasyCwmp 源码中已经实现了 TR069 协议中常用 RPC 方法,源码定义的 RPC 方法在 xml.c 文件中:
const struct rpc_method rpc_methods[] = {
{ “GetRPCMethods”, xml_handle_get_rpc_methods },
{ “SetParameterValues”, xml_handle_set_parameter_values },
{ “GetParameterValues”, xml_handle_get_parameter_values },
{ “GetParameterNames”, xml_handle_get_parameter_names },
{ “GetParameterAttributes”, xml_handle_get_parameter_attributes },
{ “SetParameterAttributes”, xml_handle_set_parameter_attributes },
{ “AddObject”, xml_handle_AddObject },
{ “DeleteObject”, xml_handle_DeleteObject },
{ “Download”, xml_handle_download },
{ “Upload”, xml_handle_upload },
{ “Reboot”, xml_handle_reboot },
{ “FactoryReset”, xml_handle_factory_reset },
{ “ScheduleInform”, xml_handle_schedule_inform },
};

2.3 商业源码对比

免费与商业源码比较
初步阅读开源代码,未发现该开源代码有什么优势,这也许就是商业和非商业的区别。 而且在官网上,明确说明开源免费的效率要比商业版的低得多,而且维护也比较困难。其中,Data Model部分,是shell脚本编写,开源,集成到openwrt中。C写的才是商业机密,性能比你shell吊炸天!!!!要的就是你在shell里面痛苦,再找我要商业版的,_,外国犊子够奸诈了吧!!!!
所以,我们需要构建一个使用C语言程序编写的商业版的CWMP程序。

3. easycwmp源码编译和测试(X86平台)

环境:
linux系统:Ubuntu 18.04
CPE:easycwmp-1.8.6.tar.gz
ACS: 华为ITMS测试版
安装EasyCwmp所需要的依赖:若安装过程提示找不到安装包,请到更新Ubuntu源。

3.1 配置我们将要使用的USER和GROUP变量:

UUSER=yy
GROUP=yy

3.2. 创建目录

sudo mkdir -p /opt/{dev,git}
sudo chown -R $USER:$GROUP /opt/{dev,git}

3.3. 安装curl

sudo apt install libcurl4-openssl-dev

您的发行版应该已经包含curl开发包。可以直接使用。
注意:如果使用SSL软件包依赖关系来构建libcurl,则建议使用OpenSSL进行构建,因为EasyCwmp主要是使用OpenSSL与libcurl一起测试的。
如果使用PolarSSL构建libcurl,则无法使用ACS服务器进行摘要身份验证。

3.4 安装json-c

下载json:

git clone git://github.com/json-c/json-c.git /opt/git/json-c

因为出现错误:fatal: read error: Connection reset by peer
把git换成http即可。

git clone http://github.com/json-c/json-c.git /opt/git/json-c
cd /opt/git/json-c/

生成配置文件:

mkdir build
cd build
cmake ../CMakeLists.txt
../cmake-configure --prefix=/usr

编译

cd ..
make
sudo make install
sudo ln -sf /usr/include/json-c /usr/include/json

3.5.安装libubox

下载libubox:

git clone git://nbd.name/luci2/libubox.git /opt/git/libubox

或者命令

git clone http://git.nbd.name/luci2/libubox.git libubox
cd /opt/git/libubox/

安装依赖工具cmake:

sudo apt  install cmake

配置编译

cmake CMakeLists.txt -DBUILD_LUA=OFF
make

libubox在make时,报错:

/opt/git/libubox/blobmsg_json.c:78:6: error: implicit declaration of function ‘is_error’;
/opt/git/libubox/jshn.c:162:6: error: implicit declaration of function ‘is_error’; 

需要在对应C文件中添加

#define is_error(ptr) (ptr == NULL)

宏定义重新编译

安装:

sudo make install
sudo ln -sf /usr/local/lib/libubox.so /usr/lib/libubox.so
sudo mkdir -p /usr/share/libubox

3.6.安装uci

下载uci源码

git clone git://nbd.name/uci.git /opt/git/uci
cd /opt/git/uci/

配置编译

cmake CMakeLists.txt -DBUILD_LUA=OFF
make

安装

class="western"
sudo make install
sudo ln -sf /usr/local/bin/uci /sbin/uci
sudo ln -sf /usr/local/lib/libuci.so /usr/lib/libuci.so

3.7.安装ubus

下载ubus源码:

git clone git://nbd.name/luci2/ubus.git /opt/git/ubus
cd /opt/git/ubus/

配置编译ubus

cmake CMakeLists.txt -DBUILD_LUA=OFF
make

安装ubus

sudo make install
sudo ln -sf /usr/local/sbin/ubusd /usr/sbin/ubusd
sudo ln -sf /usr/local/lib/libubus.so /usr/lib/libubus.so

3.8. 安装microxml

下载源码:

git clone https://github.com/pivasoftware/microxml.git /opt/git/microxml
cd /opt/git/microxml/

生成配置文件:
先安装依赖工具autoconf

sudo apt install autoconf
autoconf -i

配置编译

./configure --prefix=/usr --enable-threads --enable-shared --enable-static
make

安装

sudo make install
sudo ln -sf /usr/lib/libmicroxml.so.1.0 /lib/libmicroxml.so
sudo ln -sf /usr/lib/libmicroxml.so.1.0 /lib/libmicroxml.so.1

3.9. 安装easycwmp

一旦安装了依赖项,我们就可以开始编译easycwmp。
获取最新源码easycwmp-1.8.6.tar.gz:
下载easycwmp-1.8.6.tar.gz 解压到 /opt/dev/

cd /opt/dev/
tar -xvf easycwmp-1.8.6.tar.gz
mv easycwmp-1.8.6 easycwmp
cd /opt/dev/easycwmp/

生成配置文件

autoreconf -i

配置

./configure --enable-debug --enable-devel --enable-acs=multi --enable-jsonc=1

在配置过程出现如下错误:

./configure: line 4129: syntax error near unexpected token `LIBCURL,'
./configure: line 4129: `PKG_CHECK_MODULES(LIBCURL, libcurl)'

解决方法:、
安装PKG依赖包

sudo apt install pkg-config 
sudo apt install libssl-dev

然后从 autoreconf -i 开始重新配置
再进行编译

make

4. 配置easycwmp运行环境

4.1 符号链接和脚本变量

配置easycwmp运行环境:
不用安装easycwmp,将其存放到/opt/dev/easycwmp/目录中,可直接使用它,进入 /opt/dev/easycwmp/目录
因为我们正在使用此设置进行开发,所以我们希望所有更改都在git克隆中可见。最好的方法是使用符号链接。首先在实际设备上创建脚本所在的目录:

sudo mkdir -p /usr/share/easycwmp/functions
sudo mkdir -p /etc/easycwmp

然后为easycwmp脚本创建符号链接:

sudo ln -sf /opt/dev/easycwmp/ext/openwrt/scripts/easycwmp.sh /usr/sbin/easycwmp
sudo ln -sf /opt/dev/easycwmp/ext/openwrt/scripts/defaults /usr/share/easycwmp/defaults
sudo ln -sf /opt/dev/easycwmp/ext/openwrt/scripts/functions/common/common /usr/share/easycwmp/functions/common
sudo ln -sf /opt/dev/easycwmp/ext/openwrt/scripts/functions/common/device_info /usr/share/easycwmp/functions/device_info
sudo ln -sf /opt/dev/easycwmp/ext/openwrt/scripts/functions/common/management_server /usr/share/easycwmp/functions/management_server
sudo ln -sf /opt/dev/easycwmp/ext/openwrt/scripts/functions/common/ipping_launch /usr/share/easycwmp/functions/ipping_launch
sudo ln -sf /opt/dev/easycwmp/ext/openwrt/scripts/functions/tr181/root /usr/share/easycwmp/functions/root
sudo ln -sf /opt/dev/easycwmp/ext/openwrt/scripts/functions/tr181/ip /usr/share/easycwmp/functions/ip
sudo ln -sf /opt/dev/easycwmp/ext/openwrt/scripts/functions/tr181/ipping_diagnostic /usr/share/easycwmp/functions/ipping_diagnostic

然后修改脚本为可执行

chmod +x /opt/dev/easycwmp/ext/openwrt/scripts/functions/*

同样,可以为easycwmp配置文件创建符号链接:

sudo mkdir /etc/config
sudo ln -sf /opt/dev/easycwmp/ext/openwrt/config/easycwmp /etc/config/easycwmp

最后为easycwmpd二进制文件创建符号链接:

sudo ln -sf /opt/dev/easycwmp/bin/easycwmpd /usr/sbin/easycwmpd

导出在easycwmp脚本中使用的一些变量:

export UCI_CONFIG_DIR="/opt/dev/easycwmp/ext/openwrt/config/"
export UBUS_SOCKET="/var/run/ubus.sock"

4.2 shell脚本进行测试

从OpenWrt安装一些shell脚本进行测试:

sudo mkdir -p /lib/{config,functions}
sudo wget http://pastebin.lukaperkov.net/openwrt/20121219_lib_functions.sh -O /lib/functions.sh
sudo wget http://pastebin.lukaperkov.net/openwrt/20121219_lib_config_uci.sh -O /lib/config/uci.sh
sudo wget http://pastebin.lukaperkov.net/openwrt/20121219_lib_functions_network.sh -O /lib/functions/network.sh

如果在运行时一切配置正确,执行以下操作:

bash /usr/sbin/easycwmp get value Device.

可以看到打印输出如下:

{ "parameter": "Device.DeviceInfo.Manufacturer", "fault_code": "", "value": "easycwmp", "type": "xsd:string" }
{ "parameter": "Device.DeviceInfo.ManufacturerOUI", "fault_code": "", "value": "FFFFFF", "type": "xsd:string" }
{ "parameter": "Device.DeviceInfo.ProductClass", "fault_code": "", "value": "easycwmp", "type": "xsd:string" }
{ "parameter": "Device.DeviceInfo.SerialNumber", "fault_code": "", "value": "FFFFFF123456", "type": "xsd:string" }
{ "parameter": "Device.DeviceInfo.HardwareVersion", "fault_code": "", "value": "example_hw_version", "type": "xsd:string" }
{ "parameter": "Device.DeviceInfo.SoftwareVersion", "fault_code": "", "value": "example_sw_version", "type": "xsd:string" }
{ "parameter": "Device.DeviceInfo.UpTime", "fault_code": "", "value": "429120", "type": "xsd:string" }

根据您的系统,您可能需要:

export PATH=$PATH:/usr/sbin:/sbin
sudo ln -sf bash /bin/sh

请注意,您的系统/bin/sh符号链接应指向bash解释器。

4.3 配置ACS URL和CPE参数

在运行easycwmp程序之前,配置easycwmp的ACS URL地址以及CPE网卡名称:

vim /etc/config/easycwmp  

        option interface 'ens38'
        option url 'http://192.168.200.11:9090/ACS-server/ACS'

注释掉验证的用户名和密码

#option username 'cpe'
#option password 'cpe'

在/etc/config/easycwmp和/usr/share/easycwmp/defaults中进行更改,以便easycwmpd可以连接到ACS服务器。但是在运行easycwmpd之前,请确保已在另一个运行ubusd的终端中:
一个终端运行ubus:

sudo ubusd -s /var/run/ubus.sock

另一个终端运行:

sudo /usr/sbin/easycwmpd -f -b

4.4 问题

在对接华为ITMS的软件,出现错误:

....
--- SEND HTTP REQUEST ---
> POST /ACS-server/ACS HTTP/1.1
Host: 192.168.4.11:9090
User-Agent: easycwmp
Content-Type: text/xml; charset="utf-8"
SOAPAction:
Content-Length: 2733
Expect: 100-continue

* Operation timed out after 30008 milliseconds with 0 bytes received
2017-04-24 09:20:46 [easycwmp] NOTICE - LibCurl Error: Operation timed out after 30008 milliseconds with 0 bytes received
2017-04-24 09:20:46 [easycwmp] NOTICE - sending http message failed
.....

具体原因参考:
easycwmp对接ITMS连接错误

修改方法:
查找/opt/dev/easycwmp/ 源码,把所有urn:dslforum-org:cwmp-1-2 版本 改成urn:dslforum-org:cwmp-1-0
主要涉及到的文件如下:

yy@ubuntu:/opt/dev/easycwmp$ grep "cwmp-1-2"  . -nR
./ext/soap_msg_templates/cwmp_inform_message.xml:7:     xmlns:cwmp="urn:dslforum-org:cwmp-1-2">
./ext/soap_msg_templates/cwmp_response_message.xml:7:   xmlns:cwmp="urn:dslforum-org:cwmp-1-2">
Binary file ./src/easycwmpd-backup.o matches
./src/messages.h:23:    "xmlns:cwmp=\"urn:dslforum-org:cwmp-1-2\">"                                                             \
./src/messages.h:53:    "xmlns:cwmp=\"urn:dslforum-org:cwmp-1-2\">"                                     \
./src/messages.h:67:    "xmlns:cwmp=\"urn:dslforum-org:cwmp-1-2\">"                                     \
./src/messages.h:84:    "xmlns:cwmp=\"urn:dslforum-org:cwmp-1-2\">"                                     \
./src/xml.c:61:         "urn:dslforum-org:cwmp-1-2", 

然后,重新编译easycwmp即可

cd /opt/dev/easycwmp/
make

再次运行测试:
一个终端运行ubus:

sudo ubusd -s /var/run/ubus.sock

另一个终端运行:

sudo /usr/sbin/easycwmpd -f -b
举报

相关推荐

0 条评论