# Provisioning of CWMP Agent through DHCP Server

If CPE receives DHCP option 43 in DHCP offer from upstream network it exposes the same in its UBUS method (e.g. `ifstatus wan`).

```bash
root@iopsys-44d43771b000:~# ifstatus wan
{
	...
	"data": {
		"vendorspecinf": "XXXXXXXXXXXXXXXXXXX"
	}
}
```

CWMP Agent uses DHCP option 43 for provisioning if CWMP and DHCP discovery is enabled in the device. ICWMPD ships a DHCP client hook script at `files/etc/udhcpc.user.d/udhcpc_icwmp_opt43.user` that is sourced by the udhcpc user hook on every DHCP event. It parses DHCP option 43 according to the TR-069 Annex G TLV encoding and writes the extracted values to UCI.

## Enabling DHCP discovery

DHCP discovery must be enabled in the `cwmp` UCI configuration:

```bash
uci set cwmp.acs.dhcp_discovery=1
uci commit cwmp
```

When `Device.ManagementServer.URL` is set by an ACS, DHCP discovery is disabled automatically.

## Option 43 TLV encoding (TR-069 Annex G)

The script expects vendor-specific information encoded as a sequence of TLV sub-options:

```
 Code   Len   Data item        Code   Len   Data item
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|  T1 |  n  |  d1 |  d2 | ... |  T2 |  n  |  D1 |  D2 | ... |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
```

| Sub-option | Code | Data type              | UCI field written                           |
| ---------- | ---- | ---------------------- | ------------------------------------------- |
| ACS URL    | 1    | ASCII string           | `cwmp.acs.dhcp_url`                         |
| Provisioning Code | 2 | ASCII string      | `cwmp.cpe.provisioning_code`                |
| Retry Min Wait Interval | 3 | 2-byte big-endian unsigned integer | `cwmp.acs.dhcp_retry_min_wait_interval` |
| Retry Interval Multiplier | 4 | 2-byte big-endian unsigned integer | `cwmp.acs.dhcp_retry_interval_multiplier` |

If the data does not begin with a valid sub-option code (1–4), the entire option 43 value is treated as a plain ASCII ACS URL.

## Security

By default the script only accepts `https://` ACS URLs. To allow plain HTTP URLs (not recommended in production):

```bash
uci set cwmp.acs.insecure_enable=1
uci commit cwmp
```

## UCI fields updated by the script

The script reads from and writes to `/etc/config/cwmp`. Fields written on a successful DHCP event:

| UCI path                                    | Description                                  |
| ------------------------------------------- | -------------------------------------------- |
| `cwmp.acs.dhcp_url`                         | ACS URL received via DHCP                    |
| `cwmp.acs.dhcp_retry_min_wait_interval`     | Minimum session retry wait interval (seconds)|
| `cwmp.acs.dhcp_retry_interval_multiplier`   | Session retry interval multiplier            |
| `cwmp.cpe.provisioning_code`                | Provisioning code identifying the operator   |

After writing, the script commits the UCI changes via `ubus call uci commit '{"config":"cwmp"}'` and icwmpd picks up the new configuration on its next session.

!!! note

    If in any time ACS configures `Device.ManagementServer.URL` then DHCP discovery is disabled automatically.

## Retry when a DHCP-discovered ACS is unreachable

This retry logic runs in two situations:

- **Daemon startup** — `cwmp_config_load()` is called once from `cwmp_init()` and blocks until an HTTP connection to the ACS succeeds.
- **After a session failure** — `cwmp_config_load()` is called again at the start of each retry attempt when the previous TR-069 session ended with failure.

In both cases, if `cwmp.acs.dhcp_url` is set and the connection to it fails for **300 seconds**, icwmpd assumes the provisioned URL is stale and attempts to obtain a fresh one:

1. If `dhcp_discovery` was disabled, it is re-enabled so the next DHCP event will be processed.
2. The respective interface's protocol is determined via `ubus call network.interface status`.
3. **For DHCP interfaces** — icwmpd calls `ubus call network.interface renew` to trigger an immediate DHCP lease renewal. The udhcpc client re-runs its user hooks, including `udhcpc_icwmp_opt43.user`, which parses the new option 43 and writes any updated ACS URL and retry parameters back to UCI. icwmpd then picks up the updated configuration on its next config reload.
4. The 300-second timeout resets after the renewal request, and the cycle repeats until a reachable ACS URL is discovered.

```
icwmpd startup  OR  session failure retry
    │
    ├─ cwmp.acs.dhcp_url set? ──No──► connect to cwmp.acs.url (static)
    │
    Yes
    │
    ▼
try HTTP connection to dhcp_url
    │
    ├─ OK ──► proceed with TR-069 session; disable dhcp_discovery
    │
    └─ fail for 300 s
           │
           ├─ re-enable dhcp_discovery if needed
           │
           ├─ proto == dhcp ──► ubus network.interface renew
           │                        │
           │                        └─► udhcpc re-runs opt43 hook
           │                                │
           │                                └─► new dhcp_url written to UCI
           │
           └─ reset 300 s timer, retry
```
