声明:原创作品,严禁用于商业目的。 本系列文章将全面剖析以Bcm33xxx芯片开发Cablemodem产品的SDK源码为例,从编译系统到各个功能模块进行分析与探讨。
文章目录
0.写在前篇
本系列文章来自于博通公司相关项目开发中的学习资料和开发总结,是企业或者公司项目开发过程中必备的网络相关知识,主要涉及到ecos和linux系统编译、内存管理、接口管理、HAL抽象层、以及IPV6、DHCP、TR069等网络相关协议。为维护版权和相关知识产权,请购买官方SDK和相关服务,此系列文章仅为个人学习使用,如有不妥之处和技术相关知识,请私信留言!
博通Broadcom SDK源码学习与开发1——SDK源码探究与Cable Modem 系统编译
博通Broadcom SDK源码学习与开发2——Bootloader功能和编译过程
博通Broadcom SDK源码学习与开发3——Cable Modem Docsis3.0
博通Broadcom SDK源码学习与开发4——ECOS系统数据流
博通Broadcom SDK源码学习与开发5——ECOS系统层剖析
博通Broadcom SDK源码学习与开发6——支持Linux系统
博通Broadcom SDK源码学习与开发7——HAL硬件抽象层分析
博通Broadcom SDK源码学习与开发8——内存与参数管理
博通Broadcom SDK源码学习与开发9——Interface接口管理
博通Broadcom SDK源码学习与开发10——Cable Modem IPv6地址
博通Broadcom SDK源码学习与开发11——Cable Modem DHCP管理
博通Broadcom SDK源码学习与开发12终结篇——TR069网管协议
参考:TR069协议
1. TR069的Makefile和源码
- 编译:
在编译选项中添加“tr69”, 对应的makefile为: REV/rbb_cm_src/Bfc/make/BfcTR69.mak
- 相关源码
主要有3部分代码:tr069 client agent代码,用c实现;TR069Thread和CLI配置代码,c++实现;client agent与系统间的接口代码,c++实现。(具体实现在后文讲解)
//tr069 client agent代码
REV/rbb_cm_src/Bfc/IpHelpers/TR069/tr69c/
inc/ #放置与数据模型相关的宏定义,数据结构定义头文件
main/ #agent实现文件,main,informer,event
nanoxml/ #
SOAPParser/ #soap解析,其中RPCState.c为RPC命令处理接口
standard/ #节点数据模型定义文件
webproto/ #
//tr069thread与CLI参数配置
REV/rbb_cm_src/Bfc/IpHelpers/TR069/
BcmBfcTr69CommandTable.cpp #tr69 CLI实现
BcmBfcTr69SnmpApi.cpp #提供了通过snmp进行对系统参数的get/set接口,tr69 agent利用这些接口进行大部分参数的get/set
BcmBfcTr69ThreadIpStackACT.cpp #ip_stack ip变化时,通知TR069Thread启动或停止agent
BcmBfcTr69SocketApi.cpp #提供系统与agent间有关socket操作的接口,供agent调用
BcmBfcTr69Entry.cpp #
BfcTr69NonVolSettings.cpp
BfcTr69NonVolSettingsCommandTable.cpp #tr69 non-vol参数配置CLI
BcmBfcTr69NonVolApi.cpp #提供non-vol存取的接口,供agent调用
BcmBfcTr69Thread.cpp #tr069进程实现,控制agent的运行/停止/重启
//client agent系统调用接口
REV/rbb_cm_src/Bfc/IpHelpers/TR069/tr69c/bcmBfcIf/
其中的文件定义了与standard/目录下数据模型结构中对应的object的add/del,parameters的get/set api
2. 配置参数
2.1 CLI命令
CM>cd non-vol/tr69
CD>ls
acs_password acs_url acs_username conn_req_password conn_req_url conn_req_username
ip_stack_num periodic_inform_enable periodic_inform_interval
stun_enable stun_max_keepalive stun_mix_keepalive stun_password stun_server stun_username
其中,ip_stack_num为tr69 agent关联的wan interface对应的ipstack number,默认指定为3
此外,可使用的命令有如下:
CM>cd tr69
CM>ls
acs_url log send_inform show start_client stop_client test walk_tree
其中: client可理解为tr069 client agent
acs_url 修改acsurl
send_inform agent运行前提下,立即发送inform
start_client 如ip_stack_num对应的wan interface处于可用状态,则会运行agent
walk_tree 查看节点结构.
2.2 CM ConfigFile
参数配置 CM Config有定义TR-069参数:
eRouter Configuration Encodings (202)
eRouter TR-069 Management Server (2)
EnableCWMP (1)
URL (2)
Username (3)
Password (4)
ConnectionRequestUserName (5)
ConnectionRequestPassword (6)
ACSOverride (7)
其中,EnableSWMP和ACSOverride会影响tr69 agent的行为。
2.3 DHCP option
利用DHCPv6 Option17或DHCPv4 Option125来配置ACSUrl参数
3. 多种配置参数的优先顺序
(1)启动方式:
通过CLI(start_client)启动,此时使用的为通过CLI配置的参数,即在NonVol中的参数
自动启动,条件为CM Config中的EnableCWMP为true,或者得到有效的DHCPv6 Option17或DHCPv4 Option125。此时的参数选择如下
(2)自动启动时的参数选择
// 其他参数(acsusername,acspassword,connrequsername,connreqpassword)的选择:
if(ACSOverride==true || (ACSOverride==false && ACSUrl in NonVol=="http://10.10.10.10:8080/acs"))
CM Config > NonVol
else if(ACSOverride==false && ACSUrl in NonVol!="http://10.10.10.10:8080/acs")
!NonVol > CM Config
如果ACSUrl中使用"[]"包含IP地址或者由DHCPv6 Option17得到的ACSUrl,则尝试首先使用IPv6发起连接.
4. TR069具体实现
4.1 TR069 Thread状态控制
// tr069thread有以下状态和消息类型:
enum
{
kStartThread = 0, //目前此msg仅自CLI
kStopThread, //同上
kStartClient,//同上
kStopClient, //同上
kSendInform, //同上
kIpAddressChanged //当相关的ip_stack ip发生变化时,会收到此消息类型
}QCommands;
typedef enum
{
kClientStarting = 0,
kClientReady, // Thread initialized and ready for Core
kClientRunning,
kClientStopping,
kClientStopped, // Client (core) is stopped, thread running
kExitingThread // Going away completely.
} ThreadState;
进程根据进程状态和收到的消息类型来控制tr69 client agent,start/stop agent的过程用下图简单描述:
4.2 Socket建立
建立2个socket,acsconnection socket用于连接ACS;acslisten socket用于接收acs的RPC.
// acs connection socket建立
wget.c wget_Connect()
\_www.c www_EstablishConnection()
\_BcmBfcTr69SocketApi.cpp BfcTr69Api_SocketAcsConnection()
\_BcmBfcTr69Thread::SocketAcsConnection()
// acs listen socket建立
tr69c_main() -> initTask()
\_informer.c initInformer() -> startACSComm() ->
startACSListener() -> startACScallback()
\_BfcTr69Api_SocketACSListenSocket()
\_BcmBfcTr69Thread