#include "Module_OcppBackend20.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); #undef FALSE #undef TRUE typedef enum boolean { FALSE, TRUE } BOOL; static char *requestNames[] = { "CancelReservation", "CertificateSigned", "ChangeAvailability", "ClearCache", "ClearChargingProfile", "ClearDisplayMessage", "ClearVariableMonitoring", "CostUpdated", "CustomerInformation", "DataTransfer", "DeleteCertificate", "GetBaseReport", "GetChargingProfiles", "GetCompositeSchedule", "GetDisplayMessages", "GetInstalledCertificateIds", "GetLocalListVersion", "GetLog", "GetMonitoringReport", "GetReport", "GetTransactionStatus", "GetVariables", "InstallCertificate", "PublishFirmware", "RequestStartTransaction", "RequestStopTransaction", "ReserveNow", "Reset", "SendLocalList", "SetChargingProfile", "SetDisplayMessage", "SetMonitoringBase", "SetMonitoringLevel", "SetNetworkProfile", "SetVariableMonitoring", "SetVariables", "TriggerMessage", "UnlockConnector", "UnpublishFirmware", "UpdateFirmware", "Unknown"}; static char *responseNames[] = {"Authorize", "BootNotification", "ClearedChargingLimit", "DataTransfer", "FirmwareStatusNotification", "Get15118EVCertificate", "GetCertificateStatus", "Heartbeat", "LogStatusNotification", "MeterValues", "NotifyChargingLimit", "NotifyCustomerInformation", "NotifyDisplayMessages", "NotifyEVChargingNeeds", "NotifyEVChargingSchedule", "NotifyEvent", "NotifyMonitoringReport", "NotifyReport", "PublishFirmwareStatusNotification", "ReportChargingProfiles", "ReservationStatusUpdate", "SecurityEventNotification", "SignCertificate", "StatusNotification", "TransactionEvent" }; static FunPtr funs[] = {handleAuthorizeResponse, handleBootNotificationResponse, handleClearedChargingLimitResponse, handleDataTransferResponse, handleFirmwareStatusNotificationResponse, handleGet15118EVCertificateResponse, handleGetCertificateStatusResponse, handleHeartbeatResponse, handleLogStatusNotificationResponse, handleMeterValuesResponse, handleNotifyChargingLimitResponse, handleNotifyCustomerInformationResponse, handleNotifyDisplayMessagesResponse, handleNotifyEVChargingNeedsResponse, handleNotifyEVChargingScheduleResponse, handleNotifyEventResponse, handleNotifyMonitoringReportResponse, handleNotifyReportResponse, handlePublishFirmwareStatusNotificationResponse, handleReportChargingProfilesResponse, handleReservationStatusUpdateResponse, handleSecurityEventNotificationResponse, handleSignCertificateResponse, handleStatusNotificationResponse, handleTransactionEventResponse}; static FunCallPtr funcalls[] = {handleCancelReservationRequest, handleCertificateSignedRequest, handleChangeAvailabilityRequest, handleClearCacheRequest, handleClearChargingProfileRequest, handleClearDisplayMessageRequest, handleClearVariableMonitoringRequest, handleCostUpdatedRequest, handleCustomerInformationRequest, handleDataTransferRequest, handleDeleteCertificateRequest, handleGetBaseReportRequest, handleGetChargingProfilesRequest, handleGetCompositeScheduleRequest, handleGetDisplayMessagesRequest, handleGetInstalledCertificateIdsRequest, handleGetLocalListVersionRequest, handleGetLogRequest, handleGetMonitoringReportRequest, handleGetReportRequest, handleGetTransactionStatusRequest, handleGetVariablesRequest, handleInstallCertificateRequest, handlePublishFirmwareRequest, handleRequestStartTransactionRequest, handleRequestStopTransactionRequest, handleReserveNowRequest, handleResetRequest, handleSendLocalListRequest, handleSetChargingProfileRequest, handleSetDisplayMessageRequest, handleSetMonitoringBaseRequest, handleSetMonitoringLevelRequest, handleSetNetworkProfileRequest, handleSetVariableMonitoringRequest, handleSetVariablesRequest, handleTriggerMessageRequest, handleUnlockConnectorRequest, handleUnpublishFirmwareRequest, handleUpdateFirmwareRequest, 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 || 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)) { if(json_object_is_type(obj, json_type_array)) { if(json_object_array_length(obj) < 3) { DEBUG_WARN("Message parsed array count is less than 3.\n"); return; } } else { DEBUG_WARN("Message is not an array type.\n"); return; } 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)); if(GetServerSign()==TRUE || ((strstr(Action,"TriggerMessage")!=NULL) && (strstr(Payload,"BootNotification")!=NULL)) || (strstr(Action,"Set")!=NULL)) CallHandler(UniqueId,Action,Payload); else { char callError[WEBSOCKET_BUFFER_SIZE]; sprintf(callError, "[%d,\"%s\",\"%s\",\"%s\",{}]",MESSAGE_TYPE_CALLERROR, UniqueId, "SecurityError", "Not sign in with BootNotification yet."); LWS_Send(callError); } 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 ); //printf("enter CallResultHandler\n"); 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) { //printf("callResultfptr is null\n"); } 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]; //printf("CallErrorHandler \n"); if(callErrorfptr == NULL) { printf("callErrorfptr is null\n"); } if ( callErrorfptr ) { //printf("callErrorfptr is not null\n"); callErrorfptr(id, errorCode, errorDescription, payload); } callErrorfptr = NULL; }