mirror of
https://dev.iopsys.eu/bbf/icwmp.git
synced 2026-01-28 01:27:16 +01:00
410 lines
17 KiB
Markdown
410 lines
17 KiB
Markdown
# CWMP Agent
|
|
|
|
icwmp is a client implementation of [TR-069/CWMP](https://cwmp-data-models.broadband-forum.org/) protocol.
|
|
|
|
It is written in C programming language and depends on a number of libraries of OpenWrt for building and running.
|
|
|
|
## Good to Know
|
|
|
|
The icwmp client is :
|
|
* Tested with several ACS such as **Axiros**, **AVSytem**, **GenieACS**, **OpenACS**, etc...
|
|
* Supports all required **TR069 RPCs**.
|
|
* Supports all DataModel of TR family such as **TR-181**, **TR-104**, **TR-143**, **TR-157**, etc...
|
|
* Supports all types of connection requests such as **HTTP**, **XMPP**, **STUN**.
|
|
* Supports integrated file transfer such as **HTTP**, **HTTPS**, **FTP**.
|
|
|
|
## Configuration File
|
|
|
|
The `icwmp` UCI configuration is located in **'/etc/config/cwmp'**, and contains 3 sections: **'acs'**, **'cpe'** and **'lwn'**.
|
|
|
|
```bash
|
|
config acs 'acs'
|
|
option userid 'iopsys'
|
|
option dhcp_discovery 'enable'
|
|
option compression 'Disabled'
|
|
option retry_min_wait_interval '5'
|
|
option retry_interval_multiplier '2000'
|
|
|
|
config cpe 'cpe'
|
|
option interface 'eth0.1'
|
|
option default_wan_interface 'wan'
|
|
option userid 'iopsys'
|
|
option exec_download '0'
|
|
|
|
config lwn 'lwn'
|
|
option enable '1'
|
|
option hostname ''
|
|
option port ''
|
|
```
|
|
|
|
> Note: icwmp depends on usp.raw for all datamodel parameters, some `DeviceId` related parameters can be overwritten by writing them directly on `/etc/config/cwmp` file.
|
|
|
|
```bash
|
|
uci set cwmp.cpe.manufacturer="ABC"
|
|
uci set cwmp.cpe.manufacturer_oui="XXX"
|
|
uci set cwmp.cpe.product_class="TEST_CLASS"
|
|
uci set cwmp.cpe.serial_number="1234567890"
|
|
uci set cwmp.cpe.software_version="X.Y.Z"
|
|
uci set cwmp.cpe.model_name="MODELXXX"
|
|
uci set cwmp.cpe.description="This is a test device"
|
|
uci commit cwmp
|
|
```
|
|
> Complete UCI for `cwmp` configuration available in [link](./docs/api/uci.cwmp.md) or [raw schema](./schemas/uci/cwmp.json)
|
|
|
|
## RPCs Method supported
|
|
|
|
The following tables provides a summary of all methods, and indicates the conditions under which implementation of each RPC method defined in Annex A is `REQUIRED` or `OPTIONAL`.
|
|
|
|
### Methods for CPE responding
|
|
|
|
| Method name | CPE requirement | Supported |
|
|
| ------------------------ | --------------- | --------- |
|
|
| `GetRPCMethods` | `REQUIRED` | `Yes` |
|
|
| `SetParameterValues` | `REQUIRED` | `Yes` |
|
|
| `GetParameterValues` | `REQUIRED` | `Yes` |
|
|
| `GetParameterNames` | `REQUIRED` | `Yes` |
|
|
| `SetParameterAttributes` | `REQUIRED` | `Yes` |
|
|
| `GetParameterAttributes` | `REQUIRED` | `Yes` |
|
|
| `AddObject` | `REQUIRED` | `Yes` |
|
|
| `DeleteObject` | `REQUIRED` | `Yes` |
|
|
| `Reboot` | `REQUIRED` | `Yes` |
|
|
| `Download` | `REQUIRED` | `Yes` |
|
|
| `ScheduleDownload` | OPTIONAL | `Yes` |
|
|
| `Upload` | OPTIONAL | `Yes` |
|
|
| `FactoryReset` | OPTIONAL | `Yes` |
|
|
| `GetQueuedTransfers` | OPTIONAL | No |
|
|
| `GetAllQueuedTransfers` | OPTIONAL | No |
|
|
| `CancelTransfer` | OPTIONAL | `Yes` |
|
|
| `ScheduleInform` | OPTIONAL | `Yes` |
|
|
| `ChangeDUState` | OPTIONAL | `Yes` |
|
|
| `SetVouchers` | OPTIONAL | No |
|
|
| `GetOptions` | OPTIONAL | No |
|
|
|
|
|
|
### Methods for CPE calling
|
|
|
|
| Method name | CPE requirement | Supported |
|
|
| --------------------------------- | --------------- | --------- |
|
|
| `GetRPCMethods` | OPTIONAL | `Yes` |
|
|
| `Inform` | `REQUIRED` | `Yes` |
|
|
| `TransferComplete` | `REQUIRED` | `Yes` |
|
|
| `AutonomousTransferComplete` | OPTIONAL | No |
|
|
| `DUStateChangeComplete` | OPTIONAL | `Yes` |
|
|
| `AutonomousDUStateChangeComplete` | OPTIONAL | No |
|
|
| `RequestDownload` | OPTIONAL | No |
|
|
| `Kicked` | OPTIONAL | No |
|
|
|
|
|
|
## Concepts and Workflow
|
|
|
|
As indicated in the TR069 standard, the `icwmpd` starts automatically when the system is started. Then it reads the initial configuration from UCI and if configured connects to the ACS. ACS configuration in `icwmp` can be done manually by the admin using UCI or by operator using DHCP Option 43, and later it could start other sessions due to event causes.
|
|
|
|
Session workflow could be checked with sniffer packets tool such as Wireshark or `tcpdump`.
|
|
In addition `icwmpd` has a log file '/var/log/icwmpd.log', that describes the workflow. E.g. below you can find an abstract of a log file content:
|
|
|
|
```bash
|
|
24-12-2019, 10:21:18 [INFO] STARTING ICWMP with PID :7762
|
|
24-12-2019, 10:21:18 [INFO] Periodic event is enabled. Interval period = 180000s
|
|
24-12-2019, 10:21:18 [INFO] Periodic time is Unknown
|
|
24-12-2019, 10:21:18 [INFO] Connection Request server initiated with the port: 7547
|
|
24-12-2019, 10:21:18 [INFO] Start session
|
|
24-12-2019, 10:21:18 [INFO] ACS url: http://genieacs:7547
|
|
24-12-2019, 10:21:18 [INFO] Preparing the Inform RPC message to send to the ACS
|
|
24-12-2019, 10:21:18 [INFO] Send the Inform RPC message to the ACS
|
|
24-12-2019, 10:21:19 [INFO] Get the InformResponse message from the ACS
|
|
24-12-2019, 10:21:19 [INFO] Send empty message to the ACS
|
|
24-12-2019, 10:21:19 [INFO] Receive HTTP 204 No Content
|
|
24-12-2019, 10:21:19 [INFO] End session
|
|
24-12-2019, 10:21:19 [INFO] Waiting the next session
|
|
```
|
|
|
|
You could set the UCI config `cwmp.cpe.log_severity` option to `'DEBUG'` in order to show in details the cwmp log.
|
|
|
|
## icwmp uBus
|
|
|
|
`icwmpd` must be launched on startup after `ubusd`. It exposes some CWMP client RPC along with some debug utilities over UBUS. The `icwmpd` registers `tr069` namespaces with UBUS, that has below functionalities:
|
|
|
|
> Note: For more info on the `tr069` ubus schema see [link](./docs/api/tr069.md) or [raw schema](./schemas/ubus/tr069.json)
|
|
|
|
### tr069 ubus examples
|
|
The output shown in below examples are just for demonstration purpose, the actual output shall vary as per the cwmp configuration and state. The schema for UBUS is available at [link](./docs/api/tr069.md) or [raw schema](./schemas/ubus/tr069.json)
|
|
|
|
```bash
|
|
root@iopsys:~# ubus -v list tr069
|
|
'tr069' @aadff65c
|
|
"command":{"command":"String"}
|
|
"status":{}
|
|
"inform":{"GetRPCMethods":"Boolean","event":"String"}
|
|
root@iopsys:~#
|
|
```
|
|
|
|
Each object registered with the `'tr069'` namespace has a specific functionality.
|
|
|
|
- To get the status of cwmp client, use the `status` ubus method:
|
|
|
|
```bash
|
|
root@iopsys:~# ubus call tr069 status
|
|
{
|
|
"cwmp": {
|
|
"status": "up",
|
|
"start_time": "2021-07-29T09:29:02+02:00",
|
|
"acs_url": "http://genieacs:7547"
|
|
},
|
|
"last_session": {
|
|
"status": "success",
|
|
"start_time": "2021-07-29T09:29:59+02:00",
|
|
"end_time": "2021-07-29T09:30:00+02:00"
|
|
},
|
|
"next_session": {
|
|
"status": "waiting",
|
|
"start_time": "2021-07-29T09:59:59+02:00",
|
|
"end_time": "N/A"
|
|
},
|
|
"statistics": {
|
|
"success_sessions": 2,
|
|
"failure_sessions": 0,
|
|
"total_sessions": 2
|
|
}
|
|
}
|
|
root@iopsys:~#
|
|
```
|
|
|
|
- To trigger a new session to ACS with the event `'6 CONNECTION REQUEST'` or `'8 DIAGNOSTICS COMPLETE'`, etc.., use the `inform` ubus method with the appropriate `event` argument:
|
|
|
|
```bash
|
|
root@iopsys:~# ubus call tr069 inform '{"event":"6 connection request"}'
|
|
{
|
|
"status": 1,
|
|
"info": "Session started"
|
|
}
|
|
root@iopsys:~#
|
|
root@iopsys:~# ubus call tr069 inform '{"event":"8 diagnostics complete"}'
|
|
{
|
|
"status": 1,
|
|
"info": "Session started"
|
|
}
|
|
root@iopsys:~#
|
|
root@iopsys:~# ubus call tr069 inform '{"GetRPCMethods":"1"}'
|
|
{
|
|
"status": 1,
|
|
"info": "Session started"
|
|
}
|
|
root@iopsys:~#
|
|
```
|
|
|
|
- To reload the icwmpd config, use the `command` ubus method with `reload` argument:
|
|
|
|
```bash
|
|
root@iopsys:~# ubus call tr069 command '{"command":"reload"}'
|
|
{
|
|
"status": 1,
|
|
"info": "icwmpd config reloaded"
|
|
}
|
|
root@iopsys:~#
|
|
```
|
|
- To exit the icwmpd daemon, use the `command` ubus method with `exit` argument:
|
|
|
|
```bash
|
|
root@iopsys:~# ubus call tr069 command '{"command":"exit"}'
|
|
{
|
|
"status": 1,
|
|
"info": "icwmpd daemon stopped"
|
|
}
|
|
root@iopsys:~#
|
|
```
|
|
## icwmpd command line
|
|
|
|
icwmpd command line options are described with `--help` option as below:
|
|
|
|
```bash
|
|
root@iopsys:~# icwmpd --help
|
|
Usage: icwmpd [OPTIONS]
|
|
-b, --boot-event (CWMP daemon) Start CWMP with BOOT event
|
|
-g, --get-rpc-methods (CWMP daemon) Start CWMP with GetRPCMethods request to ACS
|
|
-c, --cli CWMP CLI
|
|
-h, --help Display this help text
|
|
-v, --version Display the version
|
|
```
|
|
|
|
## icwmpd CLI
|
|
|
|
The icwmpd CLI is a debug utility and can be invoked using -c (--cli) command line option.
|
|
|
|
Different options of this CLI are described with help command as below:
|
|
|
|
```bash
|
|
root@iopsys:~# icwmpd -c help
|
|
Valid commands:
|
|
help => show this help
|
|
get [path-expr] => get parameter values
|
|
get_names [path-expr] [next-level] => get parameter names
|
|
set [path-expr] [value] => set parameter value
|
|
add [object] => add object
|
|
del [object] => delete object
|
|
get_notif [path-expr] => get parameter notifications
|
|
set_notif [path-expr] [notification] => set parameter notifications
|
|
```
|
|
> Note: icwmpd CLI is a debug utility and hence it is advised to use for debug and development purpose only.
|
|
> icwmpd CLI utility is independent of icwmpd daemon.
|
|
|
|
icwmp CLI command success result is displayed in the terminal as following:
|
|
|
|
```bash
|
|
root@iopsys:~# icwmpd -c get Device.DeviceInfo.UpTime
|
|
Device.DeviceInfo.UpTime => 91472
|
|
root@iopsys:~# icwmpd -c set Device.WiFi.SSID.1.SSID wifi1_ssid
|
|
Set value is successfully done
|
|
Device.WiFi.SSID.1.SSID => wifi1_ssid
|
|
```
|
|
In the case of fault the result is displayed as following:
|
|
|
|
```bash
|
|
root@iopsys:~# icwmpd -c get Device.DeviceInfo.UpTme
|
|
Fault 9005: Invalid parameter name
|
|
root@iopsys:~# icwmpd -c set
|
|
Fault 9003: Invalid arguments
|
|
root@iopsys:~# icwmpd -c set Device.WiFi.SSID.1.SSID
|
|
Fault 9003: Invalid arguments
|
|
```
|
|
## SPV Response and restart services
|
|
In case icwmp receives from the ACS SetParameterValues Request, it will use the uspd setm_values ubus method for all requested parameters.
|
|
|
|
Basing on setm_values response the icwmp will do the following:
|
|
|
|
- in case of fault icwmp aborts the set of all parameters and then sends Response to the ACS with FAULT 9003 including all parameters faults as defined in TR069 standard.
|
|
- in case of success icwmp commits the set of all parameters, without applying them so without restarting services, and then sends a success Response to the ACS including the status code 1.
|
|
|
|
> - All restart services are done in the CWMP end session in order to prevent any session interruption.
|
|
> - icwmp always returns 1 as status value in case of success SPV because all restart services are done in the end session.
|
|
|
|
## icwmpd forced inform parameters
|
|
As per the cwmp inform requirements, cwmp client has list of parameters defined internally. The list contains below parameters:
|
|
|
|
| Parameter name |
|
|
| ---------------------------------------------- |
|
|
| Device.RootDataModelVersion |
|
|
| Device.DeviceInfo.HardwareVersion |
|
|
| Device.DeviceInfo.SoftwareVersion |
|
|
| Device.DeviceInfo.ProvisioningCode |
|
|
| Device.ManagementServer.ParameterKey |
|
|
| Device.ManagementServer.ConnectionRequestURL |
|
|
| Device.ManagementServer.AliasBasedAddressing |
|
|
|
|
In addition to the above defined forced inform parameters as specified in datamodel standard, icwmp gives the possibility to add other datamodel parameters as forced inform parameters, by defining them in a JSON file.
|
|
|
|
Additional inform parameters can be configured in a JSON file as below:
|
|
|
|
```bash
|
|
root@iopsys:~# cat /etc/icwmpd/inform.json
|
|
{
|
|
"forced_inform":[
|
|
"Device.DeviceInfo.X_IOPSYS_EU_BaseMACAddress",
|
|
"Device.DeviceInfo.UpTime"
|
|
]
|
|
}
|
|
root@iopsys:~#
|
|
```
|
|
And then the path of the JSON file can be set in the UCI option: `cwmp.cpe.forced_inform_json` like below:
|
|
|
|
```bash
|
|
root@iopsys:~# uci set cwmp.cpe.forced_inform_json=/etc/icwmpd/inform.json
|
|
root@iopsys:~# uci commit cwmp
|
|
root@iopsys:~# /etc/init.d/icwmpd restart
|
|
```
|
|
|
|
> - It is required to restart icwmp service after the changes to use the new forced inform parameters
|
|
> - This JSON file shouldn't contain duplicate parameters or parameters of the standard inform parameters specified in the datamodel
|
|
> - Forced inform parameters defined in JSON should be leaf elements
|
|
|
|
## Boot inform parameters
|
|
In addition to the above defined forced inform parameters as specified in datamodel standard and forced inform parameters specified by the customer in a json file (defined in previous section), icwmp gives also possibility to add Boot Inform parameter by defining them in a JSON file.
|
|
|
|
Boot inform parameters will appear in inform messages that includes '0 BOOTSTRAP' or '1 BOOT' events.
|
|
|
|
inform parameters can be configured in a JSON file as below:
|
|
|
|
```bash
|
|
root@iopsys:~# cat /etc/icwmpd/inform.json
|
|
{
|
|
"boot_inform":[
|
|
"Device.DeviceInfo.UpTime"
|
|
]
|
|
}
|
|
root@iopsys:~#
|
|
```
|
|
And then the path of the JSON file can be set in the UCI option: `cwmp.cpe.boot_inform_json` like below:
|
|
|
|
```bash
|
|
root@iopsys:~# uci set cwmp.cpe.boot_inform_json=/etc/icwmpd/inform.json
|
|
root@iopsys:~# uci commit cwmp
|
|
root@iopsys:~# /etc/init.d/icwmpd restart
|
|
```
|
|
> - It is required to restart icwmp service after the changes to use the new boot inform parameters
|
|
> - This JSON file shouldn't contain duplicate parameters or parameters of the standard inform parameters specified in the datamodel
|
|
> - Boot inform parameters defined in JSON should be leaf elements
|
|
> - Boot inform parameters appears only in BOOT or BOOTSTRAP inform message.
|
|
|
|
## icwmpd notifications
|
|
As per the cwmp notifications requirements, there is a list parameters specified in the standard that has forced notification type. Those parameters are defined internally in icwmp client. The list contains below parameters:
|
|
|
|
| Parameter name | Notification |
|
|
| ------------------------------------- |---------------|
|
|
| Device.DeviceInfo.SoftwareVersion | 2 |
|
|
| Device.DeviceInfo.ProvisioningCode | 2 |
|
|
|
|
According to the standard, if the ACS set new notification of one of those parameters so icwmp will return the CWMP fault 9009.
|
|
|
|
In addition to thos parameters, icwmp gives the possibility to set default notifications of some parameters that the customer choose using a json file, in order to permit icwmp to start with those parameters with default notification type.
|
|
The json file must respect following form:
|
|
|
|
```bash
|
|
root@iopsys:~# cat /etc/icwmpd/inform.json
|
|
{
|
|
"custom_notification": [
|
|
{
|
|
"parameter": "Device.Users.",
|
|
"notify_type": "2"
|
|
},
|
|
{
|
|
"parameter": "Device.WiFi.SSID.1.SSID",
|
|
"notify_type": "1"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
The location of this file should be specified in the uci config option: cwmp.cpe.custom_notify_json
|
|
```bash
|
|
root@iopsys:~# uci set cwmp.cpe.custom_notify_json=/etc/icwmpd/inform.json
|
|
root@iopsys:~# uci commit cwmp
|
|
root@iopsys:~# /etc/init.d/icwmpd restart
|
|
```
|
|
|
|
Contrary to forced parameters notifications, the ACS has privileges to set new notification type of those custom parameters.
|
|
|
|
>- The actual update doesn't support wildcard parameters. So parameter like Device.WiFi.SSID.*. will be skipped
|
|
>- The actual update doesn't support multiple json notify files
|
|
|
|
## Dependencies
|
|
|
|
To successfully build icwmp, the 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 |
|
|
| libwolfssl | https://github.com/wolfSSL/wolfssl | GPL-2.0 |
|
|
| libcurl | https://dl.uxnr.de/mirror/curl | MIT |
|
|
| libmicroxml | https://dev.freecwmp.org/microxml | LGPL 2.0 |
|
|
|
|
Runtime dependencies:
|
|
|
|
| Dependency | Link | License |
|
|
| ----------- | ------------------------------------------- | -------------- |
|
|
| ubus | https://git.openwrt.org/project/ubus.git | LGPL 2.1 |
|
|
| bbf | https://dev.iopsys.eu/iopsys/bbf.git | LGPLv2.1 |
|
|
| uspd | https://dev.iopsys.eu/iopsys/uspd.git | GPL v2.0 |
|
|
|
|
> icwmpd gets the datamodel from the DUT via ubus using uspd, and also it registers `tr069` ubus namespace to expose some debug and cwmp client rpc funtionalities, so it is required to start it after starting `ubusd` and `uspd`.
|