Firmware Management — Migration Guide
Use cases L01–L04 (Firmware Management). Perspective: CSMS Developer.
Created by tzi.app — your guide to migrating from OCPP 2.0.1 to OCPP 2.1.
1. Summary of Changes
High-Level Overview
| Area | Change Type | Impact |
|---|---|---|
| FirmwareType.location max length | Breaking | Increased from 512 to 2000 characters |
| PublishFirmwareRequest.location max length | Breaking | Increased from 512 to 2000 characters |
| PublishFirmwareStatusNotification location items | Breaking | Item max length increased from 512 to 2000 characters |
| customData fields added | Additive | New optional customData on all messages and nested types |
| statusInfo added to FirmwareStatusNotificationRequest | Additive | New optional field for richer status reporting |
| JSON Schema IDs introduced | Informational | New URN-based schema identifiers for all messages |
| Signature algorithm explicitly specified | Clarification | RSA-PSS or ECSchnorr with SHA256 now explicitly stated |
| New requirement L01.FR.32 | Additive | Defines reboot-to-activate behavior options |
| Cancellation rejection clarified | Clarification | CS MAY respond Rejected if it cannot cancel mid-install |
| Configuration variables formalized | Organizational | FileTransferProtocols and AllowNewSessionsPendingFirmwareUpdate documented |
| Error handling & edge cases expanded | Organizational | Comprehensive subsections for reboots, EVSE availability, security events |
2. Detailed Changes
2.1 FirmwareType.location — Max Length Increased (512 → 2000)
Affected messages: UpdateFirmwareRequest (L01, L02)
| Field | OCPP 2.0.1 | OCPP 2.1 |
|---|---|---|
firmware.location maxLength | 512 | 2000 |
Migration action: Update any URI length validation in your CSMS to accept up to 2000 characters. If your database column for firmware URIs is constrained to 512 characters, expand it.
2.2 PublishFirmwareRequest.location — Max Length Increased (512 → 2000)
Affected messages: PublishFirmwareRequest (L03)
| Field | OCPP 2.0.1 | OCPP 2.1 |
|---|---|---|
location maxLength | 512 | 2000 |
Migration action: Same as above — update URI length validation and storage for publish firmware locations.
2.3 PublishFirmwareStatusNotificationRequest.location Items — Max Length Increased
Affected messages: PublishFirmwareStatusNotificationRequest (L03)
| Field | OCPP 2.0.1 | OCPP 2.1 |
|---|---|---|
location array item maxLength | 512 | 2000 |
location array constraint | (none specified) | minItems: 1 (when status = Published) |
Migration action: Update validation and storage for Local Controller published URIs. Note the new minItems: 1 constraint when status = Published.
2.4 customData Field Added to All Messages
OCPP 2.1 introduces an optional customData field (type CustomDataType) on every request, response, and nested object in this section.
Affected messages/types:
UpdateFirmwareRequest / ResponseFirmwareStatusNotificationRequest / ResponsePublishFirmwareRequest / ResponsePublishFirmwareStatusNotificationRequest / ResponseUnpublishFirmwareRequest / ResponseFirmwareTypeStatusInfoType{
"vendorId": "com.example"
}Migration action: Update message schemas and JSON validators to accept the optional customData field. The CSMS response FirmwareStatusNotificationResponse can now optionally include customData (previously always {}). No action required if you don't use vendor-specific extensions — the field is optional.
2.5 statusInfo Added to FirmwareStatusNotificationRequest
| Field | OCPP 2.0.1 | OCPP 2.1 |
|---|---|---|
statusInfo in FirmwareStatusNotificationRequest | Not present | Optional (StatusInfoType) |
In OCPP 2.0.1, FirmwareStatusNotificationRequest only contained status and requestId. OCPP 2.1 adds an optional statusInfo field with reasonCode and additionalInfo, allowing Charging Stations to provide richer context about status transitions.
{
"status": "Downloading",
"requestId": 123,
"statusInfo": {
"reasonCode": "InProgress",
"additionalInfo": "Download at 45%"
}
}Migration action: Update your FirmwareStatusNotificationRequest handler to parse and log the optional statusInfo field. Consider surfacing additionalInfo in operator dashboards for better firmware update visibility.
2.6 JSON Schema IDs Introduced
OCPP 2.1 assigns formal URN-based JSON Schema IDs to all messages. These were not present in OCPP 2.0.1.
| Message | OCPP 2.1 Schema ID |
|---|---|
UpdateFirmwareRequest | urn:OCPP:Cp:2:2025:1:UpdateFirmwareRequest |
UpdateFirmwareResponse | urn:OCPP:Cp:2:2025:1:UpdateFirmwareResponse |
FirmwareStatusNotificationRequest | urn:OCPP:Cp:2:2025:1:FirmwareStatusNotificationRequest |
FirmwareStatusNotificationResponse | urn:OCPP:Cp:2:2025:1:FirmwareStatusNotificationResponse |
PublishFirmwareRequest | urn:OCPP:Cp:2:2025:1:PublishFirmwareRequest |
PublishFirmwareResponse | urn:OCPP:Cp:2:2025:1:PublishFirmwareResponse |
PublishFirmwareStatusNotificationRequest | urn:OCPP:Cp:2:2025:1:PublishFirmwareStatusNotificationRequest |
PublishFirmwareStatusNotificationResponse | urn:OCPP:Cp:2:2025:1:PublishFirmwareStatusNotificationResponse |
UnpublishFirmwareRequest | urn:OCPP:Cp:2:2025:1:UnpublishFirmwareRequest |
UnpublishFirmwareResponse | urn:OCPP:Cp:2:2025:1:UnpublishFirmwareResponse |
Migration action: If your CSMS performs JSON Schema validation, update schema references to the new 2.1 URNs.
2.7 retries Field Constraint Formalized
| Field | OCPP 2.0.1 | OCPP 2.1 |
|---|---|---|
retries in UpdateFirmwareRequest | integer (no constraint) | integer, >= 0 (0 = no retries) |
retries in PublishFirmwareRequest | integer (no constraint) | integer, >= 0 (0 = no retries) |
retryInterval in PublishFirmwareRequest | integer (no constraint) | integer, >= 0 |
Migration action: Add validation that retries and retryInterval are non-negative when constructing requests. The semantic meaning of 0 (no retries) is now explicit.
3. Firmware Signature Algorithm Explicitly Specified
| Aspect | OCPP 2.0.1 | OCPP 2.1 |
|---|---|---|
| Signature description | "digitally protected (signature over hash of firmware file)" | "RSA-PSS or ECSchnorr over the entire firmware file, with SHA256 for hash values" |
OCPP 2.0.1 requirement L01.FR.09 stated firmware should be "digitally protected" without specifying exact algorithms. OCPP 2.1 explicitly names the acceptable algorithms: RSA-PSS or ECSchnorr with SHA256.
Migration action: Verify your firmware signing toolchain uses RSA-PSS or ECSchnorr with SHA256. If you were using a different algorithm (e.g., PKCS#1 v1.5), update your signing process.
4. New Requirements & Clarifications
4.1 New Requirement L01.FR.32 — Reboot-to-Activate Behavior
OCPP 2.1 adds requirement L01.FR.32 which formalizes two acceptable patterns for reboot-to-activate:
| Option | Behavior |
|---|---|
| (a) Preferred | CS sends InstallRebooting, reboots, then sends Installed from the new firmware |
| (b) Alternative | CS sends Installed without an explicit InstallRebooting notification |
Migration action: No CSMS code changes needed — this formalizes existing behavior. Ensure your state machine accepts both patterns (which it should already if following 2.0.1 guidance).
4.2 Cancellation Rejection Clarified (L01.FR.27 / L02.FR.18)
OCPP 2.1 explicitly documents that a Charging Station MAY respond with Rejected to a new UpdateFirmwareRequest if it cannot cancel an ongoing update (e.g., already mid-install).
| Aspect | OCPP 2.0.1 | OCPP 2.1 |
|---|---|---|
| CS can reject new request during install | Implied | Explicitly stated (L01.FR.27 / L02.FR.18) |
Migration action: Ensure your CSMS handles a Rejected response to UpdateFirmwareRequest when another update is in progress. Consider implementing a retry-after-delay strategy.
5. Configuration Variables Formally Documented
OCPP 2.1 adds a dedicated section for configuration variables relevant to firmware management. While these variables existed in 2.0.1, they are now explicitly linked to firmware management behavior.
| Variable | Description | CSMS Action |
|---|---|---|
FileTransferProtocols | Protocols supported by the CS (HTTP, HTTPS, FTP, SFTP, FTPS) | Check before sending firmware URI — ensure the firmware.location protocol is supported |
AllowNewSessionsPendingFirmwareUpdate | If false, CS sets unused EVSEs to UNAVAILABLE during install wait | Be aware of EVSE availability impact during firmware updates |
Migration action: Consider querying FileTransferProtocols via GetVariablesRequest before initiating firmware updates to ensure protocol compatibility. Monitor StatusNotificationRequest for EVSE availability changes during firmware updates.
6. Error Handling & Edge Cases Expanded
OCPP 2.1 provides more detailed guidance on edge cases. While the underlying behavior is largely unchanged from 2.0.1, the following are now explicitly documented.
EVSE Availability During Firmware Update
New explicit guidance
- When
AllowNewSessionsPendingFirmwareUpdateisfalseor unset, the CS sets all unused EVSEs to UNAVAILABLE. - Any EVSE that becomes available before installation completes is also set to UNAVAILABLE.
- Expect
StatusNotificationRequestmessages marking EVSEs asUnavailable. - EVSEs return to normal after firmware update completes.
Installing Status May Be Omitted
Formalized (L01.FR.23)
- If the bootloader cannot send OCPP messages during a reboot-before-install, the
Installingstatus may be omitted. - The CSMS should not assume
Installingwill always be received.
Reboot Count Clarified
InstallRebooting can appear 0, 1, or 2 times during a single update:
| Count | Meaning |
|---|---|
| 0 | No reboot needed |
| 1 | Reboot before install OR reboot after install to activate |
| 2 | Reboot before AND after install |
Security Events Explicitly Linked
| Security Event | Trigger |
|---|---|
InvalidFirmwareSigningCertificate | Certificate validation failure (L01.FR.02) |
InvalidFirmwareSignature | Signature verification failure (L01.FR.03) |
FirmwareUpdated | Successful installation (L01.FR.31) |
Firmware Hosting Recommendations Expanded
- OCPP 2.1 adds: "Alternatively, encrypt the firmware file itself before hosting"
- OCPP 2.1 adds: "Secure the firmware when stored on a server or workstation"
Migration action: Review your CSMS firmware update state machine to handle all documented edge cases. No breaking changes, but the expanded guidance may reveal gaps in existing implementations.
7. Unchanged Between Versions
The following aspects remain identical between OCPP 2.0.1 and 2.1:
- Overall flow structure for L01, L02, L03, and L04
- Message names and directions
- UpdateFirmwareStatusEnumType values (Accepted, Rejected, AcceptedCanceled, InvalidCertificate, RevokedCertificate)
- FirmwareStatusEnumType values (all 13 statuses unchanged)
- PublishFirmwareStatusEnumType values (all 10 statuses unchanged)
- UnpublishFirmwareStatusEnumType values (Unpublished, NoFirmware, DownloadOngoing)
- FirmwareType field names and types (aside from location max length)
- signingCertificate max length (5500)
- signature max length (800)
- checksum max length (32) and MD5 requirement
- Core requirement IDs and their intent (L01.FR.*, L02.FR.*, L03.FR.*, L04.FR.*)
- Security event types emitted during firmware updates
- TriggerMessage behavior for firmware status polling (L01.FR.25, L01.FR.26, L03.FR.10, L03.FR.11)
8. Migration Checklist
Database
- Expand URI columns from 512 to 2000 characters (firmware location, publish location, published URIs)
Schema Validation
- Update JSON schemas to 2.1 versions (new URNs, new optional fields)
- Handle optional customData on all firmware management messages
- Handle optional statusInfo on FirmwareStatusNotificationRequest
- Ensure retries >= 0 when set in request construction
Firmware Signing
- Verify use of RSA-PSS or ECSchnorr with SHA256
State Machine
- Confirm Installing status is treated as optional (may be skipped)
- Confirm InstallRebooting is handled 0, 1, or 2 times per update
- Handle Rejected response when cancellation is not possible
Pre-Update Checks
- Consider querying
FileTransferProtocolsbefore initiating updates
Monitoring & Security
- Surface statusInfo.additionalInfo from firmware status notifications
- Log SecurityEventNotificationRequest events tied to firmware updates