16 — TR-069 / GenieACS Integration¶
Overview¶
TR-069 (Technical Report 069) is the CWMP — CPE WAN Management Protocol — a standard defined by the Broadband Forum for remote management of customer-premises equipment (CPE). It allows an ISP to remotely configure, monitor, reboot, update firmware on, and provision routers, modems, and ONTs from a central Auto-Configuration Server (ACS). PyroRadius integrates with GenieACS, an open-source ACS server, to provide TR-069 device management capabilities.
What TR-069 / CWMP Is¶
Protocol Overview¶
CPE Device (customer's router/ONT)
│
│ HTTPS POST (SOAP/XML)
│ Inform message → session starts
▼
ACS Server (GenieACS)
│
│ Responds with GetParameterValues, SetParameterValues, etc.
│ Pushes configuration, reads device state
▼
CPE acknowledges, applies config, reports back
Key characteristics: - CPE initiates the connection (not the ACS). The CPE "phones home" to the ACS URL. - Communication uses SOAP over HTTP/HTTPS. - Sessions are short-lived: CPE connects, exchanges messages, disconnects. - CPE periodically re-connects (periodic inform interval, typically 300–3600 seconds). - ACS can queue tasks for the CPE to execute on next connect.
What Can Be Done via TR-069¶
| Operation | Description |
|---|---|
| Reboot | Restart the CPE device remotely |
| Factory Reset | Restore device to factory defaults |
| Set PPPoE Credentials | Push username and password to WAN interface |
| Set Bandwidth Limits | Configure upload/download rate limits on CPE |
| Firmware Update | Push firmware image URL, CPE downloads and flashes |
| Get Device Info | Read manufacturer, model, serial, firmware version |
| Get Connection Stats | Read WAN IP, uptime, connection status |
| Get WiFi Settings | Read/set SSID, password, channel |
| Set DNS | Configure DNS servers on CPE |
GenieACS¶
GenieACS is an open-source ACS server (Node.js) that implements the CWMP protocol. PyroRadius uses GenieACS's REST API (not its web UI) to interact with devices.
GenieACS Architecture¶
GenieACS Server
├── CWMP Endpoint (port 7547) — CPE devices connect here
├── REST API (port 7557) — PyroRadius uses this
├── NBI (North-Bound Interface, port 7557) — same as REST API
└── MongoDB — stores device state, tasks, faults
Environment Variable¶
ACS_ENABLED=true # Set to false to disable all TR-069 features
ACS_BASE_URL=http://genieacs-host:7557
ACS_USERNAME=admin # GenieACS REST API credentials (if auth enabled)
ACS_PASSWORD=your-acs-password
When ACS_ENABLED=false, all TR-069 UI elements are hidden and GenieAcsService methods return early without making API calls. This allows deploying PyroRadius without a GenieACS instance.
customer_acs_devices Table¶
Stores the link between a customer and their provisioned CPE device(s).
| Column | Type | Description |
|---|---|---|
id |
bigint PK | |
customer_id |
bigint FK | References customers.id |
device_id |
varchar | GenieACS device ID (format: OUI-ProductClass-SerialNumber) |
manufacturer |
varchar | Device manufacturer (e.g. TP-Link, ZTE, Huawei) |
oui |
varchar | Organizationally Unique Identifier (first 6 hex digits of MAC) |
product_class |
varchar | Device model class |
serial_number |
varchar | Device serial number |
status |
enum | provisioned, pending, error, offline |
last_inform |
timestamp | When device last connected to GenieACS |
firmware_version |
varchar | Current firmware version (read from device) |
wan_ip |
varchar | Current WAN IP assigned to device |
created_at |
timestamp | |
updated_at |
timestamp |
A customer can have multiple devices (e.g. main router + repeater). Each device has one row.
GenieAcsService Class¶
Handles all communication with the GenieACS REST API.
class GenieAcsService
{
private string $baseUrl;
private ?string $username;
private ?string $password;
public function isEnabled(): bool
// Returns (bool) env('ACS_ENABLED', false)
public function getDevice(string $deviceId): ?array
// GET /devices/<deviceId> → returns device object from GenieACS
public function listDevices(array $filters = []): array
// GET /devices?query=<json> → list devices matching filters
public function getDeviceParameters(string $deviceId, array $paths): array
// GET /devices/<deviceId>?projection=<paths> → read specific parameters
public function setParameter(string $deviceId, string $path, mixed $value): bool
// Creates a "setParameterValues" task via POST /tasks
public function reboot(string $deviceId): bool
// Creates a "reboot" task via POST /tasks
public function factoryReset(string $deviceId): bool
// Creates a "factoryReset" task via POST /tasks
public function pushFirmware(string $deviceId, string $firmwareUrl): bool
// Creates a "download" task with firmware URL
public function getDeviceFaults(string $deviceId): array
// GET /faults → returns fault list for device
public function matchDeviceToCustomer(string $deviceId): ?Customer
// Attempts to match device via PPPoE username parameter
}
Creating a Task (GenieACS Pattern)¶
GenieACS uses an asynchronous task queue. To set a parameter:
// POST http://genieacs:7557/devices/<deviceId>/tasks?timeout=3000&connection_request
$payload = [
'name' => 'setParameterValues',
'parameterValues' => [
['InternetGatewayDevice.WANPPPConnectionService.1.Username', $username, 'xsd:string'],
['InternetGatewayDevice.WANPPPConnectionService.1.Password', $password, 'xsd:string'],
]
];
The connection_request query parameter tells GenieACS to immediately ping the device to start a session (rather than waiting for the next periodic inform).
How CPE Provisioning Works¶
Full Provisioning Flow¶
1. CPE connects to ISP (factory default or after reset)
2. CPE sends CWMP Inform to GenieACS (port 7547)
3. GenieACS creates/updates device record in MongoDB
4. GenieACS notifies PyroRadius (via webhook or PyroRadius polls)
5. PyroRadius's GenieController::provision() runs:
a. Find customer matching device serial or PPPoE username
b. Create/update customer_acs_devices row
c. Queue setParameterValues task:
- PPPoE username
- PPPoE password
- WAN connection type = PPPoE
- DNS servers
- Bandwidth limits (if applicable)
6. GenieACS delivers task to CPE on next session
7. CPE applies configuration, connects with correct credentials
8. CPE status in customer_acs_devices → provisioned
Device Identification¶
GenieACS device IDs use the format: <OUI>-<ProductClass>-<SerialNumber>
Example: 00259E-EchoLifeHG8120-48575443C7AB1234
PyroRadius matches devices to customers by:
1. Looking up device_id in customer_acs_devices (if already linked).
2. If new device, reading the PPPoE username from InternetGatewayDevice.WANPPPConnectionService.*.Username and matching against customers.pppoe_username.
3. If no match found, device is listed as unprovisioned for manual assignment.
Tr069Controller¶
Handles the UI for TR-069 device management.
| Method | Route | Description |
|---|---|---|
index() |
GET /tr069 | List all ACS devices with status |
show() |
GET /tr069/{deviceId} | Device detail: parameters, faults, task history |
provision() |
POST /tr069/{deviceId}/provision | Push PPPoE credentials and config to device |
reboot() |
POST /tr069/{deviceId}/reboot | Queue reboot task |
factoryReset() |
POST /tr069/{deviceId}/factory-reset | Queue factory reset task |
updateFirmware() |
POST /tr069/{deviceId}/firmware | Queue firmware download task |
refreshParameters() |
POST /tr069/{deviceId}/refresh | Re-read all parameters from device |
unlink() |
DELETE /tr069/{deviceId}/unlink | Remove customer_acs_devices row (unassign from customer) |
GenieController¶
Handles the webhook/callback from GenieACS when a new device connects.
GenieACS can be configured to POST to this endpoint when a new device Informs. GenieController:
1. Receives device ID and basic device info.
2. Looks up customer_acs_devices for an existing link.
3. If new device: attempts auto-match to customer by PPPoE username.
4. If matched: runs automatic provisioning.
5. If unmatched: logs for manual review.
This enables zero-touch provisioning: when a customer connects a new router, it automatically gets configured without staff intervention.
TR-069 Parameter Paths by Device Type¶
Standard TR-098 (InternetGatewayDevice)¶
| Setting | Parameter Path |
|---|---|
| PPPoE Username | InternetGatewayDevice.WANPPPConnectionService.1.Username |
| PPPoE Password | InternetGatewayDevice.WANPPPConnectionService.1.Password |
| WAN Connection Type | InternetGatewayDevice.WANPPPConnectionService.1.ConnectionType |
| Upstream Bandwidth | InternetGatewayDevice.QueueManagement.Classification.1.TrafficClass.MaxRateDown |
| Device Info | InternetGatewayDevice.DeviceInfo.Manufacturer |
| Firmware Version | InternetGatewayDevice.DeviceInfo.SoftwareVersion |
| Serial Number | InternetGatewayDevice.DeviceInfo.SerialNumber |
Standard TR-181 (Device — newer standard)¶
| Setting | Parameter Path |
|---|---|
| PPPoE Username | Device.PPP.Interface.1.Username |
| PPPoE Password | Device.PPP.Interface.1.Password |
| Firmware Version | Device.DeviceInfo.SoftwareVersion |
Older devices use TR-098; newer devices (post-2012) use TR-181. GenieACS handles both. PyroRadius's provisioning code checks device model to determine which path prefix to use.
Current Status and Limitations¶
Enable/Disable¶
TR-069 features are controlled by the ACS_ENABLED environment variable. In production deployments without a GenieACS server, set ACS_ENABLED=false. All TR-069 menu items, controller methods, and background tasks will be skipped.
Known Limitations¶
| Limitation | Details |
|---|---|
| No real-time push | GenieACS is async; tasks execute on next CPE inform (up to periodic interval) |
| Device compatibility | Not all CPE devices implement TR-069 correctly; some have non-standard parameter paths |
| Connection Request | connection_request parameter forces immediate session but requires CPE to be reachable from ACS server (NAT can block this) |
| Faults not auto-cleared | If a task fails, the fault record stays in GenieACS until manually dismissed |
| No CWMP v1.2 features | Currently uses basic CWMP v1.0/v1.1 operations only |
| Bulk provisioning | Provisioning multiple devices at once is done sequentially, not in parallel |
Security Note¶
The GenieACS CWMP port (7547) and REST API port (7557) should never be exposed to the public internet: - Port 7547: accessible only from CPE devices (customer WAN IPs) - Port 7557: accessible only from the PyroRadius application server - Use firewall rules or a VPN to restrict access
Related Models and Relationships¶
Customer→hasManyCustomerAcsDeviceCustomerAcsDevice→belongsToCustomerNas(unrelated to ACS — RADIUS NAS, not TR-069)