-
Notifications
You must be signed in to change notification settings - Fork 5
Introduction
A brief introduction to why Transformer was created and define some terminology that is used throughout the codebase.
Broadband Forum defined a protocol for network service providers to remotely manage deployed network devices (CPEs) from an Auto-Configuration Server (ACS). This protocol, named CPE WAN Management Protocol (CWMP), is described in Technical Report 069, or TR-069 for short. Several versions have been released; the latest one (Amendment 5 at the time of writing) can be downloaded from the BBF website.
As described in the specification the protocol is intended to be used for the following
- Auto-configuration and dynamic service provisioning
- Software/firmware image management
- Software module management
- Status and performance monitoring
- Diagnostics
Communication between CPE and ACS primarily happens using RPCs encoded in SOAP over HTTP(S). Most of the time it's the CPE who decides to contact the ACS (because of a periodic timer expiring, an earlier configured timestamp is reached, a notification needs to be delivered, ...) but the ACS can trigger a CPE by means of a Connection Request to setup a new connection.
When a connection with the ACS is established by the CPE it will initiate a new session by sending an Inform RPC to the ACS, who will acknowledge it with an InformResponse message. After that additional RPCs can be invoked.
Some RPCs used often by the ACS are:
- GetParameterValues: Retrieve configuration data from the device. How this data is organized and exposed is explained in the section on data models.
- SetParameterValues: Change configuration parameters on the device. The specification requires that all parameters sent in this RPC are either successfully changed or on error none are changed. In other words, a SetParameterValues RPC must be executed as a transaction.
- GetParameterNames: Allows the ACS to get a view on the available configuration parameters and whether they can be changed.
- GetParameterAttributes: Retrieve attributes associated with configuration parameters. Currently there are two attributes defined: notification and access list.
- SetParameterAttributes: Change the attributes associated with configuration parameters. By changing the notification attribute the ACS can subscribe to updates of those parameters. The CPE has to either report changes in the next Inform it sends (passive notification) or as soon as possible (active notification). By changing the access list attribute the ACS can grant or revoke access to configuration parameters for other management channels.
- AddObject: Add a new object instance to the configuration of the device.
- DeleteObject: Remove an existing object instance from the configuration of the device.
- Reboot: Perform a reboot of the device. This shouldn't happen immediately but at the end of the ongoing management session between the CPE and the ACS.
- FactoryReset: Reset the device to factory defaults.
- Download: Instruct the CPE to download a file from a given location. Several types of files are defined; the most commonly used are firmware upgrade image and vendor configuration file. The actual download and processing of the file should happen asynchronously from the ongoing session. After completion the CPE should contact the ACS to report the result.
- Upload: In this case the ACS asks the CPE to upload a certain file. The most commonly requested files are vendor configuration files and log files.
A GetParameterValues RPC sent by the ACS:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:cwmp="urn:dslforum-org:cwmp-1-1">
<SOAP-ENV:Header>
<cwmp:ID SOAP-ENV:mustUnderstand="1">11</cwmp:ID>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<cwmp:GetParameterValues>
<ParameterNames SOAP-ENC:arrayType="xsd:string[3]">
<string>InternetGatewayDevice.DeviceInfo.SoftwareVersion</string>
<string>InternetGatewayDevice.Layer3Forwarding.ForwardNumberOfEntries</string>
<string>InternetGatewayDevice.WANDevice.2.WANConnectionDevice.1.WANPPPConnection.1.ExternalIPAddress</string>
</ParameterNames>
</cwmp:GetParameterValues>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Example response by the CPE:
<soapenv:Envelope soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cwmp="urn:dslforum-org:cwmp-1-2">
<soapenv:Header>
<cwmp:ID soapenv:mustUnderstand="1">11</cwmp:ID>
</soapenv:Header>
<soapenv:Body>
<cwmp:GetParameterValuesResponse>
<ParameterList soap:arrayType="cwmp:ParameterValueStruct[03]">
<ParameterValueStruct><Name>InternetGatewayDevice.DeviceInfo.SoftwareVersion</Name><Value xsi:type="xsd:string">17.1.7590-0010000</Value></ParameterValueStruct>
<ParameterValueStruct><Name>InternetGatewayDevice.Layer3Forwarding.ForwardNumberOfEntries</Name><Value xsi:type="xsd:unsignedInt">12</Value></ParameterValueStruct>
<ParameterValueStruct><Name>InternetGatewayDevice.WANDevice.2.WANConnectionDevice.1.WANPPPConnection.1.ExternalIPAddress</Name><Value xsi:type="xsd:string">80.0.0.1</Value></ParameterValueStruct>
</ParameterList>
</cwmp:GetParameterValuesResponse>
</soapenv:Body>
</soapenv:Envelope>
The TR-069 document specifies the protocol and what the various RPCs do. The actual configuration data of the device and how it's organized (the data model) is defined in separate documents. There's a separate section on the BBF website that collects them all.
There are currently two root data models that are actively in use: the older InternetGatewayDevice:1 one (mainly governed by TR-098) and the newer Device:2 one (governed by TR-181). Each of them have seen several revisions; IGD is at the time of writing at version 1.14, while Device:2 is at 2.11.
The structure and semantics of the data models are defined in TR-106 (Amendment 7 is the latest at the time of writing). Also defined in TR-106 is an XML Schema used to define and validate data models.
In essence a data model is a hierarchically organized set of objects with their parameters starting at one root node. There's quite some metadata associated with these objects and parameters that refine what operations can be done on that object or parameter, what are allowed values, ...
Note that the specification (TR-181, TR-098) contains everything that is standardized. An actual device will most likely only support a subset of that: the "supported data model" of that device. At runtime based on the current configuration and state of the device it exposes an "instantiated data model"; this is what the ACS sees when interacting with the device. In Transformer we refer to this distinction as the set of objecttypes supported/implemented (the metadata) and the object instances.
As an example let's take a look at the TR-181 definition of the Device.IP.Interface.{i}.IPv4Address.{i}. objecttype:
- The fact that this objecttype ends with the instance placeholder {i}. means it's a multi-instance objecttype, i.e. there can be multiple object instances of this objecttype.
- This IPv4Address.{i}. objecttype is a child of the (multi-instance) Interface.{i}. objecttype, which in turn is a child of the single-instance IP objecttype. There are two variants of single-instance objecttypes: mandatory and optional. The former means the instance is always present in the instantiated data model, while the latter might or might not be present.
- The IPv4Address.{i}. objecttype is marked as writable. This means it should be possible for the user of the data model to add or remove instances.
The parameters of this objecttype are:
- The Enable parameter is defined as a writable boolean. Note that allowed boolean values are 0, 1, true and false.
- Status is a read-only string whose value is one of the values in the given enumeration (Disabled, Enabled, Error_Misconfigured or Error).
- IPAddress is a writable string of exactly 15 characters. While the HTML page of the specification shows this parameter as a string, the formal XML defines its type as IPv4Address which is derived from the primitive string type. Also, this parameter is marked as writable in the definition but in practice (as explained in the description) a modification of the parameter will only be accepted if another parameter (AddressingType) has a certain value (Static). This is an example of how not all constraints on a parameter can be formally defined in the XML.
- ...
In the formal XML description of the data model there are many more attributes attached to the objecttype and parameter definitions.
There are two aspects of addressing: first there's how the instances of a multi-instance objecttype are addressed; second there's how paths in the (instantiated) data model are interpreted.
Instances of a multi-instance objecttype are primarily assigned an object index (or instance number), starting from 1 for the first object under a specific parent object and ever increasing. As long as an object exists it must keep the same instance number, even across reboots of the device. If an object disappears or is deleted its index will also disappear. This can leave a hole in the numbering. For example, the Device.IP.Interface.{i}.IPv4Address.{i}. objecttype could have the following instantiated objects at a certain moment:
- Device.IP.Interface.1.IPv4Address.1.
- Device.IP.Interface.1.IPv4Address.2.
- Device.IP.Interface.2.IPv4Address.4.
- Device.IP.Interface.3.IPv4Address.1.
The downside of instance numbers is that an ACS can't a priori know which object instance has which number. That makes it difficult to create efficient generic provisioning scripts which leads to additional requirements for CPE vendors to implement some kind of "fixed" or "predictable" instance numbering. For example, one service provider wants the LAN interface to be on index 1 and the WAN interface on index 2; another service provider wants it the other way around... This has lead to the introduction of alias-based addressing: most multi-instance objecttypes get a writable Alias parameter and the value of this parameter can be used as instance identifier. For example, the four data model paths from the previous paragraph might also be written as:
- Device.IP.Interface.[lan].IPv4Address.[private10].
- Device.IP.Interface.[lan].IPv4Address.[private192].
- Device.IP.Interface.[wan-data].IPv4Address.[ppp].
- Device.IP.Interface.[wan-voice].IPv4Address.[cpe-5903].
The two types of instance identifiers - instance numbers and instance aliases - can be mixed freely in one path. Which brings us seamlessly to the various ways a path is interpreted. There are two main categories of paths: exact and partial.
- Exact paths always address a specific parameter of a specific object. When performing a GetParameterValues RPC on such a path the value of exactly that parameter is returned. Example: Device.IP.Interface.1.IPv4Address.1.IPAddress
- A partial path always ends with a dot . and addresses the subtree starting at the given path, the objecttype or the given object instance. Examples:
- A GetParameterValues RPC on Device.IP.Interface. will return all parameters of all Interface instances and their IPv4Address child instances.
- A GetParameterValues RPC on Device.IP.Interface.1. will return all parameters of that specific Interface instance and all its IPv4Address child instances.
- An AddObject RPC on Device.IP.Interface.[lan].IPv4Address. will create a new IPv4Address instance on that particular Interface object instance.
- Similarly a DeleteObject RPC on Device.IP.Interface.[lan].IPv4Address.1. will remove that particular IPv4Address object instance.
Knowing all of the above how can TR-069 be implemented on a device running OpenWrt or LEDE? A 'cwmpd' daemon will firstly have to implement the protocol itself. Secondly one of the standardized data models will have to be implemented. More specifically:
- The semantics of a data model have to adhere to what's described in TR-069 and TR-106.
- The various objecttypes and parameters have to be mapped to the actual data of the device. On OpenWrt/LEDE this means:
- UCI files in
/etc/config/
for the persistent configuration. - UCI files in
/var/state/
for some runtime state. - ubus for runtime state, statistics and events.
- Typical generic Linux sources of information like
/proc/
,/sys/
,/dev/
, ... - ...
- UCI files in
Instead of implementing the data model in the cwmpd daemon it seems more useful to do this in a separate daemon so it can be reused by other clients, for example the web interface.
Transformer is exactly that: a daemon that provides a data model mapping framework primarily targeting TR-069. While it provides support for accessing UCI and ubus this is not part of the core and as such Transformer can easily be run on non-OpenWrt/LEDE devices.