OpenWrt 集成 easycwmpd 成为 TR-069协议中的设备端(CPE)

OpenWrt 集成 easycwmpd 成为 TR-069协议中的设备端(CPE)

 

easycwmpd 是 EasyCwmp 这个开源 CWMP(CPE WAN Management Protocol) 客户端软件的核心后台守护进程(daemon)

简单来说,它让OpenWrt这样的设备可以成为TR-069协议中的CPE,接受远程ACS(自动配置服务器)的管理

💡 它主要做什么?

  • 与ACS通信:作为设备端(CPE),它会主动向ACS服务器发起连接,报告设备信息和事件。它的工作方式取决于启动时带的参数,例如,用 --boot 参数启动会发送"1 BOOT"事件,表示设备刚刚启动;用 --getrpcmethod 参数启动则会发送"2 PERIODIC"事件,并进行方法查询

  • 执行管理任务:接收并执行来自ACS的远程命令,例如重启设备、恢复出厂设置、下载配置文件、修改配置参数等

  • 本地操作与调试:即使不与ACS通信,你也可以通过 easycwmp 命令(注意没有后面的 d)在本地查看和操作数据模型,比如使用 easycwmp get value 来查看所有TR-069参数

⚙️ 在你OpenWrt上的关键操作

结合你之前用apk安装.apk文件的场景,成功安装后,你需要关注以下几点:

  1. 核心配置文件/etc/config/easycwmp 这个UCI配置文件非常重要,所有连接ACS的信息都在这里设置,包括:

    • config acs 里的 url、认证的 username/password

    • config local 里的 periodic_enable 和 periodic_interval,控制心跳上报的开关和周期

  2. 启动与停止:进程管理通常通过 /etc/init.d/easycwmpd 脚本来完成

    • 启动:/etc/init.d/easycwmpd start

    • 停止:/etc/init.d/easycwmpd stop

    • 重启:/etc/init.d/easycwmpd restart

  3. 前台调试:如果后台启动遇到问题(比如之前有人在日志里看到“Broken pipe”报错),可以用前台模式运行来查看详细输出,非常有助于调试。例如:

    bash
    # 先停止后台服务
    /etc/init.d/easycwmpd stop
    # 在前台运行,并模拟启动(BOOT)事件
    /usr/sbin/easycwmpd -f -b

    -f 表示前台运行,-b 表示发送 "1 BOOT" 事件

  4. 日志查看:日志默认会记录在OpenWrt的系统日志中,可以通过 logread | grep easycwmp 来查看

⚠️ 注意事项

  • 确认已安装:你可以先用 which easycwmpd 命令确认 easycwmpd 程序是否已安装到系统中。

  • 配置文件:检查 /etc/config/easycwmp 中的ACS URL、用户名、密码是否填写正确,这是能否成功连接的关键

 

在OpenWrt上测试 easycwmpd的功能

在OpenWrt上测试 easycwmpd,可以从本地功能验证和与ACS服务器联调两个方面入手。

🔧 本地功能验证 (无需ACS)

这部分测试可以帮你确认 easycwmpd 本身及其数据模型(Data Model)是否工作正常,这是最基础的调试步骤。

1. 查看数据模型

easycwmp 命令行工具(注意没有末尾的 d)是查看和操作本地数据模型参数的主要方式。你可以用它来查看设备的所有TR-069参数

bash
# 查看所有数据模型参数树
easycwmp get value

2. 模拟ACS调用 (高级调试)

easycwmp 支持通过 --json-input 参数,以交互式JSON命令的方式模拟ACS的RPC调用,非常适合用来测试特定参数的 get 和 set 脚本逻辑是否正确

bash
# 启动交互式调试会话
easycwmp --json-input

进入交互模式后,可以输入JSON格式的命令来测试,例如:

json
# 测试获取参数
{ "command": "get", "parameter": "Device.DeviceInfo.Manufacturer" }

# 测试设置参数 (注意部分参数为只读)
{ "command": "set", "parameter": "Device.DeviceInfo.Manufacturer", "argument": "YourVendor" }

# 应用更改 (对于需要apply生效的参数)
{ "command": "apply", "class": "value", "argument": "unsetCommandKey" }

# 结束会话
{ "command": "exit" }

3. 前台运行并查看详细日志

easycwmpd 支持在前台运行,并将详细的调试信息直接打印到终端,这是定位启动或连接问题最有效的方法

首先,确保后台没有运行中的 easycwmpd 进程

bash
/etc/init.d/easycwmpd stop

然后,在前台启动 easycwmpd,并带上 -b 参数模拟设备启动(发送 "1 BOOT" 事件)

bash
# -f: 前台运行, -b: 发送 BOOT 事件
/usr/sbin/easycwmpd -f -b

你需要观察终端输出的日志,寻找连接成功、失败或错误信息。

🌐 与ACS服务器联调

这部分测试用于验证 easycwmpd 能否与真实的ACS(如GenieACS)正常通信,执行完整的TR-069会话。

1. 检查并配置连接信息

easycwmpd 使用UCI配置文件 /etc/config/easycwmp,确保以下关键配置正确,尤其是ACS的URL

bash
# 查看并编辑配置
vi /etc/config/easycwmp

重点检查 config acs 部分:

  • option url:ACS服务器的完整URL,例如 http://<你的ACS服务器IP>:7547

  • option periodic_enable 和 option periodic_interval:控制心跳上报的开关和周期。

2. 检查ubus通信

easycwmpd 通过 ubus 与OpenWrt系统通信。如果 ubus list 输出中看不到 tr069,说明通信可能有问题,可以尝试手动设置 ubus 套接字路径后重启服务

bash
# 设置正确的ubus socket路径 (路径可能因版本而异)
uci set easycwmp.@local[0].ubus_socket=/tmp/run/ubus/ubus.sock
# 或者对于老版本系统 /var/run/ubus.sock [citation:9]

# 提交更改并重启服务
uci commit easycwmp
/etc/init.d/easycwmpd restart

# 再次检查
ubus list | grep tr069

3. 启动服务并观察日志

正确配置后,启动服务并实时查看系统日志:

bash
/etc/init.d/easycwmpd start
logread -f | grep easycwmp

在ACS管理界面应该能看到设备上线。如果连接失败,日志中会包含错误信息,有助于进一步排查。

⚠️ 关键注意事项

  • 配置文件被覆盖问题:你可能会遇到修改 /etc/config/easycwmp 后重启服务,某些参数(如 manufacturer)被自动重置的情况。这是因为 easycwmp 在启动时会从 /etc/device_info 文件读取并覆盖这些设备信息参数。如需永久修改,应编辑 /etc/device_info 文件。

  • 只读参数:部分数据模型参数(如 Device.DeviceInfo.Manufacturer)被定义为只读。尝试使用 easycwmp set value 修改它会返回错误码(如9008),这是正常现象。修改这类参数需要通过前面提到的 /etc/device_info 文件。

 

查看 easycwmp 的配置文件内容

root@LWrt:~# 
root@LWrt:~# cat /etc/config/easycwmp 

config local
        option enable '1'
        option interface 'wan'
        option port '7547'
        option ubus_socket '/var/run/ubus.sock'
        option date_format '%FT%T%z'
        option username 'easycwmp'
        option password 'easycwmp'
        option authentication 'Digest'
        option logging_level '3'

config acs
        option url 'http://192.168.1.110:8080/openacs/acs'
        option username 'easycwmp'
        option password 'easycwmp'
        option periodic_enable '1'
        option periodic_interval '100'
        option periodic_time '0001-01-01T00:00:00Z'

config device
        option manufacturer 'LWrt'
        option oui '9483C4'
        option product_class 'Generic'
        option serial_number '9483C40C47E6'
        option hardware_version 'v0'
        option software_version 'r37854-4b24da3b4c5c'

root@LWrt:~# 
root@LWrt:~# ps -ef | grep easycwmp
 7242 root      8344 S    /usr/sbin/easycwmpd -f --boot
31319 root      1424 S    grep easycwmp
root@LWrt:~# 
root@LWrt:~# easycwmp -h
USAGE: /usr/sbin/easycwmp command [parameter] [values]
command:
  get [value|notification|name]
  set [value|notification]
  apply [value|notification|object|service]
  add [object]
  delete [object]
  download
  upload
  factory_reset
  reboot
  inform [parameter|device_id]
  --json-input
invalid action '-h'
root@LWrt:~# 

 

查看设备的所有TR-069参数

root@LWrt:~# easycwmp get value
{ "parameter": "Device.DeviceInfo.SpecVersion", "value": "1.0" }
{ "parameter": "Device.DeviceInfo.ProvisioningCode", "value": "" }
{ "parameter": "Device.DeviceInfo.Manufacturer", "value": "LWrt" }
{ "parameter": "Device.DeviceInfo.ManufacturerOUI", "value": "9483C4" }
{ "parameter": "Device.DeviceInfo.ModelName", "value": "GL-MT300N-V2" }
{ "parameter": "Device.DeviceInfo.ProductClass", "value": "Generic" }
{ "parameter": "Device.DeviceInfo.SerialNumber", "value": "9483C40C47E6" }
{ "parameter": "Device.DeviceInfo.HardwareVersion", "value": "v0" }
{ "parameter": "Device.DeviceInfo.SoftwareVersion", "value": "r37854-4b24da3b4c5c" }
{ "parameter": "Device.DeviceInfo.UpTime", "value": "1328", "type": "xsd:unsignedInt" }
{ "parameter": "Device.DeviceInfo.DeviceLog", "value": "" }
{ "parameter": "Device.DeviceInfo.MemoryStatus.Total", "value": "250556" }
{ "parameter": "Device.DeviceInfo.MemoryStatus.Free", "value": "120244" }
{ "parameter": "Device.DHCPv4.Server.Enable", "value": "1", "type": "xsd:boolean" }
{ "parameter": "Device.DHCPv4.Server.Pool.1.Enable", "value": "1", "type": "xsd:boolean" }
{ "parameter": "Device.DHCPv4.Server.Pool.1.Status", "value": "Enabled" }
{ "parameter": "Device.DHCPv4.Server.Pool.1.Interface", "value": "Device.IP.Interface.2." }
{ "parameter": "Device.DHCPv4.Server.Pool.1.MinAddress", "value": "192.168.100.100" }
{ "parameter": "Device.DHCPv4.Server.Pool.1.MaxAddress", "value": "192.168.100.250" }
{ "parameter": "Device.DHCPv4.Server.Pool.1.SubnetMask", "value": "255.255.255.0" }
{ "parameter": "Device.DHCPv4.Server.Pool.1.DNSServers", "value": "" }
{ "parameter": "Device.DHCPv4.Server.Pool.1.IPRouters", "value": "192.168.100.1\/24" }
{ "parameter": "Device.DHCPv4.Server.Pool.1.LeaseTime", "value": "43200", "type": "xsd:int" }
{ "parameter": "Device.DHCPv4.Server.Pool.2.Enable", "value": "0", "type": "xsd:boolean" }
{ "parameter": "Device.DHCPv4.Server.Pool.2.Status", "value": "Disabled" }
{ "parameter": "Device.DHCPv4.Server.Pool.2.Interface", "value": "Device.IP.Interface.3." }
{ "parameter": "Device.DHCPv4.Server.Pool.2.MinAddress", "value": "192.168.110.0" }
{ "parameter": "Device.DHCPv4.Server.Pool.2.MaxAddress", "value": "192.168.110.0" }
{ "parameter": "Device.DHCPv4.Server.Pool.2.SubnetMask", "value": "255.255.255.0" }
{ "parameter": "Device.DHCPv4.Server.Pool.2.DNSServers", "value": "192.168.110.1" }
{ "parameter": "Device.DHCPv4.Server.Pool.2.IPRouters", "value": "192.168.110.93" }
{ "parameter": "Device.DHCPv4.Server.Pool.2.LeaseTime", "value": "0", "type": "xsd:int" }
{ "parameter": "Device.IP.Interface.1.Enable", "value": "1", "type": "xsd:boolean" }
{ "parameter": "Device.IP.Interface.1.Name", "value": "loopback" }
{ "parameter": "Device.IP.Interface.1.Type", "value": "Loopback" }
{ "parameter": "Device.IP.Interface.1.IPv4AddressNumberOfEntries", "value": "1", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.1.IPv4Address.1.IPAddress", "value": "127.0.0.1" }
{ "parameter": "Device.IP.Interface.1.IPv4Address.1.AddressingType", "value": "Static" }
{ "parameter": "Device.IP.Interface.1.IPv4Address.1.Enable", "value": "1", "type": "xsd:boolean" }
{ "parameter": "Device.IP.Interface.1.IPv4Address.1.SubnetMask", "value": "255.0.0.0" }
{ "parameter": "Device.IP.Interface.1.Stats.BytesSent", "value": "68316", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.1.Stats.BytesReceived", "value": "68316", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.1.Stats.PacketsSent", "value": "952", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.1.Stats.PacketsReceived", "value": "952", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.1.Stats.ErrorsSent", "value": "0", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.1.Stats.ErrorsReceived", "value": "0", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.1.Stats.DiscardPacketsSent", "value": "0", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.1.Stats.DiscardPacketsReceived", "value": "0", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.2.Enable", "value": "1", "type": "xsd:boolean" }
{ "parameter": "Device.IP.Interface.2.Name", "value": "lan" }
{ "parameter": "Device.IP.Interface.2.Type", "value": "Normal" }
{ "parameter": "Device.IP.Interface.2.IPv4AddressNumberOfEntries", "value": "1", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.2.IPv4Address.1.IPAddress", "value": "192.168.100.1" }
{ "parameter": "Device.IP.Interface.2.IPv4Address.1.AddressingType", "value": "Static" }
{ "parameter": "Device.IP.Interface.2.IPv4Address.1.Enable", "value": "1", "type": "xsd:boolean" }
{ "parameter": "Device.IP.Interface.2.IPv4Address.1.SubnetMask", "value": "255.255.255.0" }
{ "parameter": "Device.IP.Interface.2.Stats.BytesSent", "value": "4957296", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.2.Stats.BytesReceived", "value": "878582", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.2.Stats.PacketsSent", "value": "5201", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.2.Stats.PacketsReceived", "value": "4390", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.2.Stats.ErrorsSent", "value": "0", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.2.Stats.ErrorsReceived", "value": "0", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.2.Stats.DiscardPacketsSent", "value": "0", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.2.Stats.DiscardPacketsReceived", "value": "0", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.3.Enable", "value": "1", "type": "xsd:boolean" }
{ "parameter": "Device.IP.Interface.3.Name", "value": "wan" }
{ "parameter": "Device.IP.Interface.3.Type", "value": "Normal" }
{ "parameter": "Device.IP.Interface.3.IPv4AddressNumberOfEntries", "value": "1", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.3.IPv4Address.1.IPAddress", "value": "192.168.110.93" }
{ "parameter": "Device.IP.Interface.3.IPv4Address.1.AddressingType", "value": "DHCP" }
{ "parameter": "Device.IP.Interface.3.IPv4Address.1.Enable", "value": "1", "type": "xsd:boolean" }
{ "parameter": "Device.IP.Interface.3.IPv4Address.1.SubnetMask", "value": "255.255.255.0" }
{ "parameter": "Device.IP.Interface.3.Stats.BytesSent", "value": "964083", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.3.Stats.BytesReceived", "value": "4870554", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.3.Stats.PacketsSent", "value": "5440", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.3.Stats.PacketsReceived", "value": "6773", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.3.Stats.ErrorsSent", "value": "0", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.3.Stats.ErrorsReceived", "value": "0", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.3.Stats.DiscardPacketsSent", "value": "0", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Interface.3.Stats.DiscardPacketsReceived", "value": "0", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Diagnostics.IPPing.DiagnosticsState", "value": "None" }
{ "parameter": "Device.IP.Diagnostics.IPPing.Host", "value": "" }
{ "parameter": "Device.IP.Diagnostics.IPPing.NumberOfRepetitions", "value": "3", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Diagnostics.IPPing.Timeout", "value": "1000", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Diagnostics.IPPing.DataBlockSize", "value": "64", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Diagnostics.IPPing.SuccessCount", "value": "0", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Diagnostics.IPPing.FailureCount", "value": "0", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Diagnostics.IPPing.AverageResponseTime", "value": "0", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Diagnostics.IPPing.MinimumResponseTime", "value": "0", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Diagnostics.IPPing.MaximumResponseTime", "value": "0", "type": "xsd:unsignedInt" }
{ "parameter": "Device.ManagementServer.URL", "value": "http:\/\/192.168.1.110:8080\/openacs\/acs" }
{ "parameter": "Device.ManagementServer.Username", "value": "easycwmp" }
{ "parameter": "Device.ManagementServer.Password", "value": "" }
{ "parameter": "Device.ManagementServer.PeriodicInformEnable", "value": "1", "type": "xsd:boolean" }
{ "parameter": "Device.ManagementServer.PeriodicInformInterval", "value": "100", "type": "xsd:unsignedInt" }
{ "parameter": "Device.ManagementServer.PeriodicInformTime", "value": "0001-01-01T00:00:00Z", "type": "xsd:dateTime" }
{ "parameter": "Device.ManagementServer.ConnectionRequestURL", "value": "http:\/\/192.168.110.93:7547\/" }
{ "parameter": "Device.ManagementServer.ConnectionRequestUsername", "value": "easycwmp" }
{ "parameter": "Device.ManagementServer.ConnectionRequestPassword", "value": "" }
{ "parameter": "Device.ManagementServer.ParameterKey", "value": "" }
{ "parameter": "Device.WiFi.Radio.1.Enable", "value": "1", "type": "xsd:boolean" }
{ "parameter": "Device.WiFi.Radio.1.Status", "value": "Up" }
{ "parameter": "Device.WiFi.Radio.1.Name", "value": "radio0" }
{ "parameter": "Device.WiFi.Radio.1.SupportedFrequencyBands", "value": "" }
{ "parameter": "Device.WiFi.Radio.1.OperatingFrequencyBand", "value": "" }
{ "parameter": "Device.WiFi.Radio.1.ChannelsInUse", "value": "" }
{ "parameter": "Device.WiFi.Radio.1.Channel", "value": "7", "type": "xsd:unsignedInt" }
{ "parameter": "Device.WiFi.Radio.1.AutoChannelSupported", "value": "1", "type": "xsd:boolean" }
{ "parameter": "Device.WiFi.Radio.1.AutoChannelEnable", "value": "0", "type": "xsd:boolean" }
{ "parameter": "Device.WiFi.Radio.1.OperatingStandards", "value": "HT20" }
{ "parameter": "Device.WiFi.SSID.1.Enable", "value": "1", "type": "xsd:boolean" }
{ "parameter": "Device.WiFi.SSID.1.Status", "value": "Up" }
{ "parameter": "Device.WiFi.SSID.1.Name", "value": "phy0-ap0" }
{ "parameter": "Device.WiFi.SSID.1.LowerLayers", "value": "Device.WiFi.Radio.1." }
{ "parameter": "Device.WiFi.SSID.1.SSID", "value": "WelcomeNDS" }
{ "parameter": "Device.WiFi.SSID.1.X_IPInterface", "value": "Device.IP.Interface.2." }
{ "parameter": "Device.WiFi.AccessPoint.1.Enable", "value": "1", "type": "xsd:boolean" }
{ "parameter": "Device.WiFi.AccessPoint.1.Status", "value": "Enabled" }
{ "parameter": "Device.WiFi.AccessPoint.1.SSIDReference", "value": "Device.WiFi.SSID.1." }
{ "parameter": "Device.WiFi.AccessPoint.1.Security.ModesSupported", "value": "None,WEP-64,WEP-128,WPA-Personal,WPA2-Personal,WPA-WPA2-Personal,WPA3-Personal,WP2-WPA3-Personal,WPA-Enterprise,WPA2-Enterprise,WPA-WPA2-Enterprise,WPA3-Enterprise" }
{ "parameter": "Device.WiFi.AccessPoint.1.Security.ModeEnabled", "value": "None" }
{ "parameter": "Device.WiFi.AccessPoint.1.Security.WEPKey", "value": "", "type": "xsd:hexBinary­" }
{ "parameter": "Device.WiFi.AccessPoint.1.Security.PreSharedKey", "value": "", "type": "xsd:hexBinary­" }
{ "parameter": "Device.WiFi.AccessPoint.1.Security.KeyPassphrase", "value": "" }
root@LWrt:~# 

 

模拟ACS调用,交互式查询,JSON的格式报文。

image

 

配置ACS服务器的URL地址 及 心跳上报开关 和 心跳上报周期

image

 

 

=============== End

 

posted @ 2026-06-17 20:52  lsgxeva  阅读(3)  评论(0)    收藏  举报