CWMP\TR069协议学习随笔1——入门基础知识及环境搭建

什么是CWMP(TR069)

CWMP是由数字用户线路DSL——Digital Subscriber’s Line论坛(之后更名为broadband-forum)发起开发的技术规范之一,编号为TR-069,所以又被称为TR-069协议

CWMP协议基础概念

CWMP的全称为:CPE广域网管理协议(CPE WAN Management Protocol),这个协议主要用于网管中心远程管理配置数量较大的网络设备。目前主要应用在企业级路由器、一体化皮基站等网络设备的管理,所以CWMP是一个功能强大的用于数据中心、网管中心管理它所属的所有网络设备的网管协议

CWMP\TR069协议学习随笔1——入门基础知识及环境搭建_第1张图片

  • CPE是客户端设备(Customer Premises Equipment)的简称
  • ACS是自动配置服务器(Auto-Configuration Server)的简称
  • 运营支持系统(Operation Support System,OSS)和业务支撑系统(Business Support System,BSS)

与SNMP协议的比较

提到网管协议,就插一句说说SNMP协议,SNMP协议是目前被应用最为广泛的网管协议,以下就是SNMP与CWMP协议之间的部分功能对比:

功能点 CWMP SNMP
管理设备方式 被管理设备主动向ACS服务器请求DHCP分配IP 被管理设备初始化配置时,必须手动配置管理中心IP地址
管理设备数量 方法简单,数量大 方法复杂,数量小
传输数据协议 基于HTTP的SOAP规范,可传输更加丰富的数据或文件 基于UDP的SNMP报文,报文大小有限制
传输性能 请求时延高 请求时延低

CWMP主要功能

主要组成部分说明

CWMP的网络架构可简化为:

在这里插入图片描述

  • CPE就是网管中心下所有的被管理设备
  • ACS就是一个在网管中心带有DHCP服务、DNS服务,符合CWMP协议的数据配置服务器
主要功能
  • 提供数据参数配置
    • 被管理设备(CPE)接收来自ACS发起的配置请求,请求包括了协议标准的参数(比如TR098、TR181等协议规定的数据模型),以及用户自定义的数据模型
  • 文件管理
    • 被管理设备(CPE)可以从ACS服务器通过协议标准的数据模型上传或下载文件(包括升级软固件包、日志文件、性能统计文件等等)
  • 状态和性能监控
    • ACS可以通过标准定制的方法监控被管理设备(CPE)的状态和性能统计,同时CPE也可以主动通知ACS自身状态的更新
  • 告警上报
    • 被管理设备(CPE)可以主动向ACS服务器上传设备中的告警信息

CWMP协议栈

分类 协议层 描述
应用 CPE/ACS Management Application 应用可以在CPE和ACS端分别实现CWMP协议
远程调用方法 RPC Methods 在CWMP中定义的各种RPC方法,实现ACS与CPE之间的交互
报文填写标准 SOAP 1.1 消息内容是基于SOAP标准封装XML文档,避免了与防火墙的冲突
传输协议 HTTP 1.1 ACS为HTTP服务器,CPE为HTTP客户端
安全传输协议 SSL/TLS 标准的互联网传输层安全协议(可选)
底层协议 TCP/IP 标准的TCP/IP

我把这个协议栈分成两个部分说明:

  • 第一部分是定义协议如何传输的,即下边的三个协议TCP\SSL\HTTP这三层
  • 第二部分是定义协议如何使用的,即上边的三个协议SOAP\RPC\CWMP

其中,重点为第二部分,ACS通过标准的SOAP报文对CPE进行RPC远程调用,即ACS要向CPE通过SOAP传输要调用的函数名和参数。这就需要CPE上要有一个CWMP中间件去解析RPC方法,这也是本文要阐述和实现的重点

CPE侧RPC方法 中文说明 ACS侧RPC方法 中文说明
GetRPCMethods 获取RPC方法列表 GetRPCMethods 获取RPC方法列表
SetParameterValues ACS设置参数值 Inform 与ACS建立连接,通知
GetParameterValues ACS获取参数值 TransferComplete 通知传输完成
GetParameterNames ACS获取参数列表 AutonomousTransferComplete 通知传输完成(自动)
SetParameterAttributes ACS设置参数属性
GetParameterAttributes ACS获取参数属性
AddObject ACS增加一个新实例
DeleteObject ACS删除特定实例
Reboot 重启
Download 下载指定文件
Upload 上传指定文件
FactoryReset 恢复出厂设置

补充基础知识

HTTP与TCP协议基础

HTTP协议基于TCP协议,在传输之前,要建立TCP连接,也就是TCP的三次握手,在这里就不展开说明了。那么在建立连接之后,HTTP的客户端就会向服务器发送请求:

HTTP请求报文:

CWMP\TR069协议学习随笔1——入门基础知识及环境搭建_第2张图片

  • 第一部分:请求行

    最常用的方法有GET(向服务器获取所需要的信息)、POST(向服务器告知一些信息)、PUT(向指定资源位置上传信息)、DELETE(用来删除资源)
  • 第二部分:首部字段

    格式为Key Value,用于保存一些重要的字段,比如Accept-Charset表示客户端可以接受的字符集,content-Type表示正文格式(JSON、XML)、Cache-Control用来控制缓存
  • 第三部分:实体

    这一部分就是HTTP报文的具体内容了,可以是一个JSON格式字符串,也可以是一个二进制文件等等

HTTP返回报文:

CWMP\TR069协议学习随笔1——入门基础知识及环境搭建_第3张图片

  • 第一部分:状态行

    状态行的状态码如果是200意味着正常的请求,而404……
  • 第二部分:首部字段

    格式同样为Key-Value,Retry-After告诉客户端在多长时间之后再尝试访问,Content-Type表示返回的是HTML还是JSON

RPC协议基础

能够发送HTTP报文,证明TCP已经成功建立,也就是说Socket已经成功建立。那么服务器端和客户端如何相互调用对方的方法来实现自己想要进行的操作,这就需要用到RPC(Remote Procedure Call)远程调用方法了

远程调用比程序内部直接进行函数调用要复杂很多,RPC协议解决了以下的几个问题

  • 规定了远程调用的语法,即用何种格式将函数传递给远程进行调用
  • 规定了远程调用的参数格式,即用何种方式将函数的参数传递给远程进行调用
  • 规定了如何获取远程已经支持的函数方法
  • 发生错误、重传、丢包时,应该如何处理

RPC协议的处理流程回路:

CWMP\TR069协议学习随笔1——入门基础知识及环境搭建_第4张图片

  • 当客户端要发起一个远程调用时,先通过本地调用的Stub将调用的接口、方法和参数,通过约定的协议进行编码,并通过本地的RPCRuntime进行传输
  • 服务器端的RPCRuntime在接收到请求之后,交给Stub进行解码,然后调用服务器端的方法
  • 服务器端方法执行完成之后,再返回给Stub进行编码并通过RPCRuntime返回给客户端
  • 客户端RPCRuntime接收到结果,交给Stub进行解码,最终在本地返回

通过上述的流程,在Stub的作用下,客户端的用户和服务器端的用户,在调用函数的时候,和本地调用的用法基本一致,是感知不到是一个远程调用的


RPC协议的报文结构:
CWMP\TR069协议学习随笔1——入门基础知识及环境搭建_第5张图片

  • XID:标识请求(0)或者回复(1)
  • RPC版本号(RPC Version):如果版本号不匹配,会返回deny
  • 程序编号(Program Number):如果服务器端找不到对应的程序,会返回PROG_UNVAIL
  • 程序版本号(Version Number):程序版本号不匹配,就会返回PROG_MISMATCH
  • 认证鉴权:如果不通过,返回Deny
  • 参数列表:如果参数无法解析,则返回GABAGE_ARGS

所以:为了可以成功调用RPC,客户端和服务器端实现RPC的时候,首先要定义一个双方都认可的程序、版本、方法、参数等

SOAP协议基础

上边RPC的结论是,客户端和服务器端需要约定双方都认可的程序、版本、方法等,而这个约定的协议,在TR069中,就被规定为SOAP协议,SOAP(Simple Object Access Protocol)是一个基于XML的通信协议

SOAP将请求和回复放在了一个信封里边,分别包括了抬头和正文:


抬头

POST /purchaseOrder HTTP/1.1
Host: www.geektime.com
Content-Type: application/soap+xml; charset=utf-8
Content-Length: nnn
  • 通过HTTP的POST方法传递
  • 发送一个格式为application/soap+xml的XML文档给 www.geektime.com,下订单
  • 这个订单的内容在正文当中

正文



    
        1234
        
    
    
        
            
                2018-07-01
                 趣谈网络协议 
                 刘超 
                68
            
        
    

EasyCWMP

EasyCWMP是当前最为成熟的CWMP客户端软件,作为CWMP协议入门的学习,是再合适不过的了,其中EasyCWMP Core是开源的,十分方便我们进行二次开发和拓展

官网地址:http://easycwmp.org/

EasyCWMP主体分为了两个部分

  • EasyCwmp Core:包含了负责与ACS服务器交互的功能
  • EasyCwmp DataModel:包含了TR098、TR181、TR104等与TR069相关的数据模型规范

CWMP\TR069协议学习随笔1——入门基础知识及环境搭建_第6张图片

有关于EasyCWMP的具体说明会放到后边,首选先安装EasyCWMP的Release

安装EasyCWMP

在Ubuntu18.04下安装与简单使用

安装

官网流程:http://easycwmp.org/tutorial/

参考流程:https://www.cnblogs.com/myblesh/p/6225665.html

  • 如果没有用户组,先添加用户组,后边会用到
groupadd CertusNet
  • 配置用户和用户组
USER=your_user
GROUP=your_group
  • 创建文件夹
sudo mkdir -p /opt/{dev,git}
sudo chown -R $USER:$GROUP /opt/{dev,git}
  • 安装依赖
apt install curl
apt install libcurl4-openssl-dev
apt install pkg-config
apt install libssl-dev
apt install libtool

# 安装json-c
git clone git://github.com/json-c/json-c.git /opt/git/json-c
cd /opt/git/json-c/

./autogen.sh
./configure
make
make install
ln -sf /usr/local/include/json-c /usr/include/json


# libubox
git clone git://nbd.name/luci2/libubox.git /opt/git/libubox
cd /opt/git/libubox/
cmake CMakeLists.txt -DBUILD_LUA=OFF
make

遇到错误:
blobmsg_json.c:78:2 error: implicit declaration of function 'is_error'
jshn.c:162:2: error: implicit declaration of function 'is_error'
解决办法:
对应的文件里加入下面定义
#define is_error(ptr) (ptr == NULL)

-------------------
vim blobmsg_json.c
vim jshn.c 
-------------------

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

# 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

# ubus
git clone git://nbd.name/luci2/ubus.git /opt/git/ubus
cd /opt/git/ubus/
cmake CMakeLists.txt -DBUILD_LUA=OFF
make
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

# microxml
git clone https://github.com/pivasoftware/microxml.git /opt/git/microxml
cd /opt/git/microxml/
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

# 安装EasyCWMP
将下载好的EasyCWMP镜像文件放入到/opt/dev文件夹下
cd /opt/dev/
tar -xzvf easycwmp-{x}.{y}.{z}.tar.gz
mv easycwmp-{x}.{y}.{z} easycwmp
cd /opt/dev/easycwmp/

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

sudo mkdir -p /usr/share/easycwmp/functions
sudo mkdir -p /etc/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/*

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

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

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

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.

遇到问题记录:
  1. 按照官网上的教程安装microxml时,./configure的时候,出现如下问题:
# ./configure --prefix=/usr --enable-threads --enable-shared --enable-static
…………
./configure: line 4129: syntax error near unexpected token `LIBCURL,'
./configure: line 4129: `PKG_CHECK_MODULES(LIBCURL, libcurl)'

解决:没有安装PKG依赖包

apt install pkg-config
apt install libssl-dev

安装OpenACS调测环境

OpenACS是一个比较之前开源,但是现在被作者删除了所有代码的一个软件,目前网上只有Release可以下载,但仍然是目前我们能够用到的ACS服务器中的我所知道的唯一选择

在Ubuntu 18中安装OpenACS

我的环境如下:

  • VirtuaBox分别建立两个虚拟机,一个运行上一步完成的EasyCWMP,另一个运行OpenACS,网络配置选择“网桥模式”,让ACS和EasyCWMP运行在同一个网段中,同时也能让宿主机可以访问OpenACS
    • Ubuntu版本为18.04.1
    • MySQL版本为5.1.54(使用5.7以上版本,运行失败)
    • JDK版本为1.5.22
    • JBoss版本为4.2.2

安装步骤:

  • 第一步:安装JDK 1.5
# 将jdk-1_5_0_22-linux-amd64.bin复制到/opt文件夹下,并赋权限
chmod 777 jdk-1_5_0_22-linux-amd64.bin

# 安装,按空格查看下一页,直到提示输入yes
./jdk-1_5_0_22-linux-amd64.bin

# 添加环境变量
vim /etc/bash.bashrc

# 文件内容如下:
# System-wide .bashrc file for interactive bash(1) shells.

# To enable the settings / commands in this file for login shells as well,
# this file has to be sourced in /etc/profile.
PATH=$PATH:/opt/jdk1.5.0_22/bin
JAVA_HOME=/opt/jdk1.5.0_22
CLASS_PATH=/opt/jdk1.5.0_22/lib/tools.jar
export PATH JAVA_HOME CLASS_PATH


# 重启以使得java环境生效
reboot
# 或者使用source命令
source /etc/bash.bashrc

# 查看java是否配置成功
java -version
java version "1.5.0_22"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_22-b03)
Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_22-b03, mixed mode)
  • 第二步:安装MySQL,并配置
# 去MySQL官网下载5.1.54,下载Server和Client即可
# MySQL-client-5.1.54-1.glibc23.x86_64.rpm
# MySQL-server-5.1.54-1.glibc23.x86_64.rpm

# 安装rpm
sudo apt install rpm

# 安装MySQL的Server和Client
rpm -ivh MySQL-server-5.6.12-2.linux_glibc2.5.x86_64.rpm --force --nodeps
rpm -ivh MySQL-client-5.6.12-2.linux_glibc2.5.x86_64.rpm --force --nodeps

# 初始化数据库
/usr/bin/mysql_install_db --user=mysql

# 启动MySQL
/etc/init.d/mysql start

# 设置MySQL用户名密码
/usr/bin/mysqladmin -u root password 'root'

# 登陆Mysql
mysql -u root -p

# 为OpenACS分配一个用户
mysql>insert into mysql.user (Host,User,Password) values ('localhost','openacs',password('openacs'));
mysql>flush privileges;

# 创建ACS数据库,并赋给用户权限
mysql>create database ACS;
mysql>GRANT ALL ON ACS.* TO openacs@localhost IDENTIFIED BY 'openacs';
mysql>quit

# 用openacs用户登陆,并查看数据库
mysql -u openacs -p
mysql>show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| ACS                |
| test               |
+--------------------+
3 rows in set (0.06 sec)

# 至此,证明MySQL配置完成

  • 第三步:安装JBoss
# 将jboss-4.2.2.GA.zip拷贝到/opt目录下,并解压
unzip jboss-4.2.2.GA.zip

# 配置环境变量
vim /etc/bash.bashrc

# 在刚刚jdk的环境变量下边继续配置jboss的:
PATH=$PATH:/opt/jboss-4.2.2.GA/bin 
JBOSS_HOME=/opt/jboss-4.2.2.GA 

# 将数据库访问依赖mysql-connector-java-5.1.7-bin.jar复制到$(JBOSS_HOME)/server/default/lib/
cp mysql-connector-java-5.1.7-bin.jar /opt/jboss-4.2.2.GA/server/default/lib

# 关闭防火墙,方便其他机器访问:
sudo ufw disable
# 打开8080端口
/sbin/iptables -I INPUT -p tcp --dport 8080 -j ACCEPT
# 重启防火墙以生效
/etc/init.d/iptables restart

# 进入jboss目录后,验证jboss是否安装成功
cd /opt/jboss-4.2.2.GA/bin/
./run.sh 0.0.0.0

# 使用localhost:8080 或者 ip:8080 访问
# 最后,使用 Ctrl + C 退出与运行的JBoss,进入下一步安装OpenACS

CWMP\TR069协议学习随笔1——入门基础知识及环境搭建_第7张图片

  • 第四步:安装OpenACS
# 解压openacs-bin-0.5.0.3.zip
unzip openacs-bin-0.5.0.3.zip

# 将acs.ear复制到/opt/jboss-4.2.2.GA/server/default/deploy/
sudo cp acs.ear /opt/jboss-4.2.2.GA/server/default/deploy/

# 修改openacs-ds.xml
vim openacs-ds.xml



  
    ACS
    jdbc:mysql://localhost/ACS
    com.mysql.jdbc.Driver
    openacs
    openacs
    5
    20
    5
  


# 将修改后的文件复制到/opt/jboss-4.2.2.GA/server/default/deploy/
sudo cp openacs-ds.xml /opt/jboss-4.2.2.GA/server/default/deploy/

# 将openacs-service.xml复制到/opt/jboss-4.2.2.GA/server/default/deploy/jms
sudo cp openacs-service.xml /opt/jboss-4.2.2.GA/server/default/deploy/jms

# 启动JBoss
cd /opt/jboss-4.2.2.GA/bin/
./run.sh -b  0.0.0.0

# 访问OpenACS:
http://192.168.31.78:8080/openacs/

参考文章,感谢原作者:

  • 安装JDK1.5:https://www.linuxidc.com/Linux/2014-09/107291.htm
  • 安装MySQL:https://tydldd.iteye.com/blog/1904227
  • OpenACS安装参考1:https://blog.csdn.net/chow__zh/article/details/8348885
  • OpenACS安装参考2:https://blog.csdn.net/u011819712/article/details/46884841

配置EasyCWMP

  • 配置ACS的url
vim /etc/config/easycwmp
# 将option url修改为OpenACS的url:
option url http://[Your OpenACS Server IP]:8080/openacs/acs
  • 开始运行EasyCWMP
root@guoliang-VirtualBox:/home/guoliang# export PATH=$PATH:/usr/sbin:/sbin
root@guoliang-VirtualBox:/home/guoliang# ln -sf bash /bin/sh
root@guoliang-VirtualBox:/home/guoliang# /usr/sbin/ubusd -s /var/run/ubus.sock &
[1] 4239
root@guoliang-VirtualBox:/home/guoliang# /usr/sbin/easycwmpd -f -b

# 成功打印如下:
2019-02-09 16:48:33 [easycwmp] NOTICE - external script init
config_init_local(59):: easycwmp.@local[0].interface=eth0
config_init_local(69):: easycwmp.@local[0].port=7547
config_init_local(87):: easycwmp.@local[0].ubus_socket=/var/run/ubus.sock
config_init_local(75):: easycwmp.@local[0].username=easycwmp
config_init_local(81):: easycwmp.@local[0].password=easycwmp
……………………
SOAPAction:
Content-Length: 815

* upload completely sent off: 815 out of 815 bytes
< HTTP/1.1 204 No Content
< Server: Apache-Coyote/1.1
< X-Powered-By: Servlet 2.4; JBoss-4.2.2.GA (build: SVNTag=JBoss_4_2_2_GA date=200710221139)/Tomcat-5.5
< Date: Sat, 09 Feb 2019 09:54:11 GMT
< 
* Connection #0 to host 192.168.31.78 left intact
+++ RECEIVED EMPTY HTTP RESPONSE +++
2019-02-09 17:54:22 [easycwmp] NOTICE - receive empty message from the ACS
2019-02-09 17:54:22 [easycwmp] NOTICE - external: execute apply service 
2019-02-09 17:54:22 [easycwmp] NOTICE - external script exit
2019-02-09 17:54:22 [easycwmp] NOTICE - end session success
  • 此时,在OpenACS中的Find CPE中应该就能看到easycwmp了

CWMP\TR069协议学习随笔1——入门基础知识及环境搭建_第8张图片

本文中用到的所有软件下载

下载地址: https://download.csdn.net/download/colingg/10954595

  • MySQL-server-5.1.54
  • MySQL-client-5.1.54
  • mysql-connector-java-5.1.7-bin.jar
  • jdk-1_5_0_22-linux-amd64
  • jboss-4.2.2. GA
  • openacs-bin-0.5.0.3
  • easycwmp-1.8.0

本文参考资料

  • 网络协议篇之CWMP协议(一)—— CWMP(TR-069)基础

    https://blog.csdn.net/zqixiao_09/article/details/77130809
  • TR069协议规范 TR-069_Amendment-6.pdf

    https://www.broadband-forum.org/technical/download/TR-069.pdf
  • 华为AR200路由器配置指南

    https://support.huawei.com/enterprise/zh/doc/DOC1000154703?section=k006
  • 中国移动一体化皮基站网管南向接口技术规范

    https://download.csdn.net/download/colingg/10947904
  • 极客时间《趣谈网络协议》

    https://time.geekbang.org/column/intro/85?code=v5htOo-VdyX%2FinBZ5oMdV-7cbd7oPRXXqQZtSwC49jQ%3D

你可能感兴趣的:(网络协议)