Introduction

Mosaic Device Manager offers a scripting framework and a rich application programming interface (scripting API) for interacting with managed devices in the JavaScript programming language.

These JavaScript scripts utilize function calls and data structures which are made available through the scripting API.  The original motivation of these functions was to configure a managed device using the methods outlined in the TR-069 specification.

The scripting API functions provide a layer of abstraction to simplify accesses to both parameter values on managed devices (via TR-069) and settings values in the Device Manager database.

 

TR-069 Overview

TR-069 is a protocol defined by the Broadband Forum as a protocol for calling RPC methods from managed devices to management servers, and vice-versa.  A series of SOAP requests is made by the device and handled by the server in a session.  When work needs to be done in a session, Device Manager will create an engine which will execute actions, typically implemented in JavaScript.

In Mosaic Device Manager, actions are implemented by scripts.  These actions can be triggered in a variety of ways:

  • Manually, by using the ‘Action Log’ on the device summary screen
  • Enabling / Disabling services
  • Synchronization
  • Changing settings via the Northbound API
  • Events
  • Bulk Operations

The diagram below illustrates a typical, but simplified, scenario of a device informing, and executing two separate scripts in the same CWMP session.

In the above diagram, the first column represents the device interacting with the server.  The second column is the CWMP layer where Device Manager translates TR-069 into engine calls.  The third column represents the engine’s session thread which wakes up with every response from the device if a script is running.  There is a time out associated with waiting for the next wake up which is configurable.  The fourth column represents the scripts themselves.

References

See the following resources for more detail about the concepts in this document:

JavaScript Reference: Mozilla’s JavaScript language and API reference https://developer.mozilla.org/En/javascript
JavaScript Tutorial: W3 Schools https://www.w3schools.com/js/
TR-069 CPE WAN Management Protocol https://www.broadband-forum.org/technical/download/TR-069.pdf

Terminology

As described in TR-069 and TR-098, configuration data is represented as a “pathed” name (path elements separated by dots) associated with a value (having a predefined type, also defined in TR-069 and TR-098).  A name and value pair is called a property or parameter.  This dotted or “pathed” way of addressing data results in the data being represented/manipulated in a hierarchical “tree” manner.  Hence, a property name “path” leading to a tree leaf is represented by a name & value and is itself called a property, while a tree parent or object is a path with no value and has children which can themselves be properties or objects.

The confusion stems from the fact that parameter and object have slightly different meanings in JavaScript.  Hopefully the context of the discussions in these documents will clarify any confusion otherwise we’ll be more explicit about a TR-069 Object or a JavaScript Object.

 

Architectural Overview and Data

Your script, using the scripting API, runs in a system that is logically divided as follows (the boxes):

TR-069 TR-069 defines functions and mechanisms to manipulate the Device Properties (see below), and this scripting API provides a simplified layer that abstracts the TR-069 functions.
ACS Server side functions and mechanisms to manipulate a plethora of information on the ACS.  Also provides a framework for executing modules.
MODULES Scripts that implement the Sync Module Interface to provision devices directly from settings.
UTILITIES Other potentially useful functions and data for your script (e.g. logging).


The ovals in the above diagram call out the various data that is manipulated by each logical division.

Device Properties Read and written by the TR-069 functions.  Reside on the device and represent the configured behavior of the device. TR-069 style (get/set) methods with path parameter references are used to interact with the device’s data model. Paths on TR-098 based devices start with “InternetGatewayDevice.” while paths for TR-181 based devices start with “Device.”.
Settings Read and written by the ACS.  This data also represents the behavior of one or more devices but resides on the ACS.  Think of it as the data “master” which can be used to configure various device models (aka “interop”).  Starts with “Settings.”.  See also the MODULES section above.  Since this data does not reside on the device we do not use TR-069 style (get/set) methods to manipulate this data.  But there is an extra method to apply settings to a device.
Subscriber Read and written by the ACS.  Information about a subscriber.  Starts with “Subscriber.”  Since this data does not reside on the device we do not use TR-069 style (get/set) methods to manipulate this data.  Also contains the labels for the subscriber.
Device Info Read only by the ACS.  Not to be confused with Device Properties on the device.  Starts with “Device.”.  The Device Info contains the data received from the device’s inform in the current session.  It also contains the labels for the device.
Global

Read only on the ACS.  Define some behaviors of the ACS or a place to store some data that can later be copied into the settings (i.e. default settings).  Starts with “Global.”

 

Understanding the Device Data Model

TR-069 compliant devices expose their behavior through a defined data model organized into a tree. Common residential gateway data models include: TR-098 and TR-181. Parameters and objects within the data model are referenced by their “Path” and parameter values are encapsulated in Parameter Objects.

Path

Paths are used to reference parameter objects and properties in a devices data model. There are 4 types of paths that will be used in the get() and set() functions defined here. All have the type of a JavaScript string.

Path ::= PathProperty | PathObject | PathSelector.

PathProperty ::= does not end in a dot, specifies a path to a single property (not an object).

PathObject ::= ends in a dot, specifies a path to a single property that is an object.

PathSelector ::= Uses two special characters to specify a way to select multiple properties and/or objects.  Uses alteration (“|”) to specify multiple matches at the same depth of the path.  Uses {} to signify numeric indices, and hence specifies multiple PathObject paths (assumption: numerical indexes are always objects/parents).

Examples:

  • ”InternetGatewayDevice.LANDevice.1.LANEthernetInterfaceConfig.1.Enable” is a PathProperty that corresponds to a boolean value.
  • ”InternetGatewayDevice.LANDevice.1.LANEthernetInterfaceConfig.1.” is a PathObject (and has no value).
  • ”InternetGatewayDevice.LANDevice.{}.LANEthernetInterfaceConfig.{}.Enable|Status” is a PathSelector that corresponds to all of the Enable and Status properties on all available LAN Ethernet Interfaces on all available LAN Devices.

Parameter Object

The primary data structure used throughout is a Parameter.  It is simply a JavaScript associative array object with a well-defined structure to store a property, its value (if it exists) and any available metadata about the property.  Note that an associative array of these objects is returned from a get call.

Example

"InternetGatewayDevice.LANDevice.1.Hosts.Host.1.Active": {

values : 1,

writable : false,

attributes : {

notification : 0,

accessList : ["Subscriber"]

}

}

Multiple Parameters Object

Parameters are an associative array of Parameter objects which are always returned from get().  Note there is no predefined order among elements in a JavaScript associative array.

Example

{

"InternetGatewayDevice.LANDevice.1.Hosts.Host.1." : {

writable : false

// value, notify and access are undefined since they don't apply to objects.

},

"InternetGatewayDevice.LANDevice.1.Hosts.Host.1.Active" : {

values : 1,

writable : false,

attributes : {

notification : 0,

accessList : ["Subscriber"]

}

},

"InternetGatewayDevice.LANDevice.1.Hosts.Host.1.HostName" : {

value : "ada",

writable : true,

attributes : {

notification : 0,

accessList : ["Subscriber"]

}

},

"InternetGatewayDevice.LANDevice.1.Hosts.Host.1.IPAddress" : {

value : "192.168.1.2",

writable : true,

attributes : {

notification : 0,

accessList : ["Subscriber"]

}

}

}

MultiValue

Another data structure, used by the setMany and older get/set functions is a MultiValue. It is simply a JavaScript associative array object with a well defined structure to store (or set) zero or more properties. Property Paths (names) are keys into the array and property values are the array values.  Note that property names without property values might exist, in which case the associative array value is null.

 

Synchronization

See MODULES. Mosaic Device Manager uses a process called “Synchronization” to control how devices are configured. Before the device initiates contact with the ACS, a user can make changes to an alternate configuration in an abstracted data model called “Settings”.  Sections of this data model are associated with scriptable components called “script modules”.  A script can then be executed when the device informs which will iterate through each of the script modules, configuring the device with appropriate parameters.

A sync module is a scriptable library, managed by the sync engine, which knows how to implement the configuration changes on a particular device.  Its interface exposes the following things:

  • sync.syncApps() - function: Performs the actual synchronization.  This function returns the reboot behavior (complete, reboot at end of session, reboot immediately).  If a sync module reboots immediately, the sync engine will enqueue a script for the remaining sync modules.  If this sync module is re-entrant, this module will also be included.
  • includeInSync - property: Determines whether or not this sync module should be executed in this session.  For example, if a particular type of device is not supported, this would be false.
  • dependencies - property: A list of other sync modules which must be synchronized ahead of this one.
  • isConfigSync - property: This is true if the sync module uses the device’s config file to perform its configuration.  These occur last.
  • rebootAtSessionEnd - property: This is true if the sync module expects to require the device to reboot after the cwmp session has completed.
  • forcesReboot - property: This is true if the sync module expects to require the device to reboot immediately after the sync module has completed.

Below is a high-level sequence of how synchronization occurs.

 

Interoperability

Simply stated, every TR-069 device behaves differently. Scripts applicable to multiple device models from myriad vendors must be implemented defensively. Be mindful of the following issues (and others):

Encoding Data Types – Boolean Example

Devices often encode value data types differently. For instance, Boolean values of ‘Truth’ may be represented with values such as: “true”, “1”, “on”, “false”, “0”, “off”, etc.

useLibrary("tr069");

 

function truth() {

var truthTestParameter = "InternetGatewayDevice.ManagementServer.PeriodicInformEnable"

 

function values(t, f) {

return {

trueValue: t,

falseValue: f

};

}

 

switch (tr069.get(truthTestParameter)[truthTestParameter].value) {

case "0":

case "1": return values("1", "0");

case "true":

case "false": return values("true", "false");

case "on":

case "off": return values("on", "off");

}

}

Reboots

Updates of certain parameters may require a reboot for the change to take effect. This can vary by model and/or vendor.

The following example demonstrates a reboot after enabling IGMP on a typical Broadcom based device:

// Helper function to confirm parameter existence before reading function withParameterValue(parameter, fn) {

if (tr069.has(parameter))

fn(tr069.get(parameter)[parameter].value)

}

 

// Enable/disable IGMP on the default wan service for Broadcom based devices

function configureBroadcomIGMP(state) {

withParameterValue("InternetGatewayDevice.Layer3Forwarding.DefaultConnectionService", function(defaultService) {

withParameterValue(defaultService + ".X_BROADCOM_COM_IGMPEnabled", function(igmpEnabled) {

if (igmpEnabled != state) {

tr069.set(defaultService + ".X_BROADCOM_COM_IGMPEnabled", state)

reboot();

}

});

});

}

Another scenario possibly requiring a reboot is the creation and/or modification of WAN services. The following example:

  • Creates a bridged WAN service
  • Schedules a script to add the new bridged WAN service to a bridged interface grouping
  • Reboots the device to force the new WAN service to be activated

function preConfigureWAN() {

createWANService(); // Create the Bridged WAN service

runInNextSession("Configure Bridge"); // Schedule

rebootNow();

}

Session Abandonment

Some devices will (erroneously) abandon the current CWMP session when certain parameters change. WAN service related parameters (InternetGatewayDevice.WANDevice.{}.) and TR-069 Management settings (InternetGatewayDevice.ManagementServer.URL) are common culprits.

useLibrary("tr069");

 

function setManagementServerURL(url) {

tr069.set("InternetGatewayDevice.ManagementServer.URL", url);

terminateSession(); // remainder of scripts will run in the next session

}

Parameter Support

Not all devices support all parameters defined for the particular device type’s data model (e.g. TR-098, TR-181, etc.) and data model definitions can change based on model and/or vendor, or may not support newer revisions of the model. Many devices support vendor specific extensions that may or may not be enabled. Scripts should gracefully handle missing parameter support. The TR-069 has() function will check for the existence of a parameter.

useLibrary("tr069");

 

function withParameterValue(parameter, fnExists, fnMissing) {

if (tr069.has(parameter)) {

var value = tr069.get(parameter)[parameter].value;

fnExists(value);

}

else if (fnMissing) fnMissing();

}

 

withParameterValue("InternetGatewayDevice.LANDevice.1.IPInterface.1.X_BROADCOM_COM_IfName",

function(ifName) { log.info("interface name is: " + ifName); },

function() { log.warn("interface name could not be determined."); }

);

Another example of using tr069.has() to determine the existence of a parameter, is to locate where the device puts the parameter.

(end code) useLibrary(“tr069”, “underscore”);

 

function getWPAKeyPath(wlanPath) { return _([“KeyPassphrase”, “PreSharedKey.1.KeyPassphrase”, “PreSharedKey.1.PreSharedKey”]) .detect(function(name) {return tr069.has(wlanPath + “.”  + name)}); }

function setWPAKey(wlanPath, key) { var path = getWPAKeyPath(wlanPath); if (path) { tr069.set(path, key); } else { log.warn(“could not determine key property”); } } (end code)

Device Information Functions

In an effort to harmonize access to a device’s identifying information the following “interop” functions are provided to read a device’s manufacturer, model number/name and software version number.

useLibrary('interop');

 

// Determine the gateway's Manufacturer, Model and firmware version

var mfg = interop.getManufacturer();

var hwVers = interop.getHardwareVersion();

var swVers = interop.getSoftwareVersion();

Underscore

Mosaic Device Manager includes the Underscore.js library. This utility is helpful for simplifying more complicated algorithms and give more functional programming styles to the default JavaScript language and API.

useLibrary("tr069", "underscore");

 

function getExternalIPAddresses() {

var p = "InternetGatewayDevice.WANDevice.{}.WANConnectionDevice.{}.WANIPConnection|WANPPPConnection.{}.ExternalIPAddress";

return _(tr069.get(p)).pluck("value")

}