Wednesday, October 22, 2014

My perl-cwmp patches are merged


Hello,
I've used perl-cwmp here and there. It is a nice, really small, really light and simple TR-069 ACS, with a very easy install and no heavy requirements. You can read the whole code for few minutes and you can make your own modifications. I am using it in a lot of small "special" cases, where you need something fast and specific, or a very complex workflow that cannot be implemented by any other ACS server.

However, this project has been stalled for a while. I've found that a lot of modern TR-069/CWMP agents do not work well with the perl-cwmp. 

There are quite of few reasons behind those problems:

- Some of the agents are very strict - they expect the SOAP message to be formatted in a specific way, not the way perl-cwmp does it
- Some of the agents are compiled with not so smart, static expansion of the CWMP xsd file. That means they do expect string type spec in the SOAP message and strict ordering

perl-cwmp do not "compile" the CWMP XSD and do not send strict requests nor interpretate the responses strictly. It does not automatically set the correct property type in the request according to the spec, because it never reads the spec. It always assume that the property type is a string.

To allow perl-cwmp to be fixed and adjusted to work with those type of TR-069 agents I've done few modifications to the code, and I am happy to announce they have been accepted and merged to the main code:

The first modification is that I've updated (according to the current standard) the SOAP header. It was incorrectly set and many TR069 devices I have tested (and basically all that worked with the Broadcom TR069 client) rejected the request.

The second modification is that all the properties now may have specified type. Unless you specify the type it is always assumed to be a string. That will allow the ACS to set property value of agents that do a strict set check.

InternetGatewayDevice.ManagementServer.PeriodicInformInterval: #xsd:unsignedInt#60

The #...# specifies the type of the property. In the example above, we are setting value of unsignedInt 60 to PeriodicInformInterval.

You can also set value to a property by reading a value from another property.
For that you can use ${ property name }

Here is an example how to set the PPP password to be the value of the Serial Number:

InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANPPPConnection.1.Password: ${InternetGatewayDevice.DeviceInfo.SerialNumber}

And last but not least - now you can execute small code, or external script and set the value of a property to the output of that code. You can do that with $[ code ]

Here is an example how to set a random value to the PeriodicInformInterval:

InternetGatewayDevice.ManagementServer.PeriodicInformInterval: #xsd:unsignedInt#$[60 + int(rand(100))]

Here is another example, how to execute external script that could take this decision:
InternetGatewayDevice.ManagementServer.PeriodicInformInterval: #xsd:unsignedInt#$[ `./externalscript.sh ${InternetGatewayDevice.LANDevice.1.LANEthernetInterfaceConfig.1.MACAddress} ${InternetGatewayDevice.DeviceInfo.SerialNumber}` ]

The last modification I've done is to allow the perl-cwmp to "fork" a new process when a TR-069 request arrives. It has been single threaded code, which mean the agents has to wait until the previous task is completed. However, if the TCP listening queue is full, or the ACS very busy, some of the agents will assume there is no response and timeout. You may have to wait for 24h (the default periodic interval for some vendors) until you get your next request. Now that can be avoided.

All this is very valuable for dynamic and automated configurations without the need of modification of the core code, just modifying the configuration file.

No comments:

Post a Comment