Skip to content

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.

POST /genie/inform

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


  • CustomerhasMany CustomerAcsDevice
  • CustomerAcsDevicebelongsTo Customer
  • Nas (unrelated to ACS — RADIUS NAS, not TR-069)