#include "Module_OcppBackend.h" void CallErrorHandler(char *id, char *errorCode, char *errorDescription,char *payload); int CallHandler(char *uuid, char *str1,char *payload); void CallResultHandler(char *str1,char *payload, int gun_index); extern void CheckTransactionPacket(char *uuid); typedef void (*FunCallErrorPtr)(char *id, char *errorCode, char *errorDescription,char *payload); typedef void (*FunPtr)(char *payload, int gun_index); typedef int (*FunCallPtr)(char *uuid, char *payload); typedef enum boolean { FALSE, TRUE } BOOL; static char *requestNames[] = { "CancelReservation", "ChangeAvailability", "ChangeConfiguration", "ClearCache", "ClearChargingProfile", "DataTransfer", "GetCompositeSchedule", "GetConfiguration", "GetDiagnostics", "GetLocalListVersion", "RemoteStartTransaction", "RemoteStopTransaction", "ReserveNow", "Reset", "SendLocalList", "SetChargingProfile", "TriggerMessage", "UnlockConnector", "UpdateFirmware", "CertificateSigned", "DeleteCertificate", "ExtendedTriggerMessage", "GetInstalledCertificateIds", "GetLog", "InstallCertificate", "SignedUpdateFirmware", "Unknown"}; static char *responseNames[] = {"Authorize", "BootNotification", "DataTransfer", "DiagnosticsStatusNotification", "FirmwareStatusNotification", "Heartbeat", "MeterValues", "StartTransaction", "StatusNotification", "StopTransaction", "LogStatusNotification", "SecurityEventNotification", "SignCertificate", "SignedFirmwareStatusNotification"}; static FunPtr funs[] = {handleAuthorizeResponse, handleBootNotificationResponse, handleDataTransferResponse, handleDiagnosticsStatusNotificationResponse, handleFirmwareStatusNotificationResponse, handleHeartbeatResponse, handleMeterValuesResponse, handleStartTransactionResponse, handleStatusNotificationResponse, handleStopTransactionnResponse, handleLogStatusNotificationResponse, handleSecurityEventNotificationResponse, handleSignCertificateResponse, handleSignedFirmwareStatusNotificationResponse}; static FunCallPtr funcalls[] = {handleCancelReservationRequest, handleChangeAvailabilityRequest, handleChangeConfigurationRequest, handleClearCacheRequest, handleClearChargingProfileRequest, handleDataTransferRequest, handleGetCompositeScheduleRequest, handleGetConfigurationRequest, handleGetDiagnosticsRequest, handleGetLocalListVersionRequest, handleRemoteStartRequest, handleRemoteStopTransactionRequest, handleReserveNowTransactionRequest, handleResetRequest, handleSendLocalListRequest, handleSetChargingProfileRequest, handleTriggerMessageRequest, handleUnlockConnectorRequest, handleUpdateFirmwareRequest, handleCertificateSignedRequest, handleDeleteCertificateRequest, handleExtendedTriggerMessageRequest, handleGetInstalledCertificateIdsRequest, handleGetLogRequest, handleInstallCertificateRequest, handleSignedUpdateFirmwareRequest, handleUnknownRequest}; static FunCallErrorPtr funcallerror[] = { handleError }; //========================================== // Receive Message routine //========================================== void ReceivedMessage(void *in, size_t len) { //DEBUG_INFO("ReceivedMessage\n"); char tempin[WEBSOCKET_BUFFER_SIZE]; int MsgType = 0; char UniqueId[37],Action[33],Payload[WEBSOCKET_BUFFER_SIZE-712],ErrorCode[129],ErrorDescription[513]; char *arr[2]= {}; int gun_index = 0; const char *del = ","; char *substr = NULL; int count = 0; int i = 0; char key_value[VALUE_MAX_LENGTH]; //parsing received message and do something memset(key_value, 0, sizeof key_value); memset(UniqueId, 0, sizeof UniqueId); memset(Action, 0, sizeof Action); memset(Payload, 0, sizeof Payload); memset(ErrorCode, 0, sizeof ErrorCode); memset(ErrorDescription, 0, sizeof ErrorDescription); memset(tempin, 0, sizeof tempin); strcpy(tempin, (const char *)in); memset( (void *)in, 0, sizeof(char)*len ); if(tempin[0] != '\0') { if(strcmp((const char *)tempin,"[ ]") == 0) { DEBUG_WARN("Message is empty array.\n"); return; } json_object *obj = NULL; obj = json_tokener_parse(tempin); if(!is_error(obj)) { MsgType = json_object_get_int(json_object_array_get_idx(obj, 0)); sprintf(UniqueId, "%s", json_object_get_string(json_object_array_get_idx(obj, 1))); if((MsgType != 2) && (MsgType != 3) && (MsgType != 4) ) { DEBUG_WARN("Message type not valid.\n"); return; } if(UniqueId[0] == '\0') { DEBUG_WARN("Message unique id is null.\n"); return; } CheckTransactionPacket(UniqueId); switch (MsgType) { case MESSAGE_TYPE_CALL: sprintf(Action, "%s", json_object_get_string(json_object_array_get_idx(obj, 2))); sprintf(Payload, "%s", json_object_to_json_string_ext(json_object_array_get_idx(obj, 3), JSON_C_TO_STRING_PLAIN)); CallHandler(UniqueId,Action,Payload); break; case MESSAGE_TYPE_CALLRESULT: sprintf(Payload, "%s", json_object_to_json_string_ext(json_object_array_get_idx(obj, 2), JSON_C_TO_STRING_PLAIN)); if(hashmap_operation(HASH_OP_GET, UniqueId, key_value) == TRUE) { hashmap_operation(HASH_OP_REMOVE, UniqueId, key_value); char * const testdup = strdup(key_value); substr = strtok(testdup, del); while (substr != NULL) { arr[count] = substr; count++; substr = strtok(NULL, del); } i=0; sprintf(Action, "%s", *(arr+i++)); gun_index = atoi(*(arr+i++)); CallResultHandler(Action, Payload, gun_index); free(testdup); } break; case MESSAGE_TYPE_CALLERROR: sprintf(ErrorCode, "%s", json_object_get_string(json_object_array_get_idx(obj, 2))); sprintf(ErrorDescription, "%s", json_object_get_string(json_object_array_get_idx(obj, 3))); sprintf(Payload, "%s", json_object_to_json_string_ext(json_object_array_get_idx(obj, 4), JSON_C_TO_STRING_PLAIN)); if(hashmap_operation(HASH_OP_GET, UniqueId, key_value) == TRUE) { hashmap_operation(HASH_OP_REMOVE, UniqueId, key_value); sprintf(Action, "%s", key_value); CallErrorHandler(UniqueId,ErrorCode, ErrorDescription, ""); } break; default: break; } } else { DEBUG_WARN("Message is invalid JSON format.\n"); } json_object_put(obj); } else { DEBUG_WARN("Message is null. can't parse message.\n"); } } int CallHandler(char *uuid, char *str1,char *payload) { int result = FAIL; int CallHandlerNumber = 0; int CallHandlerIndex = (ARRAY_SIZE(requestNames)-1); int (*callfptr)(char *uuid,char *payload); CallHandlerNumber = sizeof(requestNames)/sizeof(requestNames[0]); for(int i= 0; i < CallHandlerNumber ; i ++ ) { if(strcmp(requestNames[i],str1) == 0) { CallHandlerIndex = i ; break; } } callfptr = NULL; callfptr = funcalls[CallHandlerIndex]; if(callfptr == NULL) {} if ( callfptr ) { callfptr(uuid, payload); result = PASS; } callfptr = NULL; return result; } void CallResultHandler(char *str1, char *payload, int gun_index) { static int CallResultHandlerNumber = 0; static int CallResultHandlerIndex = 0; void (*callResultfptr)(char *payload, int gun_index ); CallResultHandlerNumber = sizeof(responseNames)/sizeof(responseNames[0]); for(int i= 0; i < CallResultHandlerNumber ; i ++ ) { if(strcmp(responseNames[i],str1) == 0) { CallResultHandlerIndex = i ; break; } } callResultfptr = NULL; callResultfptr = funs[CallResultHandlerIndex]; if(callResultfptr == NULL) {} if ( callResultfptr ) { callResultfptr(payload, gun_index); } callResultfptr = NULL; } void CallErrorHandler(char *id, char *errorCode, char *errorDescription,char *payload) { void (*callErrorfptr)(char *id, char *errorCode, char *errorDescription,char *payload ); callErrorfptr = NULL; callErrorfptr = funcallerror[0]; if(callErrorfptr == NULL) { DEBUG_ERROR("callErrorfptr is null\n"); } if ( callErrorfptr ) { callErrorfptr(id, errorCode, errorDescription, payload); } callErrorfptr = NULL; }