fix: ensure inflight requests id cannot be duplicated
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Thu, 6 Jun 2024 20:37:49 +0000 (22:37 +0200)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Thu, 6 Jun 2024 20:37:49 +0000 (22:37 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
src/charging-station/ChargingStation.ts
src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts
src/charging-station/ocpp/1.6/OCPP16RequestService.ts
src/charging-station/ocpp/1.6/OCPP16ResponseService.ts
src/charging-station/ocpp/2.0/OCPP20IncomingRequestService.ts
src/charging-station/ocpp/2.0/OCPP20RequestService.ts
src/charging-station/ocpp/2.0/OCPP20ResponseService.ts

index 6b194f80fe36f931de071445ec44fdde4e9ed17b..5fad6d150a648ea9ba9a548955e56b5176b54162 100644 (file)
@@ -1925,7 +1925,7 @@ export class ChargingStation extends EventEmitter {
     }
     throw new OCPPError(
       ErrorType.PROTOCOL_ERROR,
-      `Cached request for message id ${messageId} ${getMessageTypeString(
+      `Cached request for message id '${messageId}' ${getMessageTypeString(
         messageType
       )} is not an array`,
       undefined,
@@ -1935,6 +1935,14 @@ export class ChargingStation extends EventEmitter {
 
   private async handleIncomingMessage (request: IncomingRequest): Promise<void> {
     const [messageType, messageId, commandName, commandPayload] = request
+    if (this.requests.has(messageId)) {
+      throw new OCPPError(
+        ErrorType.SECURITY_ERROR,
+        `Received message with duplicate message id '${messageId}'`,
+        commandName,
+        commandPayload
+      )
+    }
     if (this.stationInfo?.enableStatistics === true) {
       this.performanceStatistics?.addRequestStatistic(commandName, messageType)
     }
@@ -1959,7 +1967,7 @@ export class ChargingStation extends EventEmitter {
       // Error
       throw new OCPPError(
         ErrorType.INTERNAL_ERROR,
-        `Response for unknown message id ${messageId}`,
+        `Response for unknown message id '${messageId}'`,
         undefined,
         commandPayload
       )
@@ -1984,7 +1992,7 @@ export class ChargingStation extends EventEmitter {
       // Error
       throw new OCPPError(
         ErrorType.INTERNAL_ERROR,
-        `Error response for unknown message id ${messageId}`,
+        `Error response for unknown message id '${messageId}'`,
         undefined,
         { errorType, errorMessage, errorDetails }
       )
@@ -2069,10 +2077,10 @@ export class ChargingStation extends EventEmitter {
       }
       if (!(error instanceof OCPPError)) {
         logger.warn(
-          `${this.logPrefix()} Error thrown at incoming OCPP command '${
+          `${this.logPrefix()} Error thrown at incoming OCPP command ${
             commandName ?? requestCommandName ?? Constants.UNKNOWN_OCPP_COMMAND
             // eslint-disable-next-line @typescript-eslint/no-base-to-string
-          }' message '${data.toString()}' handling is not an OCPPError:`,
+          } message '${data.toString()}' handling is not an OCPPError:`,
           error
         )
       }
index 8852649f48bb60de8e76ce706a984bac3efa529b..fe25221050a8afa02e2f4b0091217c5726116b2b 100644 (file)
@@ -651,7 +651,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
         // Throw exception
         throw new OCPPError(
           ErrorType.NOT_IMPLEMENTED,
-          `'${commandName}' is not implemented to handle request PDU ${JSON.stringify(
+          `${commandName} is not implemented to handle request PDU ${JSON.stringify(
             commandPayload,
             undefined,
             2
index 1f3807ccdbd086660ab077d501562477cd91d3aa..6f772e0700d52f8c77280304f41ec7ae564ba7d4 100644 (file)
@@ -193,7 +193,7 @@ export class OCPP16RequestService extends OCPPRequestService {
     // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
     throw new OCPPError(
       ErrorType.NOT_SUPPORTED,
-      `Unsupported OCPP command '${commandName}'`,
+      `Unsupported OCPP command ${commandName}`,
       commandName,
       commandParams
     )
@@ -277,7 +277,7 @@ export class OCPP16RequestService extends OCPPRequestService {
         throw new OCPPError(
           ErrorType.NOT_SUPPORTED,
           // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
-          `Unsupported OCPP command '${commandName}'`,
+          `Unsupported OCPP command ${commandName}`,
           commandName,
           commandParams
         )
index 4306fc8f4f06d5daa3820a0b0e4e7cde374ad061..aec5d65f31ba851e199aa865b8b759694b81faea 100644 (file)
@@ -469,7 +469,7 @@ export class OCPP16ResponseService extends OCPPResponseService {
         // Throw exception
         throw new OCPPError(
           ErrorType.NOT_IMPLEMENTED,
-          `'${commandName}' is not implemented to handle response PDU ${JSON.stringify(
+          `${commandName} is not implemented to handle response PDU ${JSON.stringify(
             payload,
             undefined,
             2
index b1cd51fc8e935a7cebfe05a935a623ca4e41dc6c..4ae587d43f7de90a119341843b8682985c95dccc 100644 (file)
@@ -109,7 +109,7 @@ export class OCPP20IncomingRequestService extends OCPPIncomingRequestService {
         // Throw exception
         throw new OCPPError(
           ErrorType.NOT_IMPLEMENTED,
-          `'${commandName}' is not implemented to handle request PDU ${JSON.stringify(
+          `${commandName} is not implemented to handle request PDU ${JSON.stringify(
             commandPayload,
             undefined,
             2
index 1f1ed478f5679a6b2a063ffee98f40f2153979fd..38dbedf87f9b7f426507cfa8e92bf42ca5ef606d 100644 (file)
@@ -92,7 +92,7 @@ export class OCPP20RequestService extends OCPPRequestService {
     // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
     throw new OCPPError(
       ErrorType.NOT_SUPPORTED,
-      `Unsupported OCPP command '${commandName}'`,
+      `Unsupported OCPP command ${commandName}`,
       commandName,
       commandParams
     )
@@ -119,7 +119,7 @@ export class OCPP20RequestService extends OCPPRequestService {
         throw new OCPPError(
           ErrorType.NOT_SUPPORTED,
           // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
-          `Unsupported OCPP command '${commandName}'`,
+          `Unsupported OCPP command ${commandName}`,
           commandName,
           commandParams
         )
index e5fe290774975e77d08706f5af3587ac7757eead..9851d3339371d8fe3e47cb7a5dcaa835d7bcace0 100644 (file)
@@ -142,7 +142,7 @@ export class OCPP20ResponseService extends OCPPResponseService {
         // Throw exception
         throw new OCPPError(
           ErrorType.NOT_IMPLEMENTED,
-          `'${commandName}' is not implemented to handle response PDU ${JSON.stringify(
+          `${commandName} is not implemented to handle response PDU ${JSON.stringify(
             payload,
             undefined,
             2