lorenzodonini / ocpp-go

Open Charge Point Protocol implementation in Go

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

OCPP2.0.1 No means for cleanly sending securityerror codes

Jonesywolf opened this issue · comments

According to the standard, when the CSMS rejects the ChargingStation's BootNotification, the chargingstation must reply with a RPC
Framework: CALLERROR: SecurityError (from the standard) which translates to an error code of ocppj.SecurityError. While it is possible to send this error using chargingStation.client.SendError(...), this error must be issued in response to any request when the boot status notification is rejected so if I sent this within the request, I have no means to avoid sending two responses.

As a quick hack to get around this, I used the error's string field to issue a different type of error, but this is far from a great solution.

func (cs *chargingStation) sendResponse(response ocpp.Response, err error, requestId string) {
	if err != nil {
		if err.Error() == "CALLERROR: SecurityError" {
			// Send error response
			err = cs.client.SendError(requestId, ocppj.SecurityError, err.Error(), nil)
			if err != nil {
				// Error while sending an error. Will attempt to send a default error instead
				cs.client.HandleFailedResponseError(requestId, err, "")
				// Notify client implementation
				err = fmt.Errorf("replying to request %s with 'security error' failed: %w", requestId, err)
				cs.error(err)
			}
		} else {
			// Send error response
			err = cs.client.SendError(requestId, ocppj.InternalError, err.Error(), nil)
			if err != nil {
				// Error while sending an error. Will attempt to send a default error instead
				cs.client.HandleFailedResponseError(requestId, err, "")
				// Notify client implementation
				err = fmt.Errorf("replying to request %s with 'internal error' failed: %w", requestId, err)
				cs.error(err)
			}
		}
		return
	}

Perhaps a cleaner solution would involve a custom error class (or be built on top of the CallError class) that implements the error interface and includes a status code? This might require a type assertion in sendResponse() to check if the error has a StatusCode field but would be a lot better than what I hacked together. Just an idea.

I believe this is solved with #225. Closing.