Fix connector Id validation in TriggerMessage handling
[e-mobility-charging-stations-simulator.git] / src / charging-station / ocpp / 1.6 / OCPP16IncomingRequestService.ts
index 52751b4bac994ddfc9e2bc0f68746093b7c2bb55..dd1018a07d0bd49b3bae29547af8fc7aae12f0b6 100644 (file)
@@ -28,12 +28,12 @@ import {
   DiagnosticsStatusNotificationRequest,
   GetConfigurationRequest,
   GetDiagnosticsRequest,
-  MessageTrigger,
   OCPP16AvailabilityType,
   OCPP16BootNotificationRequest,
   OCPP16ClearCacheRequest,
   OCPP16HeartbeatRequest,
   OCPP16IncomingRequestCommand,
+  OCPP16MessageTrigger,
   OCPP16RequestCommand,
   OCPP16StatusNotificationRequest,
   OCPP16TriggerMessageRequest,
@@ -281,8 +281,8 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
   ): Promise<void> {
     let response: JsonType;
     if (
-      chargingStation.getOcppStrictCompliance() &&
-      chargingStation.isInPendingState() &&
+      chargingStation.getOcppStrictCompliance() === true &&
+      chargingStation.isInPendingState() === true &&
       (commandName === OCPP16IncomingRequestCommand.REMOTE_START_TRANSACTION ||
         commandName === OCPP16IncomingRequestCommand.REMOTE_STOP_TRANSACTION)
     ) {
@@ -298,12 +298,13 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
       );
     }
     if (
-      chargingStation.isRegistered() ||
-      (!chargingStation.getOcppStrictCompliance() && chargingStation.isInUnknownState())
+      chargingStation.isRegistered() === true ||
+      (chargingStation.getOcppStrictCompliance() === false &&
+        chargingStation.isInUnknownState() === true)
     ) {
       if (
-        this.incomingRequestHandlers.has(commandName) &&
-        OCPP16ServiceUtils.isIncomingRequestCommandSupported(chargingStation, commandName)
+        this.incomingRequestHandlers.has(commandName) === true &&
+        OCPP16ServiceUtils.isIncomingRequestCommandSupported(chargingStation, commandName) === true
       ) {
         try {
           this.validatePayload(chargingStation, commandName, commandPayload);
@@ -378,14 +379,18 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
     chargingStation: ChargingStation,
     commandPayload: ResetRequest
   ): DefaultResponse {
-    this.asyncResource.runInAsyncScope(
-      chargingStation.reset.bind(chargingStation) as (
-        this: ChargingStation,
-        ...args: any[]
-      ) => void,
-      chargingStation,
-      (commandPayload.type + 'Reset') as OCPP16StopTransactionReason
-    );
+    this.asyncResource
+      .runInAsyncScope(
+        chargingStation.reset.bind(chargingStation) as (
+          this: ChargingStation,
+          ...args: any[]
+        ) => Promise<void>,
+        chargingStation,
+        (commandPayload.type + 'Reset') as OCPP16StopTransactionReason
+      )
+      .catch(() => {
+        /* This is intentional */
+      });
     logger.info(
       `${chargingStation.logPrefix()} ${
         commandPayload.type
@@ -408,9 +413,15 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
     commandPayload: UnlockConnectorRequest
   ): Promise<UnlockConnectorResponse> {
     const connectorId = commandPayload.connectorId;
+    if (chargingStation.connectors.has(connectorId) === false) {
+      logger.error(
+        `${chargingStation.logPrefix()} Trying to unlock a non existing connector Id ${connectorId.toString()}`
+      );
+      return Constants.OCPP_RESPONSE_UNLOCK_NOT_SUPPORTED;
+    }
     if (connectorId === 0) {
       logger.error(
-        chargingStation.logPrefix() + ' Trying to unlock connector ' + connectorId.toString()
+        chargingStation.logPrefix() + ' Trying to unlock connector Id ' + connectorId.toString()
       );
       return Constants.OCPP_RESPONSE_UNLOCK_NOT_SUPPORTED;
     }
@@ -574,6 +585,11 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
         chargingStation.getConnectorStatus(commandPayload.connectorId)?.transactionStarted ===
           false)
     ) {
+      logger.error(
+        `${chargingStation.logPrefix()} Trying to set transaction charging profile(s) on connector ${
+          commandPayload.connectorId
+        } without a started transaction`
+      );
       return Constants.OCPP_SET_CHARGING_PROFILE_RESPONSE_REJECTED;
     }
     OCPP16ServiceUtils.setChargingProfile(
@@ -676,7 +692,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
     commandPayload: ChangeAvailabilityRequest
   ): Promise<ChangeAvailabilityResponse> {
     const connectorId: number = commandPayload.connectorId;
-    if (!chargingStation.getConnectorStatus(connectorId)) {
+    if (chargingStation.connectors.has(connectorId) === false) {
       logger.error(
         `${chargingStation.logPrefix()} Trying to change the availability of a non existing connector Id ${connectorId.toString()}`
       );
@@ -1102,22 +1118,26 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
         chargingStation,
         OCPP16SupportedFeatureProfiles.RemoteTrigger,
         OCPP16IncomingRequestCommand.TRIGGER_MESSAGE
+      ) ||
+      !OCPP16ServiceUtils.isMessageTriggerSupported(
+        chargingStation,
+        commandPayload.requestedMessage
       )
     ) {
       return Constants.OCPP_TRIGGER_MESSAGE_RESPONSE_NOT_IMPLEMENTED;
     }
-    // TODO: factor out the check on connector id
-    if (commandPayload?.connectorId < 0) {
-      logger.warn(
-        `${chargingStation.logPrefix()} ${
-          OCPP16IncomingRequestCommand.TRIGGER_MESSAGE
-        } incoming request received with invalid connectorId ${commandPayload.connectorId}`
-      );
+    if (
+      !OCPP16ServiceUtils.isConnectorIdValid(
+        chargingStation,
+        OCPP16IncomingRequestCommand.TRIGGER_MESSAGE,
+        commandPayload.connectorId
+      )
+    ) {
       return Constants.OCPP_TRIGGER_MESSAGE_RESPONSE_REJECTED;
     }
     try {
       switch (commandPayload.requestedMessage) {
-        case MessageTrigger.BootNotification:
+        case OCPP16MessageTrigger.BootNotification:
           setTimeout(() => {
             chargingStation.ocppRequestService
               .requestHandler<OCPP16BootNotificationRequest, OCPP16BootNotificationResponse>(
@@ -1134,7 +1154,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
               });
           }, Constants.OCPP_TRIGGER_MESSAGE_DELAY);
           return Constants.OCPP_TRIGGER_MESSAGE_RESPONSE_ACCEPTED;
-        case MessageTrigger.Heartbeat:
+        case OCPP16MessageTrigger.Heartbeat:
           setTimeout(() => {
             chargingStation.ocppRequestService
               .requestHandler<OCPP16HeartbeatRequest, OCPP16HeartbeatResponse>(
@@ -1150,7 +1170,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
               });
           }, Constants.OCPP_TRIGGER_MESSAGE_DELAY);
           return Constants.OCPP_TRIGGER_MESSAGE_RESPONSE_ACCEPTED;
-        case MessageTrigger.StatusNotification:
+        case OCPP16MessageTrigger.StatusNotification:
           setTimeout(() => {
             if (commandPayload?.connectorId) {
               chargingStation.ocppRequestService