Skip to content
Snippets Groups Projects

README

uspd is a TR-369/USP backend ubus daemon process to understand USP syntax defined in R-ARC.7 - R-ARC.12 and provide details.

Note 1: The command outputs shown in this readme are examples only, actual output may differ based on device and configuration. Note 2: Long command outputs are compressed for better readability

Project Components

Project consists of following components:

  • Application itself written in C programming language
  • Documentation in a Markdown format

Build Instructions

uspd is written using C programming language and depends on a number of components found in OpenWrt for building and running.

UCI Config

uspd requires a configuration file to provide more granular objects over ubus. Granularity is an optional feature of uspd, it can be skipped or set to level 0. The configuration file is an uci file /etc/config/uspd. Sample configuration file is provided below.

config uspd 'usp'
        option granularitylevel  '0'
	option loglevel  '2'

In the above uci, log_level can have below value:

log_level Meaning
0 Uspd will not log anything
1 Only errors will be loged
2 Only errors and warnings will be loged
3 Log everything except debug
4 Everything will be loged

For more info on the UCI uspd configuration see link

Ubus API

uspd needs to be started on startup after ubusd, as it exposes the USP functionality over ubus. By default(when granularity is not set in uci), uspd registers below two namespaces with ubus.

root@iopsys:~# ubus list |grep usp
usp
usp.raw

Each namespace provide the similar result but in different formats. usp namespace is to provide the output as required by USP or End User or in pretty format, whereas usp.raw namespace is to provide output in raw format, which can be used by other USP frontend applications(like: obuspa). Each namespace has below functionalities.

root@iopsys:~# ubus -v list usp
'usp' @deb5f751
        "dump_schema":{}
        "list_operate":{}
        "get":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean"}
        "object_names":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean"}
        "instances":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean"}
        "validate":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean"}
        "set":{"path":"String","value":"String","values":"Table","proto":"String","key":"String"}
        "operate":{"path":"String","action":"String","input":"Table","proto":"String"}
        "add_object":{"path":"String","proto":"String","key":"String"}
        "del_object":{"path":"String","proto":"String","key":"String"}
        "getm_values":{"paths":"Array","proto":"String","next-level":"Boolean"}
        "getm_names":{"paths":"Array","proto":"String","next-level":"Boolean"}
        "getm_attributes":{"paths":"Array","proto":"String","next-level":"Boolean"}
        "setm_attributes":{"paths":"Array","proto":"String"}
root@iopsys:~#
root@iopsys:~# ubus -v list usp.raw
'usp.raw' @ff9d104b
        "dump_schema":{}
        "list_operate":{}
        "get":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean"}
        "object_names":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean"}
        "instances":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean"}
        "validate":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean"}
        "set":{"path":"String","value":"String","values":"Table","proto":"String","key":"String"}
        "operate":{"path":"String","action":"String","input":"Table","proto":"String"}
        "add_object":{"path":"String","proto":"String","key":"String"}
        "del_object":{"path":"String","proto":"String","key":"String"}
        "getm_values":{"paths":"Array","proto":"String","next-level":"Boolean"}
        "getm_names":{"paths":"Array","proto":"String","next-level":"Boolean"}
        "getm_attributes":{"paths":"Array","proto":"String","next-level":"Boolean"}
        "setm_attributes":{"paths":"Array","proto":"String"}
root@iopsys:~#

Note: proto in each method specify the datamodel prototype('cwmp', 'usp') to use, if not provided default datamodel will be used.

The objects registered with the above namespaces can be called with appropriate parameters to perform a USP Get/Set/Operate/Add Object/Delete Object operation as below.

Overview

uspd provides below commands in pretty(usp) or raw(usp.raw) formats:

  1. Get
  2. Get multiple values
  3. Get multiple names
  4. Get multiple attributes
  5. Set
  6. Set multiple attributes
  7. Operate
  8. Add object
  9. Delete object
  10. Object names
  11. Instances
  12. Validate
  13. Dump schema
  14. List operate

It also provide a granularity layer which can be configured using uci parameter and provide additional ubus objects.

Granularity

Granularity feature is basically exposes the same USP functionality by registering additinal ubus namespaces to reduce the path length in ubus parameter. It is the number of levels upto which we want to shorten the length.

Ex:

  • When Granularity is set to 1, exposed ubus namespaces are
root@iopsys:~# ubus list|grep usp
usp
usp.Device.
usp.raw
  • When Granularity is set to 2, exposed ubus namespaces are
root@iopsys:~# ubus list|grep usp
usp
usp.Device.
usp.Device.Bridging.
usp.Device.DHCPv4.
usp.Device.DHCPv6.
usp.Device.DNS.
usp.Device.DeviceInfo.
usp.Device.DynamicDNS.
usp.Device.Ethernet.
usp.Device.Firewall.
usp.Device.Hosts.
usp.Device.IP.
usp.raw
root@iopsys:~#

These granular ubus objects provides the same functionality as of usp ubus namespace

root@iopsys:~# ubus -v list usp.Device.WiFi.
'usp.Device.WiFi.' @6fd43aca
        "dump_schema":{}
        "list_operate":{}
        "get":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean"}
        "object_names":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean"}
        "instances":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean"}
        "validate":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean"}
        "set":{"path":"String","value":"String","values":"Table","proto":"String","key":"String"}
        "operate":{"path":"String","action":"String","input":"Table","proto":"String"}
        "add_object":{"path":"String","proto":"String","key":"String"}
        "del_object":{"path":"String","proto":"String","key":"String"}
        "getm_values":{"paths":"Array","proto":"String","next-level":"Boolean"}
        "getm_attributes":{"paths":"Array","proto":"String","next-level":"Boolean"}
        "getm_names":{"paths":"Array","proto":"String","next-level":"Boolean"}
        "setm_attributes":{"paths":"Array","proto":"String"}
root@iopsys:~#

Registered method can be called with appropriate parameters, like:

root@iopsys:~# ubus call usp.Device. get '{"path":"Users."}'
{
        "Users": {
                "User": [
                        {
                                "Alias": "cpe-1",
                                "Enable": true,
                                "Language": "",
                                "Password": "",
                                "RemoteAccessCapable": true,
                                "Username": "user"
                        },
                        {
                                "Alias": "cpe-2",
                                "Enable": true,
                                "Language": "",
                                "Password": "",
                                "RemoteAccessCapable": true,
                                "Username": "support"
                        },
                        {
                                "Alias": "cpe-3",
                                "Enable": true,
                                "Language": "",
                                "Password": "",
                                "RemoteAccessCapable": true,
                                "Username": "admin"
                        }
                ],
                "UserNumberOfEntries": 3
        }
}
root@iopsys:~#
root@iopsys:~# ubus call usp.Device. getm_values '{"paths":["Device.Users.User.1.Username","Device.Users.User.2.Username"]}'
{
        "Device.Users.User.1.Username": "user",
        "Device.Users.User.2.Username": "support"
}
root@iopsys:~#

Get

API to query the value of a specific object.

To get the output in pretty format use usp ubus namespace:

root@iopsys:~# ubus call usp get '{"path":"Device.IP.Diagnostics.", "proto":"usp"}'
{
        "Diagnostics": {
                "IPv4DownloadDiagnosticsSupported": true,
                "IPv4PingSupported": true,
                "IPv4ServerSelectionDiagnosticsSupported": true,
                "IPv4TraceRouteSupported": true,
                "IPv6UploadDiagnosticsSupported": true,
                "UDPEchoConfig": {
                        "BytesReceived": 0,
                        "BytesResponded": 0,
                        "TimeFirstPacketReceived": "0",
                        "TimeLastPacketReceived": "0",
                        "UDPPort": 0
                }
        }
}
root@iopsys:~#
root@iopsys:~# ubus call usp get '{"path":"Device.IP.Diagnostics.", "proto":"cwmp"}'
{
        "Diagnostics": {
                "DownloadDiagnostics": {
                        "BOMTime": "0",
                        "DSCP": 0,
                        "DiagnosticsState": "None",
                        "DownloadDiagnosticMaxConnections": 1,
                        "TotalBytesSent": 0,
                        "TotalBytesSentUnderFullLoading": 0
                },
                "IPPing": {
                        "AverageResponseTime": 0,
                        "AverageResponseTimeDetailed": 0,
                        "DSCP": 0,
                        "DataBlockSize": 64,
                        "ProtocolVersion": "Any",
                        "SuccessCount": 0,
                        "Timeout": 1000
                },
                "IPv4DownloadDiagnosticsSupported": true,
                "IPv4PingSupported": true,
                "IPv4ServerSelectionDiagnosticsSupported": true,
                "IPv6UDPEchoDiagnosticsSupported": true,
                "IPv6UploadDiagnosticsSupported": true,
                }
        }
}
root@iopsys:~#
root@iopsys:~# ubus call usp get '{"path":"Device.Users."}'
{
        "Users": {
                "User": [
                        {
                                "Alias": "cpe-1",
                                "Enable": true,
                                "Language": "",
                                "Password": "",
                                "RemoteAccessCapable": true,
                                "Username": "user"
                        },
                        {
                                "Alias": "cpe-2",
                                "Enable": true,
                                "Language": "",
                                "Password": "",
                                "RemoteAccessCapable": true,
                                "Username": "support"
                        },
                        {
                                "Alias": "cpe-3",
                                "Enable": true,
                                "Language": "",
                                "Password": "",
                                "RemoteAccessCapable": true,
                                "Username": "admin"
                        }
                ],
                "UserNumberOfEntries": 3
        }
}

To get the output in raw format use usp.raw ubus namespace:

root@iopsys:~# ubus call usp.raw get '{"path":"Device.Users."}'
{
        "parameters": [
                {
                        "parameter": "Device.Users.User.1.Alias",
                        "value": "cpe-1",
                        "type": "xsd:string"
                },
                {
                        "parameter": "Device.Users.User.1.Enable",
                        "value": "1",
                        "type": "xsd:boolean"
                },
                {
                        "parameter": "Device.Users.User.1.Language",
                        "value": "",
                        "type": "xsd:string"
                },
                {
                        "parameter": "Device.Users.User.1.Password",
                        "value": "",
                        "type": "xsd:string"
                },
                {
  • For more info on the usp ubus API see link
  • For more info on the usp.raw ubus API see link

Get multiple values

API to get values to specific object, object name must be provided in paths paratermer array.

root@iopsys:~# ubus call usp getm_values '{"paths":["Device.Users.Us
er.1.","Device.Users.User.2."]}'
{
        "Device.Users.User.1.": {
                "Alias": "cpe-1",
                "Enable": "1",
                "Language": "",
                "Password": "",
                "RemoteAccessCapable": "1",
                "Username": "user"
        },
        "Device.Users.User.2.": {
                "Alias": "cpe-2",
                "Enable": "1",
                "Language": "",
                "Password": "",
                "RemoteAccessCapable": "1",
                "Username": "support"
        }
}

Get multiple attributes

API to get attributes to specific object, object name must be provided in paths paratermer array.

root@iopsys:~# ubus call usp getm_attributes '{"paths":["Device.Users.User.1.","Device.Users.User.2."]}'
{
        "Device.Users.User.1.": {
                "Alias": "0",
                "Enable": "0",
                "Language": "0",
                "Password": "0",
                "RemoteAccessCapable": "0",
                "Username": "0"
        },
        "Device.Users.User.2.": {
                "Alias": "0",
                "Enable": "0",
                "Language": "0",
                "Password": "0",
                "RemoteAccessCapable": "0",
                "Username": "0"
        }
}

Set

API to set value to specific object, object name must be provided in path parameter and vlaue in value paratermer.

root@iopsys:~# ubus call usp set '{"path":"Device.WiFi.SSID.[BSSID==\"34:E3:80:76:01:22\"].SSID", "value":"test-2g"}'
{
	"parameters": [
		{
			"status": true,
			"path": "Device.WiFi.SSID.1.SSID"
		}
	]
}

root@iopsys:~# ubus call usp get '{"path":"Device.WiFi.SSID.[BSSID==\"34:E3:80:76:01:22\"].SSID"}'?
{
        "SSID": [
                {
                        "SSID": "test-2g"
                }
        ]
}
  • For more info on the usp ubus API see link
  • For more info on the usp.raw ubus API see link

Set multiple attributes

API to set multiple attributes to specific object, object name must be provided in paths paratermer array.

root@iopsys:~# ubus call usp setm_attributes '{"paths":[{"path":"Device.DeviceIn
fo.SerialNumber","notify-type":"1","notify":"1"}]}'
{
        "parameters": [
                {
                        "path": "Device.DeviceInfo.SerialNumber"
                }
        ]
}

Add object

API to add new objects in multi-instance object

root@iopsys:~# ubus call usp add_object '{"path":"Device.Users.User"}'
{
        "status": true,
        "instance": "4"
}
  • For more info on the usp ubus API see link
  • For more info on the usp.raw ubus API see link

Delete object

API to delete an existing object from multi-instance object

root@iopsys:~# ubus call usp del_object '{"path":"Device.Users.User.[Username==\"user_2\"]."}'
{
	"parameters": [
		{
			"parameter": "Device.Users.User.2.",
			"status": true
		}
	]
}
  • For more info on the usp ubus API see link
  • For more info on the usp.raw ubus API see link

Operate

API to run operate/diagnostics commands as defined in TR-369

root@iopsys:~# ubus call usp operate '{"path":"Device.IP.Diagnostics.", "action":"IPPing","input":{"Host":"iopsys.eu"}}'
{
        "Results": [
                {
                        "path": "Device.IP.Diagnostics.IPPing",
                        "result": [
                                {
                                        "AverageResponseTime": 0,
                                        "AverageResponseTimeDetailed": 0,
                                        "FailureCount": 3,
                                        "MaximumResponseTime": 0,
                                        "MaximumResponseTimeDetailed": 0,
                                        "MinimumResponseTime": 9999,
                                        "MinimumResponseTimeDetailed": 999999999,
                                        "SuccessCount": 0
                                }
                        ]
                }
        ]
}

root@iopsys:~# ubus call usp.raw operate '{"path":"Device.IP.Diagnostics.", "action":"IPPing","input":{"Host":"iopsys.eu"}}'
{
        "Results": [
                {
                        "path": "Device.IP.Diagnostics.IPPing",
                        "parameters": [
                                {
                                        "parameter": "AverageResponseTime",
                                        "value": "0",
                                        "type": "xsd:unsignedInt"
                                },
                                {
                                        "parameter": "AverageResponseTimeDetailed",
                                        "value": "0",
                                        "type": "xsd:unsignedInt"
                                },
                                {
                                        "parameter": "FailureCount",
                                        "value": "3",
                                        "type": "xsd:unsignedInt"
                                },
                                {
                }
        ]
}

root@iopsys:~# ubus call usp operate '{"path":"Device.IP.Interface.[Name==\"wan\"].", "action":"Reset"}'
{
        "Results": [
                {
                        "path": "Device.IP.Interface.2.Reset",
                        "result": [
                                {

                                }
                        ]
                }
        ]
}

root@iopsys:~# ubus call usp.raw operate '{"path":"Device.IP.Interface.[Name==\"wan\"].", "action":"Reset"}'
{
        "Results": [
                {
                        "path": "Device.IP.Interface.2.Reset",
                        "parameters": [

                        ]
                }
        ]
}
  • For more info on the usp ubus API see link
  • For more info on the usp.raw ubus API see link

Instances

API to get the available instances of an multi-instance object. USP Instances method returns the registered instances.

root@iopsys:~# ubus call usp instances '{"path":"Device.IP.Interface.", "proto":"usp"}'
{
        "parameters": [
                {
                        "parameter": "Device.IP.Interface.1."
                },
                {
                        "parameter": "Device.IP.Interface.1.IPv4Address.1."
                },
                {
                        "parameter": "Device.IP.Interface.2."
                },
                {
                        "parameter": "Device.IP.Interface.3."
                },
                {
                        "parameter": "Device.IP.Interface.3.IPv4Address.1."
                },
                {
                        "parameter": "Device.IP.Interface.3.IPv6Address.1."
                },
                {
                        "parameter": "Device.IP.Interface.3.IPv6Prefix.1."
                }
        ]
}

List Operate

API to list all operate command objects

root@iopsys:~# ubus call usp list_operate
{
        "parameters": [
                {
                        "parameter": "Device.DHCPv4.Client.{i}.Renew()",
                        "type": "sync"
                },
                {
                        "parameter": "Device.DNS.Diagnostics.NSLookupDiagnostics()",
                        "type": "async"
                },
                {
                {
                        "parameter": "Device.IP.Diagnostics.IPPing()",
                        "type": "async"
                },
                {
                        "parameter": "Device.IP.Diagnostics.TraceRoute()",
                        "type": "async"
                },
                {
                        "parameter": "Device.IP.Diagnostics.UDPEchoDiagnostics()",
                        "type": "async"
                },
                {
                        "parameter": "Device.IP.Interface.{i}.Reset()",
                        "type": "sync"
                },
                {
                        "parameter": "Device.Reboot()",
                        "type": "sync"
                },
                {

Dump schema

API to dump all registered schema paths,

{
        "parameters": [
                {
                        "parameter": "Device.ATM.Link.{i}.",
                        "writable": "1",
                        "type": "xsd:object"
                },
                {
                        "parameter": "Device.ATM.Link.{i}.Alias",
                        "writable": "1",
                        "type": "xsd:string"
                },
                {
                        "parameter": "Device.ATM.Link.{i}.DestinationAddress",
                        "writable": "1",
                        "type": "xsd:string"
                },
                {
                        "parameter": "Device.ATM.Link.{i}.Enable",
                        "writable": "1",
                        "type": "xsd:boolean"
                },
                {
  • For more info on the usp ubus API see link
  • For more info on the usp.raw ubus API see link

Path syntax and possible error cases

Please note some error scenerios with the uspd.

  1. The path parameter value must start with 'Device.'. The command below doesn't have Device before path "Users.User."
root@iopsys:~# ubus call usp.raw get '{"path":"Users.User."}'
{
        "fault": 7026
}
  1. The path parameter must end with a '.' if the path element is not a leaf element e.g., Note that first two commands doesn't end with a '.' while the command with Alias is correct, due to Alias being the leaf element. To find correct schema path user can check with dump_schema option.
root@iopsys:~#
root@iopsys:~# ubus call usp get '{"path":"Device.Users.User.4"}'
{
        "fault": 7026
}
root@iopsys:~#
root@iopsys:~# ubus call usp get '{"path":"Device.Users.User"}'
{
        "fault": 9005
}
root@iopsys:~#
root@iopsys:~# ubus call usp get '{"path":"Device.Users.User.*"}'
{
        "fault": 7026
}
root@iopsys:~#
root@iopsys:~# ubus call usp get '{"path":"Device.Users.User.4.Alias"}'
{
        "Alias": "cpe-4"
}
  1. In path parameter value below, note that, the first search expression 'Type==Normal' is string which should be used as : Type=="Normal"
root@iopsys:~# ubus call usp get '{"path":"Device.IP.Interface.[Type==Normal].IPv4Address.[AddressingType==\"Static\"].IPAddress"}'
{
        "fault": 7008
}
root@iopsys:~#
root@iopsys:~# ubus call usp get '{"path":"Device.IP.Interface.[Type==\"Normal\"].IPv4Address.[AddressingType==\"Static\"].IPAddress"}'
{
        "Interface": [
                {
                        "IPv4Address": [
                                {
                                        "IPAddress": "2.0.0.3"
                                }
                        ]
                }
        ]
}
  1. The path parameter value must not have an empty search expression
root@iopsys:~# ubus call usp get '{"path":"Device.Users.User.[]."}'
{
        "fault": 9005
}
  1. The path parameter value must use proper '.' seperated path search expression. Note that a '.' is missing between User and *
root@iopsys:~# ubus call usp get '{"path":"Device.Users.User*."}'
{
        "fault": 7026
}
  1. The path parameter value must be a valid path schema, in example below SSID is used which is invalid schema element for Device.Users.User.{i}.
root@iopsys:~# ubus call usp get '{"path":"Device.Users.User.1.SSID"}'
{
        "fault": 7026
}
  1. Please note that in search expression, string comparison only work with "==" or "!=". Whereas in command below its =
root@iopsys:~# ubus call usp get '{"path":"Device.Users.User.[Username=\"user\"].Alias"}'
{
        "fault": 7008
}

Errors Codes

Error Code Meaning
7003 Message failed due to an internal error.
7004 Message failed due to invalid values in the request elements and/or failure to update one or more parameters during Add or Set requests.
7005 Message failed due to memory or processing limitations.
7008 Requested path was invalid or a reference was invalid.
7010 Requested Path Name associated with this ParamError did not match any instantiated parameters.
7011 Unable to convert string value to correct data type.
7012 Out of range or invalid enumeration.
7022 Command failed to operate.
7026 Path is not present in the data model schema.

Parallel calls

Uspd can also handle parallel object calls, e.g.,

root@iopsys:~# time ubus call usp.raw get '{"path":"Device."}' >/dev/null &
root@iopsys:~# time ubus call usp.raw get '{"path":"Device.Users."}' >/dev/null
real    0m 0.07s
user    0m 0.00s
sys     0m 0.00s
root@iopsys:~#
real     0m 1.86s
user    0m 0.05s
sys     0m 0.00s

[1]+  Done                       time ubus call usp.raw get "{\"path\":\"Device.\"}" >/dev/null
root@iopsys:~#

More example


root@iopsys:~# ubus call usp get '{"path":"Device.WiFi.SSID.*.SSID"}'
{
        "SSID": [
                {
                        "SSID": "NORRLAND-34E380760120"
                },
                {
                        "SSID": "NORRLAND-34E380760120"
                }
        ]
}

root@iopsys:~# ubus call usp get '{"path":"Device.WiFi.SSID.*.BSSID"}'
{
        "SSID": [
                {
                        "BSSID": "34:E3:80:76:01:22"
                },
                {
                        "BSSID": "34:E3:80:76:01:23"
                }
        ]
}

root@iopsys:~# ubus call usp get '{"path":"Device.WiFi.SSID.[BSSID==\"34:E3:80:76:01:22\"].SSID"}'
{
        "SSID": [
                {
                        "SSID": "NORRLAND-34E380760120"
                }
        ]
}

root@iopsys:~# ubus call usp get '{"path":"Device.IP.Interface.[Status==\"Up\"].IPv4Address.[AddressingType==\"DHCP\"].IPAddress"}'
{
        "Interface": [
                {
                        "IPv4Address": [
                                {
                                        "IPAddress": "192.168.0.96"
                                }
                        ]
                }
        ]
}

root@iopsys:~# ubus call usp get '{"path":"Device.IP.Interface.[Status==\"Up\"].IPv4Address.[AddressingType==\"DHCP\"&&Status==\"Up\"]."}'
{
        "Interface": [
                {
                        "IPv4Address": [
                                {
                                        "AddressingType": "DHCP",
                                        "Alias": "cpe-2",
                                        "Enable": true,
                                        "IPAddress": "192.168.0.96",
                                        "Status": "Up",
                                        "SubnetMask": "255.255.255.0",
                                        "X_IOPSYS_EU_FirewallEnabled": true
                                }
                        ]
                }
        ]
}

root@iopsys:~# ubus call usp get '{"path":"Device.IP.Interface.[Type==\"Normal\"&&Stats.PacketsSent<=500].IPv4Address.[AddressingType==\"Static\"].IPAddress"}'
{
        "Interface": [
                {
                        "IPv4Address": [
                                {
                                        "IPAddress": "192.168.1.1"
                                }
                        ]
                }
        ]
}

root@iopsys:~# ubus call usp get '{"path":"Device.WiFi.AccessPoint.[SSIDReference+.SSID==\"NORRLAND-34E380760120\"].AssociatedDevice.[Noise>15].SignalStrength"}
'
{
        "AccessPoint": [
                {
                        "AssociatedDevice": [
                                {
                                        "SignalStrength": -31
                                }
                        ]
                }
        ]
}


root@iopsys:~# ubus call usp get '{"path":"Device.WiFi.SSID.*.LowerLayers#1+.Name"}'
{
        {
                "Name": "wlan0",
                "Name": "wlan2"
        }
}



root@iopsys:~# ubus call usp get '{"path":"Device.Users.User.*.Username"}'
{
        "User": [
                {
                        "Username": "user"
                },
                {
                        "Username": "support"
                },
                {
                        "Username": "admin"
                }
        ]
}

root@iopsys:~# ubus call usp.raw set '{"path":"Device.IP.Diagnostics.IPPing.DiagnosticsState", "value":"Requested", "proto":"cwmp"}'
{
	"parameters": [
		{
			"path": "Device.IP.Diagnostics.IPPing.DiagnosticsState",
			"status": true,
			"flag": 16
		}
	]
}

root@iopsys:~# ubus call usp.raw set '{"path":"Device.Users.User.2.Username", "value":"abc", "proto":"cwmp"}'
{
	"parameters": [
		{
			"path": "Device.Users.User.2.Username",
			"status": true,
			"flag": 0
		}
	]
}

root@iopsys:~# ubus call usp.raw set '{"path":"Device.Users.User.2.Username", "value":"abc"}'
{
	"parameters": [
		{
			"path": "Device.Users.User.2.Username",
			"status": true
		}
	]
}

root@iopsys:~# ubus call usp.raw list_inform
{
	"parameters": [
		{
			"parameter": "Device.DeviceInfo.ActiveFirmwareImage",
			"value": "Device.DeviceInfo.FirmwareImage.1",
			"type": "xsd:string"
		},
		{
			"parameter": "Device.DeviceInfo.Description",
			"value": "Iopsys code analysis test simulator",
			"type": "xsd:string"
		},
		{
			"parameter": "Device.DeviceInfo.HardwareVersion",
			"value": "1.0",
			"type": "xsd:string"
		},
		{
			"parameter": "Device.DeviceInfo.Manufacturer",
			"value": "iopsys",
			"type": "xsd:string"
		},
		{
			"parameter": "Device.DeviceInfo.ManufacturerOUI",
			"value": "XXX",
			"type": "xsd:string"
		},
		{
			"parameter": "Device.DeviceInfo.ModelName",
			"value": "ModelName",
			"type": "xsd:string"
		},
		{
			"parameter": "Device.DeviceInfo.ProductClass",
			"value": "FirstClass",
			"type": "xsd:string"
		},
		{
			"parameter": "Device.DeviceInfo.ProvisioningCode",
			"value": "",
			"type": "xsd:string"
		},
		{
			"parameter": "Device.DeviceInfo.SerialNumber",
			"value": "000000001",
			"type": "xsd:string"
		},
		{
			"parameter": "Device.DeviceInfo.SoftwareVersion",
			"value": "IOPSYS-CODE-ANALYSIS",
			"type": "xsd:string"
		},
		{
			"parameter": "Device.ManagementServer.AliasBasedAddressing",
			"value": "true",
			"type": "xsd:boolean"
		},
		{
			"parameter": "Device.ManagementServer.ConnReqJabberID",
			"value": "",
			"type": "xsd:string"
		},
		{
			"parameter": "Device.ManagementServer.ConnReqXMPPConnection",
			"value": "",
			"type": "xsd:string"
		},
		{
			"parameter": "Device.ManagementServer.ConnectionRequestURL",
			"value": "",
			"type": "xsd:string"
		},
		{
			"parameter": "Device.ManagementServer.ParameterKey",
			"value": "",
			"type": "xsd:string"
		}
	]
}

root@iopsys:~# ubus call usp.raw init_notify '{"proto":"cwmp", "amd_version":5, "instance_mode": 0}'
root@iopsys:~#
  • For more info on the usp ubus API see link
  • For more info on the usp.raw ubus API see link

Concepts and Workflow

uspd internally uses libbbfdm to get the datamodel objects. On startup it parses the uci file to check if the granularity is set and then as per the granularity value it registers the required ubus namespaces.

When a ubus method is called it first checks the path parameter to identify if it has special USP syntax, if present it parses and determine the correct objects from libbbfdm, then proceeds with the Get/Set/Operate/Add/Del operation on the quilified objects.

So, uspd search for [[+*]+ in path expression, if it matches then segments the path and get the schema from libbbfdm and store it in a link-list, then it proceeds with the next segment to filter out the unneeded schema paths. It keeps on doing so till all the expressions are solved and it finally left with qualified objects. Once all the expressions are solved, it starts getting the values for qualified objects and store it in a stack to print the output in pretty format.

For operate command, it solve the path expression and then call bbf_operate from libbbfdm to execute the operate command.

uspd uses dm_entry_param_method API from libbbfdm to get the device tree schema and it's values.

In short, it covers/supports the new syntax introduced in TR-369 by using the existing datamodel available with libbbfdm.

Dependencies

Build-Time Dependencies

To successfully build uspd, following libraries are needed:

Dependency Link License
libuci https://git.openwrt.org/project/uci.git LGPL 2.1
libubox https://git.openwrt.org/project/libubox.git BSD
libubus https://git.openwrt.org/project/ubus.git LGPL 2.1
libjson-c https://s3.amazonaws.com/json-c_releases MIT
libbbfdm https://dev.iopsys.eu/iopsys/bbf.git LGPL 2.1

Run-Time Dependencies

In order to run the uspd, following dependencies are needed to be running/available before uspd.

Dependency Link License
ubusd https://git.openwrt.org/project/ubus.git LGPL 2.1
libbbfdm https://dev.iopsys.eu/iopsys/bbf.git LGPL 2.1

System daemon ubusd is used to expose the USP functionality over ubus.