`${chargingStation.logPrefix()} ${moduleName}.handleRequestUpdateFirmware: Received UpdateFirmware request with requestId ${requestId.toString()} for location '${firmware.location}'`
)
- // C10: Validate signing certificate PEM format if present
+ // Reject malformed signing certificates up front so the firmware update path handles only parsable PEMs
if (isNotEmptyString(firmware.signingCertificate)) {
if (
!hasCertificateManager(chargingStation) ||
)
}
- // H10: Cancel any in-progress firmware update
+ // Cancel any in-progress firmware update; respond with AcceptedCanceled so the new request starts fresh
const stationState = this.getStationState(chargingStation)
if (stationState.activeFirmwareUpdateAbortController != null) {
const previousRequestId = stationState.activeFirmwareUpdateRequestId
): Promise<void> {
const { installDateTime, location, retrieveDateTime, signature } = firmware
- // H10: Set up abort controller for cancellation support
+ // Store the abort controller so a subsequent UpdateFirmware can cancel this in-progress update
const abortController = new AbortController()
const stationState = this.getStationState(chargingStation)
stationState.activeFirmwareUpdateAbortController = abortController
const checkAborted = (): boolean => abortController.signal.aborted
- // C12: If retrieveDateTime is in the future, send DownloadScheduled and wait
+ // Delay the download until retrieveDateTime; inform the CSMS via DownloadScheduled first
const now = Date.now()
const retrieveTime = convertToDate(retrieveDateTime)?.getTime() ?? now
if (retrieveTime > now) {
await sleep(OCPP20Constants.FIRMWARE_STATUS_DELAY_MS)
if (checkAborted()) return
- // H9: If firmware location is empty or malformed, send DownloadFailed and stop
+ // Empty or malformed firmware location: simulate the L01.FR.30 download retries, then emit DownloadFailed and stop
if (isEmpty(location) || !this.isValidFirmwareLocation(location)) {
// L01.FR.30: Simulate download retries before reporting DownloadFailed
const maxRetries = retries ?? 0
)
}
- // C12: If installDateTime is in the future, send InstallScheduled and wait
+ // Delay the install until installDateTime; inform the CSMS via InstallScheduled first
if (installDateTime != null) {
const currentTime = Date.now()
const installTime = convertToDate(installDateTime)?.getTime() ?? currentTime
requestId
)
- // H11: Send SecurityEventNotification for successful firmware update
+ // Send SecurityEventNotification after a successful firmware update
this.sendSecurityEventNotification(
chargingStation,
'FirmwareUpdated',
await flushMicrotasks()
assert.strictEqual(sentRequests[3].payload.status, OCPP20FirmwareStatusEnumType.Installed)
- // H11: SecurityEventNotification for FirmwareUpdated
+ // Expect SecurityEventNotification of type FirmwareUpdated on successful install
assert.strictEqual(sentRequests.length, 5)
assert.strictEqual(
sentRequests[4].command,
await flushMicrotasks()
assert.strictEqual(sentRequests[4].payload.status, OCPP20FirmwareStatusEnumType.Installed)
- // H11: SecurityEventNotification after Installed
+ // Expect SecurityEventNotification to be emitted after the Installed status
assert.strictEqual(sentRequests.length, 6)
assert.strictEqual(
sentRequests[5].command,