# How do you upgrade firmware on a USP (TR-369) device?

Dodderware engineering team · Published 2026-10-28 · https://blog.dodderware.com/usp-firmware-upgrade/

[Leer en español](https://blog.dodderware.com/es/actualizacion-firmware-usp/)

> **Short answer:** In TR-369, a Controller upgrades firmware by invoking Download(), through an Operate message, on an instance of the Device.DeviceInfo.FirmwareImage table. The Agent downloads the file into that image slot and validates it, checksum included. A single-image device activates it at once with AutoActivate. A device with two or more images downloads to a non-active slot, then switches with Activate() or a reboot.

If you plan CPE firmware upgrades, sending the file is the easy part. The hard questions come after it: did the image
validate, did the device boot it, and what happens to the subscriber if it did not. TR-369 answers them in its theory of
operation for firmware, Appendix II, built around one data model table and two commands, `Download()` and `Activate()`.
This guide walks through it using only what the specification says.

## Where does USP keep a device’s firmware?

Firmware lifecycle management is one of the extensions TR-369 lists in its scope (§1.2.2), and it is kept apart from
the rest of the software on the device. USP software module management covers every piece of software “with the
exception of the primary firmware” (Appendix I.2). The primary firmware is managed through the Firmware Image Objects
of the data model instead.

Those objects form the table `Device.DeviceInfo.FirmwareImage.{i}.`, where each instance holds one image, and an
instance is active if it holds the firmware that is currently running (Appendix II.1). The appendix works with four
elements:

| Data model element                                   | What it does                                                            |
| ---------------------------------------------------- | ----------------------------------------------------------------------- |
| `Device.DeviceInfo.FirmwareImage.{i}.Download()`     | Downloads a file into that image instance and has the Agent validate it |
| `Device.DeviceInfo.FirmwareImage.{i}.Activate()`     | Switches the device to the image held in that instance                  |
| `Device.DeviceInfo.BootFirmwareImage`                | Points to the image instance the device should boot                     |
| `Device.DeviceInfo.FirmwareImage.{i}.BootFailureLog` | Records what went wrong when that image failed                          |

## How does a new image get onto the device?

The Controller invokes `Download()`, through an Operate message, on an instance of the firmware image table. The command
downloads the referenced file into that instance and makes the Agent validate it: “any normal system validate of a
firmware image”, plus the checksum the Controller supplied in the `Download()` command (Appendix II.1).

Which instance the Controller targets depends on the device (Appendix II.1):

- **One image.** The Controller invokes `Download()` on the active instance with the `AutoActivate` argument, so the
  new firmware is activated as soon as it has been downloaded. Such a device typically implements neither
  `BootFirmwareImage` nor `Activate()`.
- **Two or more images.** The Controller typically invokes `Download()` on a non-active instance, to preserve the
  current image “in case of an error while upgrading the firmware”.

1. **Download()** (Operate): Invoked on a non-active FirmwareImage instance, with the image checksum.
2. **Validate** (Agent): The Agent checks the image and its checksum. The result arrives as an OperationComplete notification.
3. **Switch images** (Operate)
   - Activate() on the instance
   - or BootFirmwareImage plus Reboot()
4. **Confirm the boot** (Notify)
   - Boot! with FirmwareUpdated
   - ValueChange on SoftwareVersion

*A firmware upgrade on a device with two or more images, from download to confirmed boot. Diagram by Dodderware, based on TR-369 Appendix II.1, II.2.1 and §7.6.3.3.*

Once a device holds several images that are downloaded, validated and available, a Controller can query which images
are on it, which one is active, and configure which one to activate. It then has two ways to switch (Appendix II.2.1):
set `Device.DeviceInfo.BootFirmwareImage` to the instance with the desired image and reboot the device with a `Reboot()`
command, or invoke `Activate()` against that instance.

## How does the Controller know the download finished?

`Download()` reports its result through the OperationComplete notification. The specification uses it as the example
of a command behind that notification (§7.6.4.2.5), and OperationComplete exists to signal that an asynchronous
operation finished, “either successfully or unsuccessfully” (§7.6.3.3).

Asynchronous operations follow a set pattern (§7.7.2):

1. The Agent creates an instance in its Request table and returns a reference to it in the Operate response. It
   removes that instance when the operation completes, whether it succeeded or failed.
2. A Controller that wants the result creates a Subscription with `NotificationType` set to OperationComplete and a
   `ReferenceList` that includes the path of the command.
3. When the operation completes, the Agent sends a Notify that includes the `command_key` the Controller chose in its
   Operate request. The notification carries either the output arguments or a `CommandFailure` with an error code and
   a message (§7.6.4.2.5).

A Controller can also cancel a request that is still in the table with `Device.LocalAgent.Request.{i}.Cancel()`
(§7.7.2). One detail matters for firmware: asynchronous operations are not expected to persist across a reboot of the
Agent, and a command still in process when the Agent reboots “is considered to have failed”, unless the command
description says it is retained (§7.7.2.1). Subscriptions and Notify are covered in
[USP notifications and subscriptions](https://blog.dodderware.com/usp-notifications-subscriptions/).

## How do you confirm the device booted the new image?

A successful download does not prove the device runs the new firmware. When switching images, the specification
recommends that the Controller subscribe to a ValueChange notification on `DeviceInfo.SoftwareVersion` or to the
`Boot!` event. If the software version has not changed, or the `FirmwareUpdated` argument of `Boot!` is false, the
device may have had problems booting the target image (Appendix II.2.1). In the specification’s own example, a `Boot!`
notification carries `Cause`, `CommandKey`, `ParameterMap` and `FirmwareUpdated` (§7.6.4.1).

The same signals work the other way round. If the version changes unexpectedly, or `FirmwareUpdated` is true when no
switch was planned, the device may have had problems booting a particular image (Appendix II.2.3).

Once the device is back, check the service as well as the version. On a fiber ONT, the first number to read is the
optical power: see [what RX power is healthy on a GPON ONT](https://blog.dodderware.com/gpon-ont-optical-power/).

## What happens when an upgrade fails?

This is where a second image earns its place. If a device cannot boot a target image, it can try another one (Appendix
II.2.3):

- With two images, it simply tries the alternate image, which ideally holds the previous version of the firmware.
- With more than two, it can try any of the other available images, ideally the previously known working firmware.

The device also has to leave a trail. If it boots an image other than the one `BootFirmwareImage` points to, it must not
change that parameter to point to the running image, because doing so “could make troubleshooting problems” with the
switch more difficult (Appendix II.2.3). The Controller can still see which image it asked for.

> **Did you know?**
>
> USP treats a lost Controller as a failed upgrade. If activating an image leaves the Agent unable to send messages to
> its Controller, or sending messages the Controller cannot understand, the device is expected to roll back to the
> previously activated image and add information to the failed image’s `BootFailureLog` (Appendix II.2.3).

## How do you upgrade a whole fleet in a short window?

Normally, the download and the switch both have to happen inside the maintenance window. Bandwidth limits may cap how
many devices can download at the same time, and the upgrade may then need several maintenance windows (Appendix
II.2.2).

Devices with more than one image change that. The provider can push the image to a set of devices at any point during
the day, then use a smaller maintenance window to switch them all, which the specification says can result in shorter
system-wide upgrades (Appendix II.2.2). Switching later also reduces the impact on the subscriber, and spreading the
download over the entire day, or over several days, can help minimize the impact on the provider’s network (Appendix
II).

> **Where DWS Support fits**
>
> DWS Support’s USP controller sends firmware downloads to Agents as USP Operate commands and updates device state from
> their OperationComplete notifications. Fleet upgrades run as campaigns that need approval before they start: canary
> first, then a ramp, then general availability, inside a maintenance window and under a rate limit, and any campaign
> can be paused or aborted. Images must be published before use and reach devices through short-lived tokenised URLs, and
> operators can flag known-bad firmware versions so a warning shows on the firmware and device pages.
>
> [See DWS Support](https://dodderware.com/products/dws-support/)

## Does firmware still matter as device software goes modular?

Yes, although the specification expects it to change less often. Operators and manufacturers are “moving away from
monolithic firmware images” toward modular software, which lets operators shorten device firmware versioning lead
times, “typically 12 to 18 months”, and update individual services independently of the overall firmware, including
quick patches for security issues (Appendix VI.1).

The primary firmware stays outside that model, managed through its own Firmware Image Objects (Appendix I.2). The base
image of the device still goes through `Download()` and `Activate()`. For the bigger picture of what TR-369 covers, read
[what is TR-369](https://blog.dodderware.com/what-is-tr-369/).

## Did you know?

- A Controller starts a firmware upgrade by invoking the Download() command, through an Operate message, on an instance of the Device.DeviceInfo.FirmwareImage table. (TR-369 Appendix II.1)
- The Agent validates every downloaded image, including the checksum the Controller supplied in the Download() command. (TR-369 Appendix II.1)
- On a device with two or more images, the new image normally goes to a non-active instance, so the running firmware survives a failed upgrade. (TR-369 Appendix II.1)
- If activating an image cuts the Agent off from its Controller, the device is expected to roll back to the previously activated image and log the failure in BootFailureLog. (TR-369 Appendix II.2.3)
- Operators move to modular device software partly to shorten firmware versioning lead times, “typically 12 to 18 months”. (TR-369 Appendix VI.1)

## Questions people ask

### What is the difference between Download() and Activate() in USP?

Download() fetches a firmware file into an instance of Device.DeviceInfo.FirmwareImage and has the Agent validate it. Activate() switches the device to an image that is already on it. Single-image devices use Download() with the AutoActivate argument instead and typically do not implement Activate().

### How does a Controller know that a USP firmware download finished?

The Controller subscribes to the OperationComplete notification for the command. When the operation ends, the Agent sends a Notify with the command key the Controller chose, carrying either output arguments or a CommandFailure with an error code.

### How do you confirm that a device booted the new firmware?

The specification recommends subscribing to a ValueChange on DeviceInfo.SoftwareVersion or to the Boot! event. If the version did not change, or the FirmwareUpdated argument of Boot! is false, the device may have had problems booting the target image.

### What happens if a USP firmware upgrade fails?

A device with several images can boot one of the others, ideally the last one known to work. If the new image breaks the Agent’s connection to its Controller, the device is expected to roll back to the previously activated image and record the failure in that image’s BootFailureLog.

### Can you download firmware during the day and switch it at night?

Yes, on devices with more than one image. The specification describes pushing the image at any time of day and switching all target devices inside a smaller maintenance window, which can shorten system-wide upgrades.

### Is firmware managed like the other software modules in USP?

No. USP software module management covers all software on the device except the primary firmware, which is managed through the Firmware Image Objects of the data model.

## Sources

- Broadband Forum, TR-369 – The User Services Platform, Issue 1 Amendment 5 (USP 1.5), January 2026.
- Dodderware, DWS Support product and engineering documentation.
- §1.2.2: Scope, including firmware lifecycle management
- Appendix II, II.1: Firmware management of devices with USP Agents, getting the image onto the device
- Appendix II.2.1, II.2.2, II.2.3: Switching images, delayed upgrades and recovering from a failed upgrade
- §7.6.3.3, §7.6.4.1, §7.6.4.2.5: The OperationComplete notification, the Boot! event example and OperationComplete fields
- §7.7.2, §7.7.2.1: Asynchronous operations, the Request table and persistence across reboots
- Appendix I.2: Software modules and the primary firmware
- Appendix VI.1: Software modularization and firmware versioning lead times
- DWS · Product brief: Firmware campaigns, image delivery and known-issue notices in DWS Support

[Read the TR-369 specification](https://usp.technology/specification/index.htm)

TR-369 © The Broadband Forum. All rights reserved. Quoted briefly and paraphrased for commentary; the diagrams are Dodderware’s own.

---

**Manage TR-069 and TR-369 devices from one console.** DWS Support brings every ONT and home router into one web console, whichever protocol it speaks: TR-069 through GenieACS or a built-in ACS, TR-369 through a native USP controller. Self-hosted on your infrastructure. [Request a demo](https://dodderware.com/products/dws-support/#get-started)
