#include "Module_OcppBackend20.h"
#include "define.h"

static char *APNAuthenticationEnumTypeStr[] = {
	MACROSTR(CHAP),
	MACROSTR(NONE),
	MACROSTR(PAP),
	MACROSTR(AUTO)
};

static char *AttributeEnumTypeStr[] = {
	MACROSTR(Actual),
	MACROSTR(Target),
	MACROSTR(MinSet),
	MACROSTR(MaxSet)
};

static char *AuthorizationStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Blocked),
	MACROSTR(ConcurrentTx),
	MACROSTR(Expired),
	MACROSTR(Invalid),
	MACROSTR(NoCredit),
	MACROSTR(NotAllowedTypeEVSE),
	MACROSTR(NotAtThisLocation),
	MACROSTR(NotAtThisTime),
	MACROSTR(Unknown)
};

#if 0
static char *AuthorizeCertificateStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(SignatureError),
	MACROSTR(CertificateExpired),
	MACROSTR(CertificateRevoked),
	MACROSTR(NoCertificateAvailable),
	MACROSTR(CertChainError),
	MACROSTR(ContractCancelled)
};
#endif

static char *BootReasonEnumTypeStr[] = {
	MACROSTR(ApplicationReset),
	MACROSTR(FirmwareUpdate),
	MACROSTR(LocalReset),
	MACROSTR(PowerUp),
	MACROSTR(RemoteReset),
	MACROSTR(ScheduledReset),
	MACROSTR(Triggered),
	MACROSTR(Unknown),
	MACROSTR(Watchdog)
};

static char *SecurityEventEnumTypeStr[] = {
	MACROSTR(FirmwareUpdated),
	MACROSTR(FailedToAuthenticateAtCsms),
	MACROSTR(CsmsFailedToAuthenticate),
	MACROSTR(SettingSystemTime),
	MACROSTR(StartupOfTheDevice),
	MACROSTR(ResetOrReboot),
	MACROSTR(SecurityLogWasCleared),
	MACROSTR(ReconfigurationOfSecurityParameters),
	MACROSTR(MemoryExhaustion),
	MACROSTR(InvalidMessages),
	MACROSTR(AttemptedReplayAttacks),
	MACROSTR(TamperDetectionActivated),
	MACROSTR(InvalidFirmwareSignature),
	MACROSTR(InvalidFirmwareSigningCertificate),
	MACROSTR(InvalidCsmsCertificate),
	MACROSTR(InvalidChargingStationCertificate),
	MACROSTR(InvalidTLSVersion),
	MACROSTR(InvalidTLSCipherSuite)
};

static char *CancelReservationStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Rejected)
};

static char *CertificateActionEnumTypeStr[] = {
	MACROSTR(Install),
	MACROSTR(Update)
};

static char *CertificateSignedStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Rejected)
};

static char *CertificateSigningUseEnumTypeStr[] = {
	MACROSTR(ChargingStationCertificate),
	MACROSTR(V2GCertificate)
};

static char *ChangeAvailabilityStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Rejected),
	MACROSTR(Scheduled)
};

#if 0
static char *ChargingLimitSourceEnumTypeStr[] = {
	MACROSTR(EMS),
	MACROSTR(Other),
	MACROSTR(SO),
	MACROSTR(CSO)
};
#endif

static char *ChargingProfileKindEnumTypeStr[] = {
	MACROSTR(Absolute),
	MACROSTR(Recurring),
	MACROSTR(Relative)
};

static char *ChargingProfilePurposeEnumTypeStr[] = {
	MACROSTR(ChargingStationExternalConstraints),
	MACROSTR(ChargingStationMaxProfile),
	MACROSTR(TxDefaultProfile),
	MACROSTR(TxProfile)
};

static char *ChargingProfileStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Rejected)
};

static char *ChargingRateUnitEnumTypeStr[] = {
	MACROSTR(W),
	MACROSTR(A)
};

static char *ChargingStateEnumTypeStr[] = {
	MACROSTR(Charging),
	MACROSTR(EVConnected),
	MACROSTR(SuspendedEV),
	MACROSTR(SuspendedEVSE),
	MACROSTR(Idle)
};

static char *ClearCacheStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Rejected)
};

static char *ClearChargingProfileStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Unknown)
};

static char *ClearMessageStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Unknown)
};

static char *ClearMonitoringStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Rejected),
	MACROSTR(NotFound)
};

static char *ComponentCriterionEnumTypeStr[] = {
	MACROSTR(Active),
	MACROSTR(Available),
	MACROSTR(Enabled),
	MACROSTR(Problem)
};

#if 0
static char *ConnectorEnumTypeStr[] = {
	MACROSTR(cCCS1),
	MACROSTR(cCCS2),
	MACROSTR(cG105),
	MACROSTR(cTesla),
	MACROSTR(cType1),
	MACROSTR(cType2),
	MACROSTR(s309-1P-16A),
	MACROSTR(s309-1P-32A),
	MACROSTR(s309-3P-16A),
	MACROSTR(s309-3P-32A),
	MACROSTR(sBS1361),
	MACROSTR(sCEE-7-7),
	MACROSTR(sType2),
	MACROSTR(sType3),
	MACROSTR(Other1PhMax16A),
	MACROSTR(Other1PhOver16A),
	MACROSTR(Other3Ph),
	MACROSTR(Pan),
	MACROSTR(wInductive),
	MACROSTR(wResonant),
	MACROSTR(Undetermined),
	MACROSTR(Unknown)
};
#endif

static char *ConnectorStatusEnumTypeStr[] = {
	MACROSTR(Available),
	MACROSTR(Occupied),
	MACROSTR(Reserved),
	MACROSTR(Unavailable),
	MACROSTR(Faulted)
};

#if 0
static char *CostKindEnumTypeStr[] = {
	MACROSTR(CarbonDioxideEmission),
	MACROSTR(RelativePricePercentage),
	MACROSTR(RenewableGenerationPercentage)
};
#endif

static char *CustomerInformationStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Rejected),
	MACROSTR(Invalid)
};

static char *DataEnumTypeStr[] = {
	MACROSTR(string),
	MACROSTR(decimal),
	MACROSTR(integer),
	MACROSTR(dateTime),
	MACROSTR(boolean),
	MACROSTR(OptionList),
	MACROSTR(SequenceList),
	MACROSTR(MemberList)
};

static char *DataTransferStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Rejected),
	MACROSTR(UnknownMessageId),
	MACROSTR(UnknownVendorId)
};

static char *DeleteCertificateStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Failed),
	MACROSTR(NotFound)
};

static char *DisplayMessageStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(NotSupportedMessageFormat),
	MACROSTR(Rejected),
	MACROSTR(NotSupportedPriority),
	MACROSTR(NotSupportedState),
	MACROSTR(UnknownTransaction)
};

#if 0
static char *EnergyTransferModeEnumTypeStr[] = {
	MACROSTR(DC),
	MACROSTR(AC_single_phase),
	MACROSTR(AC_two_phase),
	MACROSTR(AC_three_phase)
};
#endif

static char *EventNotificationEnumTypeStr[] = {
	MACROSTR(HardWiredNotification),
	MACROSTR(HardWiredMonitor),
	MACROSTR(PreconfiguredMonitor),
	MACROSTR(CustomMonitor)
};

static char *EventTriggerEnumTypeStr[] = {
	MACROSTR(Alerting),
	MACROSTR(Delta),
	MACROSTR(Periodic)
};

static char *FirmwareStatusEnumTypeStr[] = {
	MACROSTR(Downloaded),
	MACROSTR(DownloadFailed),
	MACROSTR(Downloading),
	MACROSTR(DownloadScheduled),
	MACROSTR(DownloadPaused),
	MACROSTR(Idle),
	MACROSTR(InstallationFailed),
	MACROSTR(Installing),
	MACROSTR(Installed),
	MACROSTR(InstallRebooting),
	MACROSTR(InstallScheduled),
	MACROSTR(InstallVerificationFailed),
	MACROSTR(InvalidSignature),
	MACROSTR(SignatureVerified)
};

static char *GenericDeviceModelStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Rejected),
	MACROSTR(NotSupported),
	MACROSTR(EmptyResultSet)
};

static char *GenericStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Rejected)
};

static char *GetCertificateIdUseEnumTypeStr[] = {
	MACROSTR(V2GRootCertificate),
	MACROSTR(MORootCertificate),
	MACROSTR(CSMSRootCertificate),
	MACROSTR(V2GCertificateChain),
	MACROSTR(ManufacturerRootCertificate)
};

static char *GetCertificateStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Failed)
};

static char *GetChargingProfileStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(NoProfiles)
};

static char *GetDisplayMessagesStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Unknown)
};

static char *GetInstalledCertificateStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(NotFound)
};

static char *GetVariableStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Rejected),
	MACROSTR(UnknownComponent),
	MACROSTR(UnknownVariable),
	MACROSTR(NotSupportedAttributeType)
};

static char *HashAlgorithmEnumTypeStr[] = {
	MACROSTR(SHA256),
	MACROSTR(SHA384),
	MACROSTR(SHA512)
};

static char *IdTokenEnumTypeStr[] = {
	MACROSTR(Central),
	MACROSTR(eMAID),
	MACROSTR(ISO14443),
	MACROSTR(KeyCode),
	MACROSTR(Local),
	MACROSTR(NoAuthorization),
	MACROSTR(ISO15693)
};

static char *InstallCertificateUseEnumTypeStr[] = {
	MACROSTR(V2GRootCertificate),
	MACROSTR(MORootCertificate),
	MACROSTR(CSMSRootCertificate),
	MACROSTR(ManufacturerRootCertificate)
};

static char *InstallCertificateStatusEnumTypeStr[]={
	MACROSTR(Accepted),
	MACROSTR(Failed),
	MACROSTR(Rejected)
};

static char *Iso15118EVCertificateStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Failed)
};

static char *LocationEnumTypeStr[] = {
	MACROSTR(Body),
	MACROSTR(Cable),
	MACROSTR(EV),
	MACROSTR(Inlet),
	MACROSTR(Outlet)
};

static char *LogEnumTypeStr[] = {
	MACROSTR(DiagnosticsLog),
	MACROSTR(SecurityLog)
};

static char *LogStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Rejected),
	MACROSTR(AcceptedCanceled)
};

static char *MeasurandEnumTypeStr[] = {
	MACROSTR(Current.Export),
	MACROSTR(Current.Import),
	MACROSTR(Current.Offered),
	MACROSTR(Energy.Active.Export.Register),
	MACROSTR(Energy.Active.Import.Register),
	MACROSTR(Energy.Reactive.Export.Register),
	MACROSTR(Energy.Reactive.Import.Register),
	MACROSTR(Energy.Active.Export.Interval),
	MACROSTR(Energy.Active.Import.Interval),
	MACROSTR(Energy.Active.Net),
	MACROSTR(Energy.Reactive.Export.Interval),
	MACROSTR(Energy.Reactive.Import.Interval),
	MACROSTR(Energy.Reactive.Net),
	MACROSTR(Energy.Apparent.Net),
	MACROSTR(Energy.Apparent.Import),
	MACROSTR(Energy.Apparent.Export),
	MACROSTR(Frequency),
	MACROSTR(Power.Active.Export),
	MACROSTR(Power.Active.Import),
	MACROSTR(Power.Factor),
	MACROSTR(Power.Offered),
	MACROSTR(Power.Reactive.Export),
	MACROSTR(Power.Reactive.Import),
	MACROSTR(SoC),
	MACROSTR(Voltage)
};

static char *MessageFormatEnumTypeStr[] = {
	MACROSTR(ASCII),
	MACROSTR(HTML),
	MACROSTR(URI),
	MACROSTR(UTF8)
};

static char *MessagePriorityEnumTypeStr[] = {
	MACROSTR(AlwaysFront),
	MACROSTR(InFront),
	MACROSTR(NormalCycle)
};

static char *MessageStateEnumTypeStr[] = {
	MACROSTR(Charging),
	MACROSTR(Faulted),
	MACROSTR(Idle),
	MACROSTR(Unavailable)
};

static char *MessageTriggerEnumTypeStr[] = {
	MACROSTR(BootNotification),
	MACROSTR(LogStatusNotification),
	MACROSTR(FirmwareStatusNotification),
	MACROSTR(Heartbeat),
	MACROSTR(MeterValues),
	MACROSTR(SignChargingStationCertificate),
	MACROSTR(SignV2GCertificate),
	MACROSTR(StatusNotification),
	MACROSTR(TransactionEvent),
	MACROSTR(SignCombinedCertificate),
	MACROSTR(PublishFirmwareStatusNotification)
};

static char *MonitorEnumTypeStr[] = {
	MACROSTR(UpperThreshold),
	MACROSTR(LowerThreshold),
	MACROSTR(Delta),
	MACROSTR(Periodic),
	MACROSTR(PeriodicClockAligned)
};

static char *MonitoringBaseEnumTypeStr[] = {
	MACROSTR(All),
	MACROSTR(FactoryDefault),
	MACROSTR(HardWiredOnly)
};

static char *MonitoringCriterionEnumTypeStr[] = {
	MACROSTR(ThresholdMonitoring),
	MACROSTR(DeltaMonitoring),
	MACROSTR(PeriodicMonitoring)
};

static char *MutabilityEnumTypeStr[] = {
	MACROSTR(ReadOnly),
	MACROSTR(WriteOnly),
	MACROSTR(ReadWrite)
};

static char *NotifyEVChargingNeedsStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Rejected),
	MACROSTR(Processing)
};

static char *OCPPInterfaceEnumTypeStr[] = {
	MACROSTR(Wired0),
	MACROSTR(Wired1),
	MACROSTR(Wired2),
	MACROSTR(Wired3),
	MACROSTR(Wireless0),
	MACROSTR(Wireless1),
	MACROSTR(Wireless2),
	MACROSTR(Wireless3)
};

static char *OCPPTransportEnumTypeStr[] = {
	MACROSTR(JSON),
	MACROSTR(SOAP)
};

static char *OCPPVersionEnumTypeStr[] = {
	MACROSTR(OCPP12),
	MACROSTR(OCPP15),
	MACROSTR(OCPP16),
	MACROSTR(OCPP20)
};

static char *OperationalStatusEnumTypeStr[] = {
	MACROSTR(Inoperative),
	MACROSTR(Operative)
};

static char *PhaseEnumTypeStr[] = {
	MACROSTR(L1),
	MACROSTR(L2),
	MACROSTR(L3),
	MACROSTR(N),
	MACROSTR(L1-N),
	MACROSTR(L2-N),
	MACROSTR(L3-N),
	MACROSTR(L1-L2),
	MACROSTR(L2-L3),
	MACROSTR(L3-L1)
};

static char *PublishFirmwareStatusEnumTypeStr[] = {
	MACROSTR(Downloaded),
	MACROSTR(DownloadFailed),
	MACROSTR(Downloading),
	MACROSTR(DownloadScheduled),
	MACROSTR(DownloadPaused),
	MACROSTR(PublishFailed),
	MACROSTR(Published),
	MACROSTR(InvalidChecksum),
	MACROSTR(ChecksumVerified)
};

static char *ReadingContextEnumTypeStr[] = {
	MACROSTR(Interruption.Begin),
	MACROSTR(Interruption.End),
	MACROSTR(Other),
	MACROSTR(Sample.Clock),
	MACROSTR(Sample.Periodic),
	MACROSTR(Transaction.Begin),
	MACROSTR(Transaction.End),
	MACROSTR(Trigger)
};

#if 0
static char *ReasonEnumTypeStr[] = {
	MACROSTR(DeAuthorized),
	MACROSTR(EmergencyStop),
	MACROSTR(EnergyLimitReached),
	MACROSTR(EVDisconnected),
	MACROSTR(GroundFault),
	MACROSTR(ImmediateReset),
	MACROSTR(Local),
	MACROSTR(LocalOutOfCredit),
	MACROSTR(MasterPass),
	MACROSTR(Other),
	MACROSTR(OvercurrentFault),
	MACROSTR(PowerLoss),
	MACROSTR(PowerQuality),
	MACROSTR(Reboot),
	MACROSTR(Remote),
	MACROSTR(SOCLimitReached),
	MACROSTR(StoppedByEV),
	MACROSTR(TimeLimitReached),
	MACROSTR(TimeLimitReached)
};
#endif

static char *RecurrencyKindEnumTypeStr[] = {
	MACROSTR(Daily),
	MACROSTR(Weekly)
};

static char *RegistrationStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Pending),
	MACROSTR(Rejected)
};

static char *ReportBaseEnumTypeStr[] = {
	MACROSTR(ConfigurationInventory),
	MACROSTR(FullInventory),
	MACROSTR(SummaryInventory)
};

static char *RequestStartStopStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Rejected)
};

static char *ReservationUpdateStatusEnumTypeStr[] = {
	MACROSTR(Expired),
	MACROSTR(Removed)
};

static char *ReserveNowStatusEnumTypeStr[] = {
    MACROSTR(Accepted),
    MACROSTR(Faulted),
	MACROSTR(Occupied),
	MACROSTR(Rejected),
	MACROSTR(Unavailable)
};

static char *ResetEnumTypeStr[] = {
	MACROSTR(Immediate),
	MACROSTR(OnIdle)
};

static char *ResetStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Rejected),
	MACROSTR(Scheduled)
};

static char *SetMonitoringStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(UnknownComponent),
	MACROSTR(UnknownVariable),
	MACROSTR(UnsupportedMonitorType),
	MACROSTR(Rejected),
	MACROSTR(OutOfRange),
	MACROSTR(Duplicate)
};


static char *SetNetworkProfileStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Rejected),
	MACROSTR(Failed)
};


static char *SetVariableStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Rejected),
	MACROSTR(InvalidValue),
	MACROSTR(UnknownComponent),
	MACROSTR(UnknownVariable),
	MACROSTR(NotSupportedAttributeType),
	MACROSTR(OutOfRange),
	MACROSTR(RebootRequired)
};


static char *TransactionEventEnumTypeStr[] = {
	MACROSTR(Ended),
	MACROSTR(Started),
	MACROSTR(Updated)
};

static char *TriggerMessageStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Rejected),
	MACROSTR(NotImplemented)
};

static char *TriggerReasonEnumTypeStr[] = {
	MACROSTR(Authorized),
	MACROSTR(CablePluggedIn),
	MACROSTR(ChargingRateChanged),
	MACROSTR(ChargingStateChanged),
	MACROSTR(Deauthorized),
	MACROSTR(EnergyLimitReached),
	MACROSTR(EVCommunicationLost),
	MACROSTR(EVConnectTimeout),
	MACROSTR(MeterValueClock),
	MACROSTR(MeterValuePeriodic),
	MACROSTR(TimeLimitReached),
	MACROSTR(Trigger),
	MACROSTR(UnlockCommand),
	MACROSTR(StopAuthorized),
	MACROSTR(EVDeparted),
	MACROSTR(EVDetected),
	MACROSTR(RemoteStop),
	MACROSTR(RemoteStart),
	MACROSTR(AbnormalCondition),
	MACROSTR(SignedDataReceived),
	MACROSTR(ResetCommand)
};

static char *UnlockStatusEnumTypeStr[] = {
	MACROSTR(Unlocked),
	MACROSTR(UnlockFailed),
	MACROSTR(OngoingAuthorizedTransaction),
	MACROSTR(UnknownConnector)
};

static char *UnpublishFirmwareStatusEnumTypeStr[] = {
	MACROSTR(DownloadOngoing),
	MACROSTR(NoFirmware),
	MACROSTR(Unpublished)
};

static char *UpdateEnumTypeStr[] = {
	MACROSTR(Differential),
	MACROSTR(Full)
};

static char *UpdateFirmwareStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Rejected),
	MACROSTR(AcceptedCanceled),
	MACROSTR(InvalidCertificate),
	MACROSTR(RevokedCertificate)
};

static char *UpdateStatusEnumTypeStr[] = {
	MACROSTR(Accepted),
	MACROSTR(Failed),
	MACROSTR(VersionMismatch)
};

static char *UploadLogStatusEnumTypeStr[] = {
	MACROSTR(BadMessage),
	MACROSTR(Idle),
	MACROSTR(NotSupportedOperation),
	MACROSTR(PermissionDenied),
	MACROSTR(Uploaded),
	MACROSTR(UploadFailure),
	MACROSTR(Uploading)
};

static char *VPNEnumTypeStr[] = {
	MACROSTR(IKEv2),
	MACROSTR(IPSec),
	MACROSTR(L2TP),
	MACROSTR(PPTP)
};

#if 0
static char *ChargePointErrorCodeEnumTypeStr[] = {
    MACROSTR(ConnectorLockFailure),
    MACROSTR(EVCommunicationError),
	MACROSTR(GroundFailure),
	MACROSTR(HighTemperature),
	MACROSTR(InternalError),
	MACROSTR(LocalListConflict),
	MACROSTR(NoError),
	MACROSTR(OtherError),
	MACROSTR(OverCurrentFailure),
	MACROSTR(OverVoltage),
	MACROSTR(PowerMeterFailure),
	MACROSTR(PowerSwitchFailure),
	MACROSTR(ReaderFailure),
	MACROSTR(ResetFailure),
	MACROSTR(UnderVoltage),
	MACROSTR(WeakSignal)
};
#endif

static char *GetCompositeScheduleStatusEnumTypeStr[] = {
    MACROSTR(Accepted),
    MACROSTR(Rejected)
};

static char *RemoteStartStopStatusEnumTypeStr[] = {
    MACROSTR(Accepted),
    MACROSTR(Rejected)

};

#if 0
static char * StopTransactionReasonEnumTypeStr[] = {
    MACROSTR(EmergencyStop),
    MACROSTR(EVDisconnected),
	MACROSTR(HardReset),
	MACROSTR(Local),
	MACROSTR(Other),
	MACROSTR(PowerLoss),
	MACROSTR(Reboot),
	MACROSTR(Remote),
	MACROSTR(SoftReset),
	MACROSTR(UnlockCommand),
	MACROSTR(DeAuthorized)
};
#endif


//ChargePointMaxProfile
#define ChargingStationMaxProfile_JSON     	"/Storage/OCPP/ChargingStationMaxProfile_OCPP20.json"

//TxDefaultProfile
#define TxDefaultProfile_0_JSON			"/Storage/OCPP/TxDefaultProfile_0_OCPP20.json"

struct SysConfigAndInfo					*ShmSysConfigAndInfo;
struct StatusCodeData 					*ShmStatusCodeData;
struct PsuData 							*ShmPsuData ;
struct OCPP20Data 						*ShmOCPP20Data;

pthread_mutex_t lock_send 				= PTHREAD_MUTEX_INITIALIZER;
char queuedata[QUEUE_MESSAGE_LENGTH]	= {0};

//===============================
// Gun Total  Numbers
//===============================
static ParsingRatedCur modelnameInfo	= {0};
static int gunTotalNumber				= 0;
static uint8_t gunType[4] 				= {0};

//===============================
// Local List Version
//===============================
static int localversion=0;

//===============================
// Variable Version
//===============================
static int variableVersion=6;

//===============================
// OCPP sign variable
//===============================
static int server_sign					= FALSE;
int server_pending 						= FALSE;
static int BootNotificationInterval 	= 10;

//===============================
// OCPP auth variable
//===============================
static int authorizeRetryTimes 			= 0;  //number of  Retry times

//===============================
// OCPP other variables
//===============================
static int HeartBeatWaitTime 						= 10;
static int FirstHeartBeat 							= 0;
static int FirmwareStatusNotificationStatus 		= FirmwareStatusEnumType_Idle;  // Idle
static int LogStatusNotificationStatus 				= UploadLogStatusEnumType_Idle; // Idle
static char CurrentChargingProfileScheduleStr[30]	= {0};

//========================================
// OCPP status/previous related variables
//========================================
static int GunStatusInterval 																= 10;
static uint8_t ChademoPreviousSystemStatus[(CHAdeMO_QUANTITY>0?CHAdeMO_QUANTITY:1)];
static uint8_t CcsPreviousSystemStatus[(CCS_QUANTITY>0?CCS_QUANTITY:1)];
static uint8_t GbPreviousSystemStatus[(GB_QUANTITY>0?GB_QUANTITY:1)];
static uint8_t AcPreviousSystemStatus[(AC_QUANTITY>0?AC_QUANTITY:1)];
static uint8_t DoPreviousSystemStatus[(CONNECTOR_QUANTITY>0?CONNECTOR_QUANTITY:1)];
static uint8_t ChademoPreviousConnectorPlugIn[(CHAdeMO_QUANTITY>0?CHAdeMO_QUANTITY:1)];
static uint8_t CcsPreviousConnectorPlugIn[(CCS_QUANTITY>0?CCS_QUANTITY:1)];
static uint8_t GbPreviousConnectorPlugIn[(GB_QUANTITY>0?GB_QUANTITY:1)];
static uint8_t AcPreviousConnectorPlugIn[(AC_QUANTITY>0?AC_QUANTITY:1)];
static uint8_t DoPreviousConnectorPlugIn[(CONNECTOR_QUANTITY>0?CONNECTOR_QUANTITY:1)];
static int TransactionMessageAttemptsValue 													= 0;
static int TransactionMessageRetryIntervalValue 											= 0;
static struct AuthorizationData idTagQuery;

//=============================================
// OCPP HeartBeat Response Not Receive Counts
//============================================
static int HeartBeatWithNOResponse = 0;
static int HeartBeatCountPerHour = 0;

sqlite3 *db;

int TransactionMessageAttemptsGet(void);
int TransactionMessageRetryIntervalGet(void);
int GetOcppConnStatus(void);
void SetOcppConnStatus(uint8_t status);
int setKeyValue(char *key, char *value);
void OCPP_get_TableAuthlocalAllData(void);
void processUnkownKey(void);

struct InterLock
{
	unsigned char isGetLogGoing:1;
	unsigned char isUpdateFirmwareGoing:1;
}interLock;

struct ClientTime
{
	struct timespec Heartbeat;
	struct timespec StatusNotification[CONNECTOR_QUANTITY];
	struct timespec StartTransaction;
	struct timespec StopTransaction;
	struct timespec MeterValues[CONNECTOR_QUANTITY];
	struct timespec RemoteStartWait;

}clientTime;

typedef union
{
	//Operations Initiated by Central System
	unsigned char CsMsgValue[CONNECTOR_QUANTITY];
	struct
	{
		//CsMsgValue[0]
		unsigned char StatusNotificationReq:1;			//bit 0,
		unsigned char StatusNotificationConf:1;			//bit 1,
		unsigned char TriggerMeterValueReq:1;			//bit 2,
		unsigned char SampleMeterReq:1;					//bit 3,
		unsigned char ClockAlignMeterReq:1;				//bit 4,
		unsigned char TriggerStatusNotificationReq:1;	//bit 5,
		unsigned char isOnCharging:1;					//bit6,
		unsigned char :1;								//bit7
	}bits[CONNECTOR_QUANTITY];
}CpinitiateMsg;

CpinitiateMsg cpinitateMsg;

//=========================================
// Save configuration
//=========================================
int runShellCmd(const char*cmd)
{
	int result = FAIL;
	char buf[256];
	FILE *fp;

	fp = popen(cmd, "r");
	if(fp != NULL)
	{
		while(fgets(buf, sizeof(buf), fp) != NULL)
		{
			DEBUG_INFO("%s\n", buf);
		}

		result = PASS;
	}
	pclose(fp);

	return result;
}

int StoreUsrConfigData(struct SysConfigData *UsrData)
{
	int result = PASS;
	int fd,wrd;
	unsigned int i,Chk;
	unsigned char *ptr, *BufTmp;
	int MtdBlockSize = 0x300000;

	Chk=0;
	ptr=(unsigned char *)UsrData;
	if((BufTmp=malloc(MtdBlockSize))!=NULL)
	{
		memset(BufTmp,0,MtdBlockSize);
		memcpy(BufTmp,ptr,sizeof(struct SysConfigData));
		for(i=ARRAY_SIZE(UsrData->CsuBootLoadFwRev);i<MtdBlockSize-4;i++)
			Chk+=*(BufTmp+i);
		memcpy(BufTmp+MtdBlockSize-4, &Chk, 4);

		// Output configuration to file.
		fd = open("/mnt/EvseConfig.bin", O_RDWR|O_CREAT);
		if (fd < 0)
		{
			DEBUG_ERROR("open /mnt/EvseConfig.bin NG\n");

			free(BufTmp);
			return 0;
		}
		wrd=write(fd, BufTmp, MtdBlockSize);
		close(fd);
		if(wrd<MtdBlockSize)
		{
			DEBUG_ERROR("write /mnt/EvseConfig.bin NG\n");

			free(BufTmp);
			return 0;
		}
		DEBUG_INFO("EvseConfig write to file in /mnt OK.\n");


		DEBUG_INFO("Erase /dev/mtd10.\n");
		runShellCmd("flash_erase /dev/mtd10 0 0");
		DEBUG_INFO("Write /dev/mtd10.\n");
		runShellCmd("nandwrite -p /dev/mtd10 /mnt/EvseConfig.bin");

		DEBUG_INFO("Erase /dev/mtd11.\n");
		runShellCmd("flash_erase /dev/mtd11 0 0");
		DEBUG_INFO("Write /dev/mtd11.\n");
		runShellCmd("nandwrite -p /dev/mtd11 /mnt/EvseConfig.bin");


		system("rm -f /mnt/EvseConfig.bin");
		DEBUG_INFO("EvseConfig write to flash OK\n");
	}
	else
	{
		DEBUG_ERROR("alloc BlockSize NG\r\n");
			result = FAIL;
	}

	if(BufTmp!=NULL)
		free(BufTmp);

	return result;
}

//=========================================
// Date time related function
//=========================================
void getNowDatetime(uint8_t *data)
{
	time_t t = time(NULL);
	struct tm tm = *localtime(&t);

	sprintf((char*)data, "%04d-%02d-%02dT%02d:%02d:%02dZ", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
}

//=========================================
// Sqlite3 related function
//=========================================
int DB_Initial()
{
	int result = PASS;
	char* errMsg = NULL;

	char *sqlOcppAuthCache = "create table if not exists ocpp20_auth_cache (idx integer primary key,"
							 "idToken text UNIQUE,"
							 "type text,"
							 "status text,"
							 "cacheExpiryDateTime text,"
							 "chargingPriority integer,"
							 "language1 text,"
							 "evseId text,"
							 "language2 text,"
							 "groupIdToken_idToken text,"
							 "groupIdToken_type text,"
							 "personalMessage text);";

	char *sqlOcppAuthLocal = "create table if not exists ocpp20_auth_local (idx integer primary key,"
							 "idToken text UNIQUE,"
							 "type text,"
							 "status text,"
							 "cacheExpiryDateTime text,"
							 "chargingPriority integer,"
							 "language1 text,"
							 "evseId text,"
							 "language2 text,"
							 "groupIdToken_idToken text,"
							 "groupIdToken_type text,"
							 "personalMessage text,"
							 "version text);";

	char *sqlOcppVariable =  "create table if not exists ocpp20_variable (idx integer primary key,"
							 "componentName text NOT NULL ,"
							 "componentInstance text, "
							 "variableName text NOT NULL, "
							 "variableInstance text, "
							 "variableCharacteristicsDataType integer, "
							 "variableCharacteristicsUnit text, "
							 "variableCharacteristicsMaxLimit real,"
							 "variableAttributesType text, "
							 "variableAttributesTypeMutability text, "
							 "variableAttributesTypeValue text, "
		                     "variableCharacteristicsMinLimit real,"
							 "unique(componentName, componentInstance,variableName, variableInstance) on conflict replace);";

	char *sqlBootType 	  =  "create table if not exists ocpp20_boot_type (idx integer primary key,"
							 "type text);";

	char *sqlSecurityEventType 	  =  "create table if not exists ocpp20_securityevent_type (idx integer primary key,"
							 "type text);";


	char *sqlNetworkProfile	= "create table if not exists ocpp20_networkprofile (idx integer primary key,"
								 "slot integer UNIQUE, connectionData text);";


	char *sqlTransaction = "create table if not exists ocpp20_transaction_record (idx integer primary key,"
						   "occurDatetime text,"
						   "message_type text,"
						   "message_content text)";

	//sqlite3_config(SQLITE_CONFIG_URI, 1);
	if(sqlite3_open(OCPP_LOCAL_DB_FILE, &db))
	{
		result = FAIL;
		DEBUG_ERROR( "Can't open database: %s\n", sqlite3_errmsg(db));
		sqlite3_close(db);
	}
	else
	{
		DEBUG_INFO( "OCPP local database open successfully.\n");

		if (sqlite3_exec(db, sqlOcppAuthCache, 0, 0, &errMsg) != SQLITE_OK)
		{
			result = FAIL;
			DEBUG_ERROR( "Create OCPP 2.0 auth cache table error message: %s\n", errMsg);
		}
		else
		{
			DEBUG_INFO( "Create OCPP 2.0 auth cache table table successfully\n");
		}

		if (sqlite3_exec(db, sqlOcppAuthLocal, 0, 0, &errMsg) != SQLITE_OK)
		{
			result = FAIL;
			DEBUG_ERROR( "Create OCPP 2.0 auth list table error message: %s\n", errMsg);
		}
		else
		{
			DEBUG_INFO( "Create OCPP 2.0 auth list table successfully\n");
		}

		if (sqlite3_exec(db, sqlOcppVariable, 0, 0, &errMsg) != SQLITE_OK)
		{
			result = FAIL;
			DEBUG_ERROR( "Create OCPP 2.0 variable table error message: %s\n", errMsg);
		}
		else
		{
			DEBUG_INFO( "Create OCPP 2.0 variable table successfully\n");
		}

		if (sqlite3_exec(db, sqlBootType, 0, 0, &errMsg) != SQLITE_OK)
		{
			result = FAIL;
			DEBUG_ERROR( "Create OCPP 2.0 boot_type table error message: %s\n", errMsg);
		}
		else
		{
			DEBUG_INFO( "Create OCPP 2.0 boot_type table successfully\n");
		}

		if (sqlite3_exec(db, sqlSecurityEventType, 0, 0, &errMsg) != SQLITE_OK)
		{
			result = FAIL;
			DEBUG_ERROR( "Create OCPP 2.0 securityevent_type table error message: %s\n", errMsg);
		}
		else
		{
			DEBUG_INFO( "Create OCPP 2.0 securityevent_type table successfully\n");
		}

		if (sqlite3_exec(db, sqlNetworkProfile, 0, 0, &errMsg) != SQLITE_OK)
		{
			result = FAIL;
			DEBUG_ERROR( "Create OCPP 2.0 ocpp20_networkprofile table error message: %s\n", errMsg);
		}
		else
		{
			DEBUG_INFO( "Create OCPP 2.0 ocpp20_networkprofile table successfully\n");
		}

		if (sqlite3_exec(db, sqlTransaction, 0, 0, &errMsg) != SQLITE_OK)
		{
			result = FAIL;
			DEBUG_ERROR( "Create OCPP 2.0 ocpp20_transaction_record table error message: %s\n", errMsg);
		}
		else
		{
			DEBUG_INFO( "Create OCPP 2.0 ocpp20_transaction_record table successfully\n");
		}

		//sqlite3_close(db);
	}

	return result;
}

int DB_cbGetVersion(void *para, int columnCount, char **columnValue, char **columnName)
{
   localversion = columnValue[12] ? atoi(columnValue[12]) : 0;

   return 0;
}

void DB_getListVerion()
{
    char sql[256];
    char* errMsg = NULL;

    strcpy(sql, "select * from ocpp20_auth_local order by version desc, idx desc limit 1");

    /* Execute SQL statement */
    if( sqlite3_exec(db, sql, DB_cbGetVersion, 0, &errMsg) != SQLITE_OK )
    {
    	DEBUG_INFO("SQL error: %s", errMsg);
    }
}

int DB_cbGetIdTag(void *para, int columnCount, char **columnValue, char **columnName)
{
   sprintf((char*)idTagQuery.idToken.idToken,"%s", columnValue[1] ? columnValue[1] : "NULL");
   sprintf((char*)idTagQuery.idToken.type,"%s", columnValue[2] ? columnValue[2] : "NULL");
   sprintf((char*)idTagQuery.idTokenInfo.status,"%s", columnValue[3] ? columnValue[3] : "NULL");
   sprintf((char*)idTagQuery.idTokenInfo.cacheExpiryDateTime,"%s", columnValue[4] ? columnValue[4] : "NULL");
   idTagQuery.idTokenInfo.chargingPriority = columnValue[5] ? atoi(columnValue[5]) : -1;
   sprintf((char*)idTagQuery.idTokenInfo.language1,"%s", columnValue[6] ? columnValue[6] : "NULL");
   sprintf((char*)idTagQuery.idTokenInfo.language2,"%s", columnValue[8] ? columnValue[8] : "NULL");
   sprintf((char*)idTagQuery.idTokenInfo.groupIdToken.idToken,"%s", columnValue[9] ? columnValue[9] : "NULL");
   sprintf((char*)idTagQuery.idTokenInfo.groupIdToken.type,"%s", columnValue[10] ? columnValue[10] : "NULL");

   return 0;
}

void DB_getIdTag(char idTag[], uint8_t isQueryFromCache)
{
    char sql[256];
    char* errMsg = NULL;

    memset(&idTagQuery, 0, sizeof(idTagQuery));

    //DEBUG_INFO("look up card: %s in ocpp_auth_local table", idTag);
    if(isQueryFromCache)
    	sprintf(sql,"select * from ocpp20_auth_cache where idToken='%s'", idTag);
    else
    	sprintf(sql,"select * from ocpp20_auth_local where idToken='%s'", idTag);

    /* Execute SQL statement */
    if(sqlite3_exec(db, sql, DB_cbGetIdTag, 0, &errMsg) != SQLITE_OK )
    {
    	DEBUG_INFO("SQL error: %s", errMsg);
    }
}

int DB_cbTableAuthlocalAllData(void *para, int columnCount, char **columnValue, char **columnName)
{
    for (int i = 0; i < columnCount; i++)
    {
    	DEBUG_INFO("%s = %s, ", columnName[i], columnValue[i]);
    }

    return 0;
}

void DB_get_TableAuthlocalAllData(void)
{
    char sql[256];
    char* errMsg = NULL;

    sprintf(sql,"select * from ocpp20_auth_local;");

    /* Execute SQL statement */
    if(sqlite3_exec(db, sql, DB_cbTableAuthlocalAllData, 0,&errMsg) != SQLITE_OK)
    {
    	DEBUG_INFO("SQL error: %s", errMsg);
    }
}

int DB_cbAddLocalListCache(void *para, int columnCount, char **columnValue, char **columnName)
{
   for(int i = 0; i<columnCount; i++)
   {
     // printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
   }

   return 0;
}

int DB_addLocalList(int listVersion, struct AuthorizationData *data)
{
	 int result = PASS;
	 char sql[512];
	 char* errMsg = NULL;

	 sprintf(sql,"insert or replace into ocpp20_auth_local (idToken, type, status, cacheExpiryDateTime, chargingPriority, language1, language2, groupIdToken_idToken, groupIdToken_type, version) VALUES('%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', %d );  SELECT * from ocpp20_auth_local;",
				 data->idToken.idToken,
				 data->idToken.type,
				 data->idTokenInfo.status,
				 data->idTokenInfo.cacheExpiryDateTime,
				 data->idTokenInfo.chargingPriority,
				 data->idTokenInfo.language1,
				 data->idTokenInfo.language2,
				 data->idTokenInfo.groupIdToken.idToken,
				 data->idTokenInfo.groupIdToken.type,
				 listVersion);

	 //* Execute SQL statement */
	 if(sqlite3_exec(db, sql, DB_cbAddLocalListCache, 0, &errMsg) != SQLITE_OK)
	 {
		 DEBUG_INFO("SQL error: %s\n", errMsg);
		 result = FAIL;
	 }
	 else
	 {
		 memset(sql, 0, ARRAY_SIZE(sql));
		 sprintf(sql, "UPDATE ocpp20_auth_local SET version=%d",listVersion);
		 if( sqlite3_exec(db, sql, NULL, NULL, &errMsg) != SQLITE_OK )
		 {
			 DEBUG_INFO("SQL error: %s\n", errMsg);
			 result = FAIL;
		 }
	 }

	 return result;
}

int DB_addLocalCache(struct IdTokenType *idToken, struct IdTokenInfoType *idTokenInfo)
{
	 int result = PASS;
	 char sql[512];
	 char* errMsg = NULL;

	 sprintf(sql,"insert or replace into ocpp20_auth_cache (idToken, type, status, cacheExpiryDateTime, chargingPriority, language1, language2, groupIdToken_idToken, groupIdToken_type) VALUES('%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s');  SELECT * from ocpp20_auth_cache;",
				 idToken->idToken,
				 idToken->type,
				 idTokenInfo->status,
				 idTokenInfo->cacheExpiryDateTime,
				 idTokenInfo->chargingPriority,
				 idTokenInfo->language1,
				 idTokenInfo->language2,
				 idTokenInfo->groupIdToken.idToken,
				 idTokenInfo->groupIdToken.type);

	 //* Execute SQL statement */
	 if(sqlite3_exec(db, sql, DB_cbAddLocalListCache, 0, &errMsg) != SQLITE_OK)
	 {
		 DEBUG_INFO("SQL error: %s\n", errMsg);
		 result = FAIL;
	 }

	 return result;
}

int deleteIdTagcallback(void *para, int columnCount, char **columnValue, char **columnName)
{
//   localversion = argv[5] ? atoi(columnValue[5]) : 0;
//   printf("localversion=%d\n", localversion);
	return 0;
}

void DB_deleteIdTag(char idTag[])
{
	char sql[512];
	char* errMsg = NULL;

	sprintf(sql,"DELETE from ocpp20_auth_local where idToken='%s'; SELECT * from ocpp20_auth_local;", idTag);

	//* Execute SQL statement */
	if( sqlite3_exec(db, sql, deleteIdTagcallback, 0, &errMsg) != SQLITE_OK )
	{
		DEBUG_INFO("SQL error: %s", errMsg);
	}
}

int DB_cleanLocalList()
{
	int result = PASS;
	char * sqlcleanLocalList = "delete from ocpp20_auth_local";
	char *errMsg = 0;

	if (sqlite3_exec(db, sqlcleanLocalList, 0, 0, &errMsg) != SQLITE_OK)
	{
		DEBUG_INFO("%s\n", errMsg);
		result = FAIL;
	}

	return result;
}

int DB_cleanLocalCache()
{
	int result = PASS;
	char * sqlcleanLocalList = "delete from ocpp20_auth_cache";
	char *errMsg = 0;

	if (sqlite3_exec(db, sqlcleanLocalList, 0, 0, &errMsg) != SQLITE_OK)
	{
		DEBUG_INFO("%s\n", errMsg);
		result = FAIL;
	}

	return result;
}

int BootTypecallback(void *para, int columnCount, char **columnValue, char **columnName)
{
	sprintf((char*)ShmOCPP20Data->BootNotification.reason,"%s", columnValue[1] ? columnValue[1] : BootReasonEnumTypeStr[BootReasonEnumType_PowerUp]);

	return 0;
}

void DB_getBooType()
{
    char sql[256];
    char* errMsg = NULL;

    sprintf(sql,"select * from ocpp20_boot_type;");

    /* Execute SQL statement */
    if(sqlite3_exec(db, sql, BootTypecallback, 0, &errMsg) != SQLITE_OK )
    {
    	DEBUG_INFO("SQL error: %s\n", errMsg);
    }
}

int DB_cbUpdateBootType(void *para, int columnCount, char **columnValue, char **columnName)
{
   for(int i = 0; i<columnCount; i++)
   {
     // printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
   }

   return 0;
}

int DB_updateBootType(BootReasonEnumType reason)
{
	int result = PASS;
	 char sql[512];
	 char* errMsg = NULL;

	 sprintf(sql,"insert or replace into ocpp20_boot_type (idx, type) VALUES(1, '%s');", BootReasonEnumTypeStr[reason>BootReasonEnumType_Watchdog?BootReasonEnumType_PowerUp:reason]);

	 //* Execute SQL statement */
	 if(sqlite3_exec(db, sql, DB_cbUpdateBootType, 0, &errMsg) != SQLITE_OK)
	 {
		 DEBUG_INFO("SQL error: %s\n", errMsg);
		 result = FAIL;
	 }

	 return result;
}

int SecurityEventTypecallback(void *para, int columnCount, char **columnValue, char **columnName)
{
	sprintf((char*)ShmOCPP20Data->SecurityEventNotification.type,"%s", columnValue[1] ? columnValue[1] : SecurityEventEnumTypeStr[SecurityEventEnumType_ResetOrReboot]);

	return 0;
}

void DB_getSecurityEventType()
{
    char sql[256];
    char* errMsg = NULL;

    sprintf(sql,"select * from ocpp20_securityevent_type;");

    /* Execute SQL statement */
    if(sqlite3_exec(db, sql, SecurityEventTypecallback, 0, &errMsg) != SQLITE_OK )
    {
    	DEBUG_INFO("SQL error: %s\n", errMsg);
    }
}

int DB_cbUpdateSecurityEventType(void *para, int columnCount, char **columnValue, char **columnName)
{
   for(int i = 0; i<columnCount; i++)
   {
     // printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
   }

   return 0;
}

int DB_updateSecurityEventType(SecurityEventEnumType reason)
{
	int result = PASS;
	 char sql[512];
	 char* errMsg = NULL;

	 sprintf(sql,"insert or replace into ocpp20_securityevent_type (idx, type) VALUES(1, '%s');", SecurityEventEnumTypeStr[reason]);

	 //* Execute SQL statement */
	 if(sqlite3_exec(db, sql, DB_cbUpdateSecurityEventType, 0, &errMsg) != SQLITE_OK)
	 {
		 DEBUG_INFO("SQL error: %s\n", errMsg);
		 result = FAIL;
	 }

	 return result;
}

int DB_variableClear()
{
	int result = PASS;
	char * sqlcleanLocalList = "delete from ocpp20_variable";
	char *errMsg = 0;

	if (sqlite3_exec(db, sqlcleanLocalList, 0, 0, &errMsg) != SQLITE_OK)
	{
		DEBUG_INFO("%s\n", errMsg);
		result = FAIL;
	}

	return result;
}

int DB_cbVariableSaveToDb(void *para, int columnCount, char **columnValue, char **columnName)
{
   for(int i = 0; i<columnCount; i++)
   {
     // printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
   }

   return 0;
}

int DB_variableSaveToDb(struct ReportDataType *variable)
{
	int result = FAIL;

	char sql[4096];
	char* errMsg = NULL;

	sprintf(sql,"insert or replace into ocpp20_variable (componentName, componentInstance, variableName, variableInstance, variableCharacteristicsDataType, variableCharacteristicsUnit, variableCharacteristicsMaxLimit, variableAttributesType, variableAttributesTypeMutability, variableAttributesTypeValue, variableCharacteristicsMinLimit) VALUES('%s', '%s', '%s', '%s', '%s', '%s', %f, '%s', '%s', '%s', '%f');  SELECT * from ocpp20_variable;",
				 variable->component.name,
				 variable->component.instance,
				 variable->variable.name,
				 variable->variable.instance,
				 variable->variableCharacteristics.dataType,
				 variable->variableCharacteristics.unit,
				 variable->variableCharacteristics.maxLimit,
				 variable->variableAttribute[0].type,
				 variable->variableAttribute[0].mutability,
				 variable->variableAttribute[0].value,
				 variable->variableCharacteristics.minLimit);

	//* Execute SQL statement */
	if(sqlite3_exec(db, sql, DB_cbVariableSaveToDb, 0, &errMsg) != SQLITE_OK)
	{
		DEBUG_INFO("SQL error: %s\n", errMsg);
		result = FAIL;
	}

	return result;
}

int DB_cbVariableIsCreate(void *para, int columnCount, char **columnValue, char **columnName)
{
	memset(&ShmOCPP20Data->ControllerComponentVariable[0], 0x00, ARRAY_SIZE(ShmOCPP20Data->ControllerComponentVariable));

	if(atoi(columnValue[0]) == 0)
	{
		DB_updateBootType(BootReasonEnumType_PowerUp);
		// Create variable table content

		/* AlignedDataCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Enabled].component.name, "AlignedDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Enabled].variable.name, "Enabled");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Enabled].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Enabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Enabled].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Enabled].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Enabled]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Available].component.name, "AlignedDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Available].variable.name, "Available");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Available].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Available].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Available].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Available].variableAttribute[0].value, "TRUE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Available]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].component.name, "AlignedDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variable.name, "Measurands");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_MemberList]);
		ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableCharacteristics.maxLimit = 20;
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
			sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableAttribute[0].value, "Current.Import,"
																															   "Energy.Active.Import.Register,"
																															   "Energy.Active.Import.Interval,"
																															   "Power.Active.Import,"
																															   "Voltage,"
																															   "SoC,"
																															   "Current.Offered,"
																															   "Power.Offered");
		else
			sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableAttribute[0].value, "Current.Import,"
																															   "Energy.Active.Import.Register,"
																															   "Energy.Active.Import.Interval,"
																															   "Power.Active.Import,"
																															   "Voltage,"
																															   "Current.Offered");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Interval].component.name, "AlignedDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Interval].variable.name, "Interval");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Interval].variableCharacteristics.unit, "Seconds");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Interval].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Interval].variableCharacteristics.minLimit = 5;
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Interval].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Interval].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Interval].variableAttribute[0].value, "0");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Interval]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_SendDuringIdle].component.name, "AlignedDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_SendDuringIdle].variable.name, "SendDuringIdle");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_SendDuringIdle].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_SendDuringIdle].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_SendDuringIdle].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_SendDuringIdle].variableAttribute[0].value, "TRUE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_SendDuringIdle]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_SignReadings].component.name, "AlignedDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_SignReadings].variable.name, "SignReadings");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_SignReadings].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_SignReadings].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_SignReadings].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_SignReadings].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_SignReadings]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedMeasurands].component.name, "AlignedDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedMeasurands].variable.name, "TxEndedMeasurands");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedMeasurands].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_MemberList]);
		ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedMeasurands].variableCharacteristics.maxLimit = 10;
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedMeasurands].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedMeasurands].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
			sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedMeasurands].variableAttribute[0].value, "Current.Import,"
																																	  "Energy.Active.Import.Register,"
																																	  "Energy.Active.Import.Interval,"
																																	  "Power.Active.Import,"
																																	  "Voltage,"
																																	  "SoC");
		else
			sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedMeasurands].variableAttribute[0].value, "Current.Import,"
																																	  "Energy.Active.Import.Register,"
																																	  "Energy.Active.Import.Interval,"
																																	  "Power.Active.Import,"
																																	  "Voltage");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedMeasurands]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedInterval].component.name, "AlignedDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedInterval].variable.name, "TxEndedInterval");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedInterval].variableCharacteristics.unit, "Seconds");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedInterval].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedInterval].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedInterval].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedInterval].variableAttribute[0].value, "0");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedInterval]);

		/* AuthCtrlrVariable Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_Enabled].component.name, "AuthCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_Enabled].variable.name, "Enabled");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_Enabled].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_Enabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_Enabled].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_Enabled].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_Enabled]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AdditionalInfoItemsPerMessage].component.name, "AlignedDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AdditionalInfoItemsPerMessage].variable.name, "AdditionalInfoItemsPerMessage");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AdditionalInfoItemsPerMessage].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AdditionalInfoItemsPerMessage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AdditionalInfoItemsPerMessage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AdditionalInfoItemsPerMessage].variableAttribute[0].value, "0");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AdditionalInfoItemsPerMessage]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_OfflineTxForUnknownIdEnabled].component.name, "AuthCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_OfflineTxForUnknownIdEnabled].variable.name, "OfflineTxForUnknownIdEnabled");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_OfflineTxForUnknownIdEnabled].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_OfflineTxForUnknownIdEnabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_OfflineTxForUnknownIdEnabled].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_OfflineTxForUnknownIdEnabled].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_OfflineTxForUnknownIdEnabled]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AuthorizeRemoteStart].component.name, "AuthCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AuthorizeRemoteStart].variable.name, "AuthorizeRemoteStart");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AuthorizeRemoteStart].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AuthorizeRemoteStart].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AuthorizeRemoteStart].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AuthorizeRemoteStart].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AuthorizeRemoteStart]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalAuthorizeOffline].component.name, "AuthCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalAuthorizeOffline].variable.name, "LocalAuthorizeOffline");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalAuthorizeOffline].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalAuthorizeOffline].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalAuthorizeOffline].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalAuthorizeOffline].variableAttribute[0].value, "TRUE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalAuthorizeOffline]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalPreAuthorize].component.name, "AuthCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalPreAuthorize].variable.name, "LocalPreAuthorize");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalPreAuthorize].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalPreAuthorize].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalPreAuthorize].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalPreAuthorize].variableAttribute[0].value, "TRUE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalPreAuthorize]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_MasterPassGroupId].component.name, "AuthCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_MasterPassGroupId].variable.name, "MasterPassGroupId");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_MasterPassGroupId].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_string]);
		ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_MasterPassGroupId].variableCharacteristics.maxLimit = 36;
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_MasterPassGroupId].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_MasterPassGroupId].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_MasterPassGroupId].variableAttribute[0].value, " ");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_MasterPassGroupId]);

		/* AuthCacheCtrlr Variable Required item*/
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Enabled].component.name, "AuthCacheCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Enabled].variable.name, "Enabled");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Enabled].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Enabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Enabled].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Enabled].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Enabled]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Available].component.name, "AuthCacheCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Available].variable.name, "Available");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Available].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Available].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Available].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Available].variableAttribute[0].value, "TRUE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Available]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_LifeTime].component.name, "AuthCacheCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_LifeTime].variable.name, "LifeTime");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_LifeTime].variableCharacteristics.unit, "Seconds");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_LifeTime].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_LifeTime].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_LifeTime].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_LifeTime].variableAttribute[0].value, "TRUE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_LifeTime]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage].component.name, "AuthCacheCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage].variable.name, "Storage");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage].variableCharacteristics.maxLimit = (1024*10);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage].variableAttribute[0].value, "TRUE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Policy].component.name, "AuthCacheCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Policy].variable.name, "Policy");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Policy].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_OptionList]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Policy].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Policy].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Policy].variableAttribute[0].value, "LRU,LFU");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Policy]);

		/* ClockCtrlr Variable Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_DateTime].component.name, "ClockCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_DateTime].variable.name, "DateTime");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_DateTime].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_dateTime]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_DateTime].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_DateTime].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		getNowDatetime(ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_DateTime].variableAttribute[0].value);
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_DateTime]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NtpSource].component.name, "ClockCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NtpSource].variable.name, "NtpSource");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NtpSource].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_OptionList]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NtpSource].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NtpSource].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NtpSource].variableAttribute[0].value, "DHCP, manual");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NtpSource]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NtpServerUri].component.name, "ClockCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NtpServerUri].variable.name, "NtpServerUri");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NtpServerUri].variable.instance, "1");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NtpServerUri].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_string]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NtpServerUri].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NtpServerUri].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NtpServerUri].variableAttribute[0].value, " ");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NtpServerUri]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeOffset].component.name, "ClockCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeOffset].variable.name, "TimeOffset");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeOffset].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_string]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeOffset].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeOffset].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeOffset].variableAttribute[0].value, "+00:00");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeOffset]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NextTimeOffsetTransitionDateTime].component.name, "ClockCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NextTimeOffsetTransitionDateTime].variable.name, "NextTimeOffsetTransitionDateTime");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NextTimeOffsetTransitionDateTime].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_dateTime]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NextTimeOffsetTransitionDateTime].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NextTimeOffsetTransitionDateTime].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NextTimeOffsetTransitionDateTime].variableAttribute[0].value, " ");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NextTimeOffsetTransitionDateTime]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NextTransition_TimeOffset].component.name, "ClockCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NextTransition_TimeOffset].variable.name, "TimeOffset");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NextTransition_TimeOffset].variable.instance, "NextTransition");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NextTransition_TimeOffset].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_string]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NextTransition_TimeOffset].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NextTransition_TimeOffset].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NextTransition_TimeOffset].variableAttribute[0].value, "+00:00");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NextTransition_TimeOffset]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeSource].component.name, "ClockCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeSource].variable.name, "TimeSource");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeSource].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_SequenceList]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeSource].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeSource].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeSource].variableAttribute[0].value, "Heartbeat,RealTimeClock");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeSource]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeZone].component.name, "ClockCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeZone].variable.name, "TimeZone");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeZone].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_string]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeZone].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeZone].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeZone].variableAttribute[0].value, "UTC");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeZone]);

		/* ChargingStation Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_Available].component.name, "ChargingStation");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_Available].variable.name, "Available");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_Available].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_Available].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_Available].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_Available].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[ChargingStation_Available]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_AvailabilityState].component.name, "ChargingStation");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_AvailabilityState].variable.name, "AvailabilityState");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_AvailabilityState].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_OptionList]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_AvailabilityState].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_AvailabilityState].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_AvailabilityState].variableAttribute[0].value, "Available,Occupied,Reserved,Unavailable,Faulted");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[ChargingStation_AvailabilityState]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_SupplyPhases].component.name, "ChargingStation");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_SupplyPhases].variable.name, "SupplyPhases");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_SupplyPhases].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_SupplyPhases].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_SupplyPhases].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_SupplyPhases].variableAttribute[0].value, "3");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[ChargingStation_SupplyPhases]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_SystemUptimeSec].component.name, "ChargingStation");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_SystemUptimeSec].variable.name, "SystemUptimeSec");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_SystemUptimeSec].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_SystemUptimeSec].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_SystemUptimeSec].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_SystemUptimeSec].variableAttribute[0].value, "0");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[ChargingStation_SystemUptimeSec]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_FreeVend].component.name, "ChargingStation");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_FreeVend].variable.name, "FreeVend");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_FreeVend].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_FreeVend].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_FreeVend].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_FreeVend].variableAttribute[0].value, (ShmSysConfigAndInfo->SysConfig.AuthorisationMode?"TRUE":"FALSE"));
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[ChargingStation_FreeVend]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_FreeVendIdtag].component.name, "ChargingStation");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_FreeVendIdtag].variable.name, "FreeVendIdtag");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_FreeVendIdtag].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_string]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_FreeVendIdtag].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_FreeVendIdtag].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_FreeVendIdtag].variableAttribute[0].value, "FreeVendIdtag");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[ChargingStation_FreeVendIdtag]);

		/* Connector Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_Available].component.name, "Connector");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_Available].variable.name, "Available");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_Available].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_Available].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_Available].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_Available].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[Connector_Available]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_ConnectorType].component.name, "Connector");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_ConnectorType].variable.name, "ConnectorType");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_ConnectorType].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_string]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_ConnectorType].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_ConnectorType].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_ConnectorType].variableAttribute[0].value, " ");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[Connector_ConnectorType]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_SupplyPhases].component.name, "Connector");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_SupplyPhases].variable.name, "SupplyPhases");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_SupplyPhases].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_SupplyPhases].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_SupplyPhases].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_SupplyPhases].variableAttribute[0].value, "3");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[Connector_SupplyPhases]);

		/* CustomizationCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[CustomizationCtrlr_CustomImplementationEnabled].component.name, "CustomizationCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[CustomizationCtrlr_CustomImplementationEnabled].variable.name, "CustomImplementationEnabled");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[CustomizationCtrlr_CustomImplementationEnabled].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[CustomizationCtrlr_CustomImplementationEnabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[CustomizationCtrlr_CustomImplementationEnabled].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[CustomizationCtrlr_CustomImplementationEnabled].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[CustomizationCtrlr_CustomImplementationEnabled]);

		/* DeviceDataCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetReport_ItemsPerMessage].component.name, "DeviceDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetReport_ItemsPerMessage].variable.instance, "GetReport");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetReport_ItemsPerMessage].variable.name, "ItemsPerMessage");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetReport_ItemsPerMessage].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetReport_ItemsPerMessage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetReport_ItemsPerMessage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetReport_ItemsPerMessage].variableAttribute[0].value, "10");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetReport_ItemsPerMessage]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetVariables_ItemsPerMessage].component.name, "DeviceDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetVariables_ItemsPerMessage].variable.instance, "GetVariables");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetVariables_ItemsPerMessage].variable.name, "ItemsPerMessage");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetVariables_ItemsPerMessage].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetVariables_ItemsPerMessage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetVariables_ItemsPerMessage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetVariables_ItemsPerMessage].variableAttribute[0].value, "10");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetVariables_ItemsPerMessage]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetReport_BytesPerMessage].component.name, "DeviceDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetReport_BytesPerMessage].variable.instance, "GetReport");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetReport_BytesPerMessage].variable.name, "BytesPerMessage");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetReport_BytesPerMessage].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetReport_BytesPerMessage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetReport_BytesPerMessage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetReport_BytesPerMessage].variableAttribute[0].value, "2048");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetReport_BytesPerMessage]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetVariables_BytesPerMessage].component.name, "DeviceDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetVariables_BytesPerMessage].variable.instance, "GetVariables");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetVariables_BytesPerMessage].variable.name, "BytesPerMessage");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetVariables_BytesPerMessage].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetVariables_BytesPerMessage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetVariables_BytesPerMessage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetVariables_BytesPerMessage].variableAttribute[0].value, "2048");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetVariables_BytesPerMessage]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_ConfigurationValueSize].component.name, "DeviceDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_ConfigurationValueSize].variable.name, "ConfigurationValueSize");
		ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_ConfigurationValueSize].variableCharacteristics.maxLimit = 1000;
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_ConfigurationValueSize].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_ConfigurationValueSize].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_ConfigurationValueSize].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_ConfigurationValueSize].variableAttribute[0].value, "10");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_ConfigurationValueSize]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_ReportingValueSize].component.name, "DeviceDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_ReportingValueSize].variable.name, "ReportingValueSize");
		ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_ReportingValueSize].variableCharacteristics.maxLimit = 2500;
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_ReportingValueSize].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_ReportingValueSize].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_ReportingValueSize].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_ReportingValueSize].variableAttribute[0].value, "10");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_ReportingValueSize]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_SetVariables_ItemsPerMessage].component.name, "DeviceDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_SetVariables_ItemsPerMessage].variable.instance, "SetVariables");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_SetVariables_ItemsPerMessage].variable.name, "ItemsPerMessage");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_SetVariables_ItemsPerMessage].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_SetVariables_ItemsPerMessage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_SetVariables_ItemsPerMessage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_SetVariables_ItemsPerMessage].variableAttribute[0].value, "10");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_SetVariables_ItemsPerMessage]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_SetVariables_BytesPerMessage].component.name, "DeviceDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_SetVariables_BytesPerMessage].variable.instance, "SetVariables");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_SetVariables_BytesPerMessage].variable.name, "BytesPerMessage");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_SetVariables_BytesPerMessage].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_SetVariables_BytesPerMessage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_SetVariables_BytesPerMessage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_SetVariables_BytesPerMessage].variableAttribute[0].value, "2048");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_SetVariables_BytesPerMessage]);

		/* DisplayMessageCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_Enabled].component.name, "DisplayMessageCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_Enabled].variable.name, "Enabled");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_Enabled].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_Enabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_Enabled].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_Enabled].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_Enabled]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_Available].component.name, "DisplayMessageCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_Available].variable.name, "Available");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_Available].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_Available].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_Available].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_Available].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_Available]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages].component.name, "DisplayMessageCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages].variable.name, "DisplayMessages");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages].variableCharacteristics.maxLimit = 1;
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages].variableAttribute[0].value, "%s", "1");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_SupportedFormats].component.name, "DisplayMessageCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_SupportedFormats].variable.name, "SupportedFormats");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_SupportedFormats].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_MemberList]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_SupportedFormats].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_SupportedFormats].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_SupportedFormats].variableAttribute[0].value, " ");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_SupportedFormats]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_SupportedPriorities].component.name, "DisplayMessageCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_SupportedPriorities].variable.name, "SupportedPriorities");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_SupportedPriorities].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_MemberList]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_SupportedPriorities].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_SupportedPriorities].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_SupportedPriorities].variableAttribute[0].value, " ");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_SupportedPriorities]);

		/* EVSE Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_Available].component.name, "EVSE");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_Available].variable.name, "Available");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_Available].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_Available].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_Available].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_Available].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[EVSE_Available]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_AvailabilityState].component.name, "EVSE");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_AvailabilityState].variable.name, "AvailabilityState");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_AvailabilityState].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_OptionList]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_AvailabilityState].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_AvailabilityState].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_AvailabilityState].variableAttribute[0].value, "Available,Occupied,Reserved,Unavailable,Faulted");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[EVSE_AvailabilityState]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_SupplyPhases].component.name, "EVSE");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_SupplyPhases].variable.name, "SupplyPhases");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_SupplyPhases].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_SupplyPhases].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_SupplyPhases].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_SupplyPhases].variableAttribute[0].value, "3");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[EVSE_SupplyPhases]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_Power].component.name, "EVSE");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_Power].variable.name, "Power");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_Power].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_decimal]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_Power].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_Power].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_Power].variableAttribute[0].value, "7700");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[EVSE_Power]);

		/* LocalAuthListCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Enabled].component.name, "LocalAuthListCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Enabled].variable.name, "Enabled");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Enabled].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Enabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Enabled].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Enabled].variableAttribute[0].value, "TRUE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Enabled]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].component.name, "LocalAuthListCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variable.name, "Entries");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variableCharacteristics.maxLimit = 5000;
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variableAttribute[0].value, "5000");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Available].component.name, "LocalAuthListCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Available].variable.name, "Available");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Available].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Available].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Available].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Available].variableAttribute[0].value, "TRUE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Available]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_ItemsPerMessage].component.name, "LocalAuthListCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_ItemsPerMessage].variable.name, "ItemsPerMessage");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_ItemsPerMessage].variable.instance, "SendLocalList");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_ItemsPerMessage].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_ItemsPerMessage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_ItemsPerMessage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_ItemsPerMessage].variableAttribute[0].value, "500");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_ItemsPerMessage]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_BytesPerMessage].component.name, "LocalAuthListCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_BytesPerMessage].variable.name, "BytesPerMessage");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_BytesPerMessage].variable.instance, "SendLocalList");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_BytesPerMessage].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_BytesPerMessage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_BytesPerMessage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_BytesPerMessage].variableAttribute[0].value, "20480");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_BytesPerMessage]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage].component.name, "LocalAuthListCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage].variable.name, "Storage");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage].variableCharacteristics.maxLimit = (1024*10);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage].variableAttribute[0].value, "100000");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage]);

		/* MonitoringCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_Enabled].component.name, "MonitoringCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_Enabled].variable.instance, "Enabled");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_Enabled].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_Enabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_Enabled].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_Enabled].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_Enabled]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_Available].component.name, "MonitoringCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_Available].variable.instance, "Available");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_Available].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_Available].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_Available].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_Available].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_Available]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_ClearVariableMonitoring_ItemsPerMessage].component.name, "MonitoringCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_ClearVariableMonitoring_ItemsPerMessage].variable.instance, "ClearVariableMonitoring");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_ClearVariableMonitoring_ItemsPerMessage].variable.name, "ItemsPerMessage");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_ClearVariableMonitoring_ItemsPerMessage].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_ClearVariableMonitoring_ItemsPerMessage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_ClearVariableMonitoring_ItemsPerMessage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_ClearVariableMonitoring_ItemsPerMessage].variableAttribute[0].value, "1");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_ClearVariableMonitoring_ItemsPerMessage]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_SetVariableMonitoring_ItemsPerMessage].component.name, "MonitoringCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_SetVariableMonitoring_ItemsPerMessage].variable.instance, "SetVariableMonitoring");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_SetVariableMonitoring_ItemsPerMessage].variable.name, "ItemsPerMessage");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_SetVariableMonitoring_ItemsPerMessage].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_SetVariableMonitoring_ItemsPerMessage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_SetVariableMonitoring_ItemsPerMessage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_SetVariableMonitoring_ItemsPerMessage].variableAttribute[0].value, "1");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_SetVariableMonitoring_ItemsPerMessage]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_ClearVariableMonitoring_BytesPerMessage].component.name, "MonitoringCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_ClearVariableMonitoring_BytesPerMessage].variable.instance, "ClearVariableMonitoring");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_ClearVariableMonitoring_BytesPerMessage].variable.name, "BytesPerMessage");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_ClearVariableMonitoring_BytesPerMessage].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_ClearVariableMonitoring_BytesPerMessage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_ClearVariableMonitoring_BytesPerMessage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_ClearVariableMonitoring_BytesPerMessage].variableAttribute[0].value, "2048");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_ClearVariableMonitoring_BytesPerMessage]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_SetVariableMonitoring_BytesPerMessage].component.name, "MonitoringCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_SetVariableMonitoring_BytesPerMessage].variable.instance, "SetVariableMonitoring");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_SetVariableMonitoring_BytesPerMessage].variable.name, "BytesPerMessage");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_SetVariableMonitoring_BytesPerMessage].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_SetVariableMonitoring_BytesPerMessage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_SetVariableMonitoring_BytesPerMessage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_SetVariableMonitoring_BytesPerMessage].variableAttribute[0].value, "2048");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_SetVariableMonitoring_BytesPerMessage]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_OfflineQueuingSeverity].component.name, "MonitoringCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_OfflineQueuingSeverity].variable.name, "OfflineQueuingSeverity");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_OfflineQueuingSeverity].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_OfflineQueuingSeverity].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_OfflineQueuingSeverity].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_OfflineQueuingSeverity].variableAttribute[0].value, "2048");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_OfflineQueuingSeverity]);

		/* OCPPCommCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_ActiveNetworkProfile].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_ActiveNetworkProfile].variable.name, "ActiveNetworkProfile");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_ActiveNetworkProfile].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_ActiveNetworkProfile].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_ActiveNetworkProfile].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_ActiveNetworkProfile].variableAttribute[0].value, "1");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_ActiveNetworkProfile]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageTimeout].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageTimeout].variable.instance, "Default");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageTimeout].variable.name, "MessageTimeout");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageTimeout].variableCharacteristics.unit, "Seconds");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageTimeout].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageTimeout].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageTimeout].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageTimeout].variableAttribute[0].value, "30");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageTimeout]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_FileTransferProtocols].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_FileTransferProtocols].variable.name, "FileTransferProtocols");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_FileTransferProtocols].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_MemberList]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_FileTransferProtocols].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_FileTransferProtocols].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_FileTransferProtocols].variableAttribute[0].value, "FTP,FTPS,HTTP,HTTPS");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_FileTransferProtocols]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_HeartbeatInterval].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_HeartbeatInterval].variable.name, "HeartbeatInterval");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_HeartbeatInterval].variableCharacteristics.unit, "Seconds");
		ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_HeartbeatInterval].variableCharacteristics.minLimit = 10;
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_HeartbeatInterval].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_HeartbeatInterval].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_HeartbeatInterval].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_HeartbeatInterval].variableAttribute[0].value, "30");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_HeartbeatInterval]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_NetworkConfigurationPriority].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_NetworkConfigurationPriority].variable.name, "NetworkConfigurationPriority");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_NetworkConfigurationPriority].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_SequenceList]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_NetworkConfigurationPriority].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_NetworkConfigurationPriority].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_NetworkConfigurationPriority].variableAttribute[0].value, "[0]");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_NetworkConfigurationPriority]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_NetworkProfileConnectionAttempts].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_NetworkProfileConnectionAttempts].variable.name, "NetworkProfileConnectionAttempts");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_NetworkProfileConnectionAttempts].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_NetworkProfileConnectionAttempts].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_NetworkProfileConnectionAttempts].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_NetworkProfileConnectionAttempts].variableAttribute[0].value, "3");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_NetworkProfileConnectionAttempts]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_OfflineThreshold].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_OfflineThreshold].variable.name, "OfflineThreshold");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_OfflineThreshold].variableCharacteristics.unit, "Seconds");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_OfflineThreshold].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_OfflineThreshold].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_OfflineThreshold].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_OfflineThreshold].variableAttribute[0].value, "30");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_OfflineThreshold]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_QueueAllMessages].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_QueueAllMessages].variable.name, "QueueAllMessages");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_QueueAllMessages].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_QueueAllMessages].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_QueueAllMessages].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_QueueAllMessages].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_QueueAllMessages]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttempts].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttempts].variable.instance, "TransactionEvent");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttempts].variable.name, "MessageAttempts");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttempts].variableCharacteristics.unit, "Seconds");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttempts].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttempts].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttempts].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttempts].variableAttribute[0].value, "3");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttempts]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttemptInterval].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttemptInterval].variable.instance, "TransactionEvent");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttemptInterval].variable.name, "MessageAttemptInterval");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttemptInterval].variableCharacteristics.unit, "Seconds");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttemptInterval].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttemptInterval].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttemptInterval].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttemptInterval].variableAttribute[0].value, "30");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttemptInterval]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_UnlockOnEVSideDisconnect].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_UnlockOnEVSideDisconnect].variable.name, "UnlockOnEVSideDisconnect");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_UnlockOnEVSideDisconnect].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_UnlockOnEVSideDisconnect].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_UnlockOnEVSideDisconnect].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_UnlockOnEVSideDisconnect].variableAttribute[0].value, "TRUE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_UnlockOnEVSideDisconnect]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_WebSocketPingInterval].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_WebSocketPingInterval].variable.name, "WebSocketPingInterval");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_WebSocketPingInterval].variableCharacteristics.unit, "Seconds");
		ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_WebSocketPingInterval].variableCharacteristics.minLimit = 10;
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_WebSocketPingInterval].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_WebSocketPingInterval].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_WebSocketPingInterval].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_WebSocketPingInterval].variableAttribute[0].value, "30");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_WebSocketPingInterval]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_ResetRetries].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_ResetRetries].variable.name, "ResetRetries");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_ResetRetries].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_ResetRetries].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_ResetRetries].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_ResetRetries].variableAttribute[0].value, "3");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_ResetRetries]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_PublicKeyWithSignedMeterValue].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_PublicKeyWithSignedMeterValue].variable.name, "PublicKeyWithSignedMeterValue");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_PublicKeyWithSignedMeterValue].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_OptionList]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_PublicKeyWithSignedMeterValue].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_PublicKeyWithSignedMeterValue].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_PublicKeyWithSignedMeterValue].variableAttribute[0].value, "Never,OncePerTransaction,EveryMeterValue");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_PublicKeyWithSignedMeterValue]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_VariableVersion].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_VariableVersion].variable.name, "VariableVersion");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_VariableVersion].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_VariableVersion].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_VariableVersion].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_VariableVersion].variableAttribute[0].value, "%d", variableVersion);
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_VariableVersion]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationPeriodically].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationPeriodically].variable.name, "StatusNotificationPeriodically");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationPeriodically].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationPeriodically].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationPeriodically].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationPeriodically].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationPeriodically]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationInterval].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationInterval].variable.name, "StatusNotificationInterval");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationInterval].variableCharacteristics.unit, "Seconds");
		ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationInterval].variableCharacteristics.minLimit = 10;
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationInterval].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationInterval].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationInterval].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationInterval].variableAttribute[0].value, "120");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationInterval]);

		/* ReservationCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_Enabled].component.name, "ReservationCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_Enabled].variable.name, "Enabled");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_Enabled].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_Enabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_Enabled].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_Enabled].variableAttribute[0].value, "TRUE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_Enabled]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_Available].component.name, "ReservationCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_Available].variable.name, "Available");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_Available].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_Available].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_Available].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_Available].variableAttribute[0].value, "TRUE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_Available]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_NonEvseSpecific].component.name, "ReservationCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_NonEvseSpecific].variable.name, "NonEvseSpecific");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_NonEvseSpecific].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_NonEvseSpecific].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_NonEvseSpecific].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_NonEvseSpecific].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_NonEvseSpecific]);

		/* SampledDataCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_Enabled].component.name, "SampledDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_Enabled].variable.name, "Enabled");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_Enabled].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_Enabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_Enabled].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_Enabled].variableAttribute[0].value, "TRUE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_Enabled]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_Available].component.name, "SampledDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_Available].variable.name, "Available");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_Available].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_Available].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_Available].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_Available].variableAttribute[0].value, "TRUE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_Available]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_SignReadings].component.name, "SampledDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_SignReadings].variable.name, "SignReadings");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_SignReadings].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_SignReadings].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_SignReadings].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_SignReadings].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_SignReadings]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].component.name, "SampledDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].variable.name, "TxEndedMeasurands");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_MemberList]);
		ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].variableCharacteristics.maxLimit = 10;
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
			sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].variableAttribute[0].value, "Current.Import,"
																																	  "Energy.Active.Import.Register,"
																																	  "Energy.Active.Import.Interval,"
																																	  "Power.Active.Import,"
																																	  "Voltage,"
																																	  "SoC");
		else
			sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].variableAttribute[0].value, "Current.Import,"
					 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	  "Energy.Active.Import.Register,"
																																	  "Energy.Active.Import.Interval,"
																																	  "Power.Active.Import,"
																																	  "Voltage");

		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedInterval].component.name, "SampledDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedInterval].variable.name, "TxEndedInterval");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedInterval].variableCharacteristics.unit, "Seconds");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedInterval].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedInterval].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedInterval].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedInterval].variableAttribute[0].value, "0");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedInterval]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxStartedMeasurands].component.name, "SampledDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxStartedMeasurands].variable.name, "TxStartedMeasurands");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxStartedMeasurands].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_MemberList]);
		ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxStartedMeasurands].variableCharacteristics.maxLimit = 10;
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxStartedMeasurands].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxStartedMeasurands].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxStartedMeasurands].variableAttribute[0].value, " ");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxStartedMeasurands]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].component.name, "SampledDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variable.name, "TxUpdatedMeasurands");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_MemberList]);
		ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableCharacteristics.maxLimit = 10;
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
			sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].value, "Current.Import,"
																																		"Energy.Active.Import.Register,"
																																		"Energy.Active.Import.Interval,"
																																		"Power.Active.Import,"
																																		"Voltage,"
																																		"SoC,"
																																		"Current.Offered,"
																																		"Power.Offered");
		else
			sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].value, "Current.Import,"
																																		"Energy.Active.Import.Register,"
																																		"Energy.Active.Import.Interval,"
																																		"Power.Active.Import,"
																																		"Voltage,"
																																		"Current.Offered");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedInterval].component.name, "SampledDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedInterval].variable.name, "TxUpdatedInterval");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedInterval].variableCharacteristics.unit, "Seconds");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedInterval].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedInterval].variableCharacteristics.minLimit = 3;
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedInterval].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedInterval].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedInterval].variableAttribute[0].value, "30");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedInterval]);

		/* SecurityCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].component.name, "SecurityCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variable.name, "BasicAuthPassword");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_string]);
		ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variableCharacteristics.maxLimit = 40;
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_WriteOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variableAttribute[0].value, "%s", (strlen((char*)ShmSysConfigAndInfo->SysConfig.OcppSecurityPassword)>0?(char*)ShmSysConfigAndInfo->SysConfig.OcppSecurityPassword:"00000000"));
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_Identity].component.name, "SecurityCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_Identity].variable.name, "Identity");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_Identity].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_string]);
		ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_Identity].variableCharacteristics.maxLimit = 48;
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_Identity].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_Identity].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_Identity].variableAttribute[0].value, "%s", ShmSysConfigAndInfo->SysConfig.ChargeBoxId);
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_Identity]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_OrganizationName].component.name, "SecurityCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_OrganizationName].variable.name, "OrganizationName");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_OrganizationName].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_string]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_OrganizationName].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_OrganizationName].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_OrganizationName].variableAttribute[0].value, "%s", ShmSysConfigAndInfo->SysConfig.chargePointVendor);
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_OrganizationName]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries].component.name, "SecurityCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries].variable.name, "CertificateEntries");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries].variableCharacteristics.maxLimit = 1;
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries].variableAttribute[0].value, "1");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_SecurityProfile].component.name, "SecurityCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_SecurityProfile].variable.name, "SecurityProfile");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_SecurityProfile].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_SecurityProfile].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_SecurityProfile].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_SecurityProfile].variableAttribute[0].value, "%d", ShmSysConfigAndInfo->SysConfig.OcppSecurityProfile);
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_SecurityProfile]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_AdditionalRootCertificateCheck].component.name, "SecurityCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_AdditionalRootCertificateCheck].variable.name, "AdditionalRootCertificateCheck");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_AdditionalRootCertificateCheck].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_AdditionalRootCertificateCheck].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_AdditionalRootCertificateCheck].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_AdditionalRootCertificateCheck].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_AdditionalRootCertificateCheck]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_MaxCertificateChainSize].component.name, "SecurityCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_MaxCertificateChainSize].variable.name, "MaxCertificateChainSize");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_MaxCertificateChainSize].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_MaxCertificateChainSize].variableCharacteristics.maxLimit = 10000;
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_MaxCertificateChainSize].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_MaxCertificateChainSize].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_MaxCertificateChainSize].variableAttribute[0].value, "10000");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_MaxCertificateChainSize]);

		/* SmartChargingCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Enabled].component.name, "SmartChargingCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Enabled].variable.name, "Enabled");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Enabled].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Enabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Enabled].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Enabled].variableAttribute[0].value, "TRUE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Enabled]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Available].component.name, "SmartChargingCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Available].variable.name, "Available");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Available].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Available].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Available].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Available].variableAttribute[0].value, "TRUE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Available]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ACPhaseSwitchingSupported].component.name, "SmartChargingCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ACPhaseSwitchingSupported].variable.name, "ACPhaseSwitchingSupported");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ACPhaseSwitchingSupported].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ACPhaseSwitchingSupported].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ACPhaseSwitchingSupported].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ACPhaseSwitchingSupported].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ACPhaseSwitchingSupported]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ProfileStackLevel].component.name, "SmartChargingCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ProfileStackLevel].variable.name, "ProfileStackLevel");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ProfileStackLevel].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ProfileStackLevel].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ProfileStackLevel].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ProfileStackLevel].variableAttribute[0].value, "3");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ProfileStackLevel]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_RateUnit].component.name, "SmartChargingCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_RateUnit].variable.name, "RateUnit");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_RateUnit].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_MemberList]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_RateUnit].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_RateUnit].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_RateUnit].variableAttribute[0].value, "A,W");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_RateUnit]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_PeriodsPerSchedule].component.name, "SmartChargingCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_PeriodsPerSchedule].variable.name, "PeriodsPerSchedule");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_PeriodsPerSchedule].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_PeriodsPerSchedule].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_PeriodsPerSchedule].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_PeriodsPerSchedule].variableAttribute[0].value, "10");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_PeriodsPerSchedule]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ExternalControlSignalsEnabled].component.name, "SmartChargingCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ExternalControlSignalsEnabled].variable.name, "ExternalControlSignalsEnabled");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ExternalControlSignalsEnabled].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ExternalControlSignalsEnabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ExternalControlSignalsEnabled].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ExternalControlSignalsEnabled].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ExternalControlSignalsEnabled]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_NotifyChargingLimitWithSchedules].component.name, "SmartChargingCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_NotifyChargingLimitWithSchedules].variable.name, "NotifyChargingLimitWithSchedules");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_NotifyChargingLimitWithSchedules].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_NotifyChargingLimitWithSchedules].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_NotifyChargingLimitWithSchedules].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_NotifyChargingLimitWithSchedules].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_NotifyChargingLimitWithSchedules]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Phases3to1].component.name, "SmartChargingCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Phases3to1].variable.name, "Phases3to1");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Phases3to1].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Phases3to1].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Phases3to1].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Phases3to1].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Phases3to1]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].component.name, "SmartChargingCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].variable.name, "Entries");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].variableCharacteristics.maxLimit = 10;
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].variableAttribute[0].value, "10");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_LimitChangeSignificance].component.name, "SmartChargingCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_LimitChangeSignificance].variable.name, "LimitChangeSignificance");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_LimitChangeSignificance].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_decimal]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_LimitChangeSignificance].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_LimitChangeSignificance].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_LimitChangeSignificance].variableAttribute[0].value, "1");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_LimitChangeSignificance]);

		/* TariffCostCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_Enabled].component.name, "TariffCostCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_Enabled].variable.instance, "Tariff");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_Enabled].variable.name, "Enabled");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_Enabled].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_Enabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_Enabled].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_Enabled].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[Tariff_Enabled]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_Available].component.name, "TariffCostCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_Available].variable.instance, "Tariff");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_Available].variable.name, "Available");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_Available].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_Available].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_Available].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_Available].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[Tariff_Available]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_TariffFallbackMessage].component.name, "TariffCostCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_TariffFallbackMessage].variable.name, "TariffFallbackMessage");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_TariffFallbackMessage].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_string]);
		ShmOCPP20Data->ControllerComponentVariable[Tariff_TariffFallbackMessage].variableCharacteristics.maxLimit = 255;
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_TariffFallbackMessage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_TariffFallbackMessage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_TariffFallbackMessage].variableAttribute[0].value, " ");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[Tariff_TariffFallbackMessage]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Enabled].component.name, "TariffCostCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Enabled].variable.instance, "Cost");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Enabled].variable.name, "Enabled");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Enabled].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Enabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Enabled].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Enabled].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[Cost_Enabled]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Available].component.name, "TariffCostCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Available].variable.instance, "Cost");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Available].variable.name, "Available");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Available].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Available].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Available].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Available].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[Cost_Available]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_TotalCostFallbackMessage].component.name, "TariffCostCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_TotalCostFallbackMessage].variable.name, "TotalCostFallbackMessage");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_TotalCostFallbackMessage].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_string]);
		ShmOCPP20Data->ControllerComponentVariable[Cost_TotalCostFallbackMessage].variableCharacteristics.maxLimit = 255;
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_TotalCostFallbackMessage].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_TotalCostFallbackMessage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_TotalCostFallbackMessage].variableAttribute[0].value, " ");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[Cost_TotalCostFallbackMessage]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Currency].component.name, "TariffCostCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Currency].variable.name, "Currency");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Currency].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_string]);
		ShmOCPP20Data->ControllerComponentVariable[Cost_Currency].variableCharacteristics.maxLimit = 3;
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Currency].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Currency].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Currency].variableAttribute[0].value, "NTD");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[Cost_Currency]);

		/* TxCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_ChargingBeforeAcceptedEnabled].component.name, "TxCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_ChargingBeforeAcceptedEnabled].variable.name, "ChargingBeforeAcceptedEnabled");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_ChargingBeforeAcceptedEnabled].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_ChargingBeforeAcceptedEnabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_ChargingBeforeAcceptedEnabled].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_ChargingBeforeAcceptedEnabled].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_ChargingBeforeAcceptedEnabled]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut].component.name, "TxCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut].variable.name, "EVConnectionTimeOut");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut].variableCharacteristics.unit, "Seconds");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut].variableAttribute[0].value, "180");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnEVSideDisconnect].component.name, "TxCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnEVSideDisconnect].variable.name, "StopTxOnEVSideDisconnect");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnEVSideDisconnect].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnEVSideDisconnect].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnEVSideDisconnect].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnEVSideDisconnect].variableAttribute[0].value, "TRUE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnEVSideDisconnect]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxBeforeAcceptedEnabled].component.name, "TxCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxBeforeAcceptedEnabled].variable.name, "TxBeforeAcceptedEnabled");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxBeforeAcceptedEnabled].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxBeforeAcceptedEnabled].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxBeforeAcceptedEnabled].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxBeforeAcceptedEnabled].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxBeforeAcceptedEnabled]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStartPoint].component.name, "TxCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStartPoint].variable.name, "TxStartPoint");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStartPoint].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_OptionList]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStartPoint].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStartPoint].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStartPoint].variableAttribute[0].value, "PowerPathClosed");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStartPoint]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStopPoint].component.name, "TxCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStopPoint].variable.name, "TxStopPoint");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStopPoint].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_OptionList]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStopPoint].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStopPoint].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStopPoint].variableAttribute[0].value, "PowerPathClosed");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStopPoint]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_MaxEnergyOnInvalidId].component.name, "TxCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_MaxEnergyOnInvalidId].variable.name, "MaxEnergyOnInvalidId");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_MaxEnergyOnInvalidId].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_integer]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_MaxEnergyOnInvalidId].variableCharacteristics.unit, "Wh");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_MaxEnergyOnInvalidId].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_MaxEnergyOnInvalidId].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_MaxEnergyOnInvalidId].variableAttribute[0].value, "0");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_MaxEnergyOnInvalidId]);

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId].component.name, "TxCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId].variable.name, "StopTxOnInvalidId");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId].variableCharacteristics.dataType, "%s", DataEnumTypeStr[DataEnumType_boolean]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Actual]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId].variableAttribute[0].value, "FALSE");
		DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId]);
	}
	else
	{
		// Variable name init

		/* AlignedDataCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Enabled].component.name, "AlignedDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Enabled].variable.name, "Enabled");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Available].component.name, "AlignedDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Available].variable.name, "Available");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].component.name, "AlignedDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variable.name, "Measurands");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Interval].component.name, "AlignedDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Interval].variable.name, "Interval");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_SendDuringIdle].component.name, "AlignedDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_SendDuringIdle].variable.name, "SendDuringIdle");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_SignReadings].component.name, "AlignedDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_SignReadings].variable.name, "SignReadings");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedMeasurands].component.name, "AlignedDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedMeasurands].variable.name, "TxEndedMeasurands");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedInterval].component.name, "AlignedDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_TxEndedInterval].variable.name, "TxEndedInterval");

		/* AuthCtrlrVariable Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_Enabled].component.name, "AuthCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_Enabled].variable.name, "Enabled");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AdditionalInfoItemsPerMessage].component.name, "AlignedDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AdditionalInfoItemsPerMessage].variable.name, "AdditionalInfoItemsPerMessage");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_OfflineTxForUnknownIdEnabled].component.name, "AuthCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_OfflineTxForUnknownIdEnabled].variable.name, "OfflineTxForUnknownIdEnabled");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AuthorizeRemoteStart].component.name, "AuthCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_AuthorizeRemoteStart].variable.name, "AuthorizeRemoteStart");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalAuthorizeOffline].component.name, "AuthCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalAuthorizeOffline].variable.name, "LocalAuthorizeOffline");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalPreAuthorize].component.name, "AuthCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalPreAuthorize].variable.name, "LocalPreAuthorize");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_MasterPassGroupId].component.name, "AuthCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_MasterPassGroupId].variable.name, "MasterPassGroupId");

		/* AuthCacheCtrlr Variable Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Enabled].component.name, "AuthCacheCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Enabled].variable.name, "Enabled");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Available].component.name, "AuthCacheCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Available].variable.name, "Available");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_LifeTime].component.name, "AuthCacheCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_LifeTime].variable.name, "LifeTime");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage].component.name, "AuthCacheCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Storage].variable.name, "Storage");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Policy].component.name, "AuthCacheCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Policy].variable.name, "Policy");

		/* ClockCtrlr Variable Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_DateTime].component.name, "ClockCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_DateTime].variable.name, "DateTime");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NtpSource].component.name, "ClockCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NtpSource].variable.name, "NtpSource");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NtpServerUri].component.name, "ClockCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NtpServerUri].variable.name, "NtpServerUri");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NtpServerUri].variable.instance, "1");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeOffset].component.name, "ClockCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeOffset].variable.name, "TimeOffset");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NextTimeOffsetTransitionDateTime].component.name, "ClockCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NextTimeOffsetTransitionDateTime].variable.name, "NextTimeOffsetTransitionDateTime");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NextTransition_TimeOffset].component.name, "ClockCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NextTransition_TimeOffset].variable.name, "TimeOffset");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_NextTransition_TimeOffset].variable.instance, "NextTransition");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeSource].component.name, "ClockCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeSource].variable.name, "TimeSource");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeZone].component.name, "ClockCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ClockCtrlr_TimeZone].variable.name, "TimeZone");

		/* ChargingStation Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_Available].component.name, "ChargingStation");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_Available].variable.name, "Available");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_AvailabilityState].component.name, "ChargingStation");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_AvailabilityState].variable.name, "AvailabilityState");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_SupplyPhases].component.name, "ChargingStation");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_SupplyPhases].variable.name, "SupplyPhases");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_SystemUptimeSec].component.name, "ChargingStation");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_SystemUptimeSec].variable.name, "SystemUptimeSec");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_FreeVend].component.name, "ChargingStation");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_FreeVend].variable.name, "FreeVend");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_FreeVendIdtag].component.name, "ChargingStation");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ChargingStation_FreeVendIdtag].variable.name, "FreeVendIdtag");

		/* Connector Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_Available].component.name, "Connector");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_Available].variable.name, "Available");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_ConnectorType].component.name, "Connector");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_ConnectorType].variable.name, "ConnectorType");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_SupplyPhases].component.name, "Connector");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Connector_SupplyPhases].variable.name, "SupplyPhases");

		/* CustomizationCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[CustomizationCtrlr_CustomImplementationEnabled].component.name, "CustomizationCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[CustomizationCtrlr_CustomImplementationEnabled].variable.name, "CustomImplementationEnabled");

		/* DeviceDataCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetReport_ItemsPerMessage].component.name, "DeviceDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetReport_ItemsPerMessage].variable.instance, "GetReport");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetReport_ItemsPerMessage].variable.name, "ItemsPerMessage");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetVariables_ItemsPerMessage].component.name, "DeviceDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetVariables_ItemsPerMessage].variable.instance, "GetVariables");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetVariables_ItemsPerMessage].variable.name, "ItemsPerMessage");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetReport_BytesPerMessage].component.name, "DeviceDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetReport_BytesPerMessage].variable.instance, "GetReport");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetReport_BytesPerMessage].variable.name, "BytesPerMessage");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetVariables_BytesPerMessage].component.name, "DeviceDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetVariables_BytesPerMessage].variable.instance, "GetVariables");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_GetVariables_BytesPerMessage].variable.name, "BytesPerMessage");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_ConfigurationValueSize].component.name, "DeviceDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_ConfigurationValueSize].variable.name, "ConfigurationValueSize");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_ReportingValueSize].component.name, "DeviceDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_ReportingValueSize].variable.name, "ReportingValueSize");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_SetVariables_ItemsPerMessage].component.name, "DeviceDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_SetVariables_ItemsPerMessage].variable.instance, "SetVariables");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_SetVariables_ItemsPerMessage].variable.name, "ItemsPerMessage");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_SetVariables_BytesPerMessage].component.name, "DeviceDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_SetVariables_BytesPerMessage].variable.instance, "SetVariables");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DeviceDataCtrlr_SetVariables_BytesPerMessage].variable.name, "BytesPerMessage");

		/* DisplayMessageCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_Enabled].component.name, "DisplayMessageCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_Enabled].variable.name, "Enabled");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_Available].component.name, "DisplayMessageCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_Available].variable.name, "Available");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages].component.name, "DisplayMessageCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_DisplayMessages].variable.name, "DisplayMessages");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_SupportedFormats].component.name, "DisplayMessageCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_SupportedFormats].variable.name, "SupportedFormats");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_SupportedPriorities].component.name, "DisplayMessageCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[DisplayMessageCtrlr_SupportedPriorities].variable.name, "SupportedPriorities");

		/* EVSE Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_Available].component.name, "EVSE");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_Available].variable.name, "Available");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_AvailabilityState].component.name, "EVSE");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_AvailabilityState].variable.name, "AvailabilityState");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_SupplyPhases].component.name, "EVSE");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_SupplyPhases].variable.name, "SupplyPhases");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_Power].component.name, "EVSE");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[EVSE_Power].variable.name, "Power");

		/* LocalAuthListCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Enabled].component.name, "LocalAuthListCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Enabled].variable.name, "Enabled");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].component.name, "LocalAuthListCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variable.name, "Entries");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Available].component.name, "LocalAuthListCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Available].variable.name, "Available");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_ItemsPerMessage].component.name, "LocalAuthListCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_ItemsPerMessage].variable.name, "ItemsPerMessage");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_ItemsPerMessage].variable.instance, "SendLocalList");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_BytesPerMessage].component.name, "LocalAuthListCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_BytesPerMessage].variable.name, "BytesPerMessage");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_BytesPerMessage].variable.instance, "SendLocalList");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage].component.name, "LocalAuthListCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Storage].variable.name, "Storage");

		/* MonitoringCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_Enabled].component.name, "MonitoringCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_Enabled].variable.instance, "Enabled");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_Available].component.name, "MonitoringCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_Available].variable.instance, "Available");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_ClearVariableMonitoring_ItemsPerMessage].component.name, "MonitoringCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_ClearVariableMonitoring_ItemsPerMessage].variable.instance, "ClearVariableMonitoring");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_ClearVariableMonitoring_ItemsPerMessage].variable.name, "ItemsPerMessage");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_SetVariableMonitoring_ItemsPerMessage].component.name, "MonitoringCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_SetVariableMonitoring_ItemsPerMessage].variable.instance, "SetVariableMonitoring");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_SetVariableMonitoring_ItemsPerMessage].variable.name, "ItemsPerMessage");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_ClearVariableMonitoring_BytesPerMessage].component.name, "MonitoringCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_ClearVariableMonitoring_BytesPerMessage].variable.instance, "ClearVariableMonitoring");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_ClearVariableMonitoring_BytesPerMessage].variable.name, "BytesPerMessage");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_SetVariableMonitoring_BytesPerMessage].component.name, "MonitoringCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_SetVariableMonitoring_BytesPerMessage].variable.instance, "SetVariableMonitoring");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_SetVariableMonitoring_BytesPerMessage].variable.name, "BytesPerMessage");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_OfflineQueuingSeverity].component.name, "MonitoringCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[MonitoringCtrlr_OfflineQueuingSeverity].variable.name, "OfflineQueuingSeverity");

		/* OCPPCommCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_ActiveNetworkProfile].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_ActiveNetworkProfile].variable.name, "ActiveNetworkProfile");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageTimeout].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageTimeout].variable.instance, "Default");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageTimeout].variable.name, "MessageTimeout");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_FileTransferProtocols].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_FileTransferProtocols].variable.name, "FileTransferProtocols");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_HeartbeatInterval].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_HeartbeatInterval].variable.name, "HeartbeatInterval");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_NetworkConfigurationPriority].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_NetworkConfigurationPriority].variable.name, "NetworkConfigurationPriority");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_NetworkProfileConnectionAttempts].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_NetworkProfileConnectionAttempts].variable.name, "NetworkProfileConnectionAttempts");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_OfflineThreshold].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_OfflineThreshold].variable.name, "OfflineThreshold");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_QueueAllMessages].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_QueueAllMessages].variable.name, "QueueAllMessages");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttempts].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttempts].variable.instance, "TransactionEvent");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttempts].variable.name, "MessageAttempts");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttemptInterval].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttemptInterval].variable.instance, "TransactionEvent");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttemptInterval].variable.name, "MessageAttemptInterval");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_UnlockOnEVSideDisconnect].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_UnlockOnEVSideDisconnect].variable.name, "UnlockOnEVSideDisconnect");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_WebSocketPingInterval].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_WebSocketPingInterval].variable.name, "WebSocketPingInterval");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_ResetRetries].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_ResetRetries].variable.name, "ResetRetries");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_PublicKeyWithSignedMeterValue].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_PublicKeyWithSignedMeterValue].variable.name, "PublicKeyWithSignedMeterValue");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_VariableVersion].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_VariableVersion].variable.name, "VariableVersion");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationPeriodically].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationPeriodically].variable.name, "StatusNotificationPeriodically");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationInterval].component.name, "OCPPCommCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationInterval].variable.name, "StatusNotificationInterval");

		/* ReservationCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_Enabled].component.name, "ReservationCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_Enabled].variable.name, "Enabled");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_Available].component.name, "ReservationCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_Available].variable.name, "Available");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_NonEvseSpecific].component.name, "ReservationCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[ReservationCtrlr_NonEvseSpecific].variable.name, "NonEvseSpecific");

		/* SampledDataCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_Enabled].component.name, "SampledDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_Enabled].variable.name, "Enabled");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_Available].component.name, "SampledDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_Available].variable.name, "Available");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_SignReadings].component.name, "SampledDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_SignReadings].variable.name, "SignReadings");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].component.name, "SampledDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].variable.name, "TxEndedMeasurands");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedInterval].component.name, "SampledDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedInterval].variable.name, "TxEndedInterval");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxStartedMeasurands].component.name, "SampledDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxStartedMeasurands].variable.name, "TxStartedMeasurands");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].component.name, "SampledDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variable.name, "TxUpdatedMeasurands");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedInterval].component.name, "SampledDataCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedInterval].variable.name, "TxUpdatedInterval");

		/* SecurityCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].component.name, "SecurityCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variable.name, "BasicAuthPassword");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_Identity].component.name, "SecurityCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_Identity].variable.name, "Identity");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_OrganizationName].component.name, "SecurityCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_OrganizationName].variable.name, "OrganizationName");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries].component.name, "SecurityCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_CertificateEntries].variable.name, "CertificateEntries");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_SecurityProfile].component.name, "SecurityCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_SecurityProfile].variable.name, "SecurityProfile");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_AdditionalRootCertificateCheck].component.name, "SecurityCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_AdditionalRootCertificateCheck].variable.name, "AdditionalRootCertificateCheck");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_MaxCertificateChainSize].component.name, "SecurityCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_MaxCertificateChainSize].variable.name, "MaxCertificateChainSize");

		/* SmartChargingCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Enabled].component.name, "SmartChargingCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Enabled].variable.name, "Enabled");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Available].component.name, "SmartChargingCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Available].variable.name, "Available");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ACPhaseSwitchingSupported].component.name, "SmartChargingCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ACPhaseSwitchingSupported].variable.name, "ACPhaseSwitchingSupported");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ProfileStackLevel].component.name, "SmartChargingCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ProfileStackLevel].variable.name, "ProfileStackLevel");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_RateUnit].component.name, "SmartChargingCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_RateUnit].variable.name, "RateUnit");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_PeriodsPerSchedule].component.name, "SmartChargingCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_PeriodsPerSchedule].variable.name, "PeriodsPerSchedule");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ExternalControlSignalsEnabled].component.name, "SmartChargingCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ExternalControlSignalsEnabled].variable.name, "ExternalControlSignalsEnabled");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_NotifyChargingLimitWithSchedules].component.name, "SmartChargingCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_NotifyChargingLimitWithSchedules].variable.name, "NotifyChargingLimitWithSchedules");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Phases3to1].component.name, "SmartChargingCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Phases3to1].variable.name, "Phases3to1");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].component.name, "SmartChargingCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].variable.name, "Entries");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_LimitChangeSignificance].component.name, "SmartChargingCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_LimitChangeSignificance].variable.name, "LimitChangeSignificance");

		/* TariffCostCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_Enabled].component.name, "TariffCostCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_Enabled].variable.instance, "Tariff");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_Enabled].variable.name, "Enabled");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_Available].component.name, "TariffCostCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_Available].variable.instance, "Tariff");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_Available].variable.name, "Available");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_TariffFallbackMessage].component.name, "TariffCostCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Tariff_TariffFallbackMessage].variable.name, "TariffFallbackMessage");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Enabled].component.name, "TariffCostCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Enabled].variable.instance, "Cost");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Enabled].variable.name, "Enabled");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Available].component.name, "TariffCostCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Available].variable.instance, "Cost");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Available].variable.name, "Available");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_TotalCostFallbackMessage].component.name, "TariffCostCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_TotalCostFallbackMessage].variable.name, "TotalCostFallbackMessage");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Currency].component.name, "TariffCostCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[Cost_Currency].variable.name, "Currency");

		/* TxCtrlr Required item */
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_ChargingBeforeAcceptedEnabled].component.name, "TxCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_ChargingBeforeAcceptedEnabled].variable.name, "ChargingBeforeAcceptedEnabled");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut].component.name, "TxCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut].variable.name, "EVConnectionTimeOut");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnEVSideDisconnect].component.name, "TxCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnEVSideDisconnect].variable.name, "StopTxOnEVSideDisconnect");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxBeforeAcceptedEnabled].component.name, "TxCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxBeforeAcceptedEnabled].variable.name, "TxBeforeAcceptedEnabled");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStartPoint].component.name, "TxCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStartPoint].variable.name, "TxStartPoint");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStopPoint].component.name, "TxCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStopPoint].variable.name, "TxStopPoint");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_MaxEnergyOnInvalidId].component.name, "TxCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_MaxEnergyOnInvalidId].variable.name, "MaxEnergyOnInvalidId");

		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId].component.name, "TxCtrlr");
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_StopTxOnInvalidId].variable.name, "StopTxOnInvalidId");
	}

	return 0;
}

void DB_variableIsCreate()
{
    char sql[512];
    char* errMsg = NULL;

    sprintf(sql,"select count(idx) as quantity from ocpp20_variable;");

    /* Execute SQL statement */
    if(sqlite3_exec(db, sql, DB_cbVariableIsCreate, 0, &errMsg) != SQLITE_OK )
    {
    	DEBUG_INFO("SQL error: %s\n", errMsg);
    }
}

int DB_cbVariableLoadFromDb(void *para, int columnCount, char **columnValue, char **columnName)
{
	for(int idx=0;idx<CtrlrVariable_CNT;idx++)
	{
		if((strcmp((char*)ShmOCPP20Data->ControllerComponentVariable[idx].component.name, columnValue[1]) == 0) &&
		   (strcmp((char*)ShmOCPP20Data->ControllerComponentVariable[idx].component.instance, columnValue[2]) == 0) &&
		   (strcmp((char*)ShmOCPP20Data->ControllerComponentVariable[idx].variable.name, columnValue[3]) == 0) &&
		   (strcmp((char*)ShmOCPP20Data->ControllerComponentVariable[idx].variable.instance, columnValue[4]) == 0))
		{
			sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[idx].variableCharacteristics.dataType, "%s", columnValue[5]);
			sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[idx].variableCharacteristics.unit, "%s", columnValue[6]);
			ShmOCPP20Data->ControllerComponentVariable[idx].variableCharacteristics.maxLimit = strlen(columnValue[7])>0?atoi(columnValue[7]):255;
			sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[idx].variableAttribute[0].type, "%s", columnValue[8]);
			sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[idx].variableAttribute[0].mutability, "%s", columnValue[9]);
			sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[idx].variableAttribute[0].value, "%s", columnValue[10]);
			ShmOCPP20Data->ControllerComponentVariable[idx].variableCharacteristics.minLimit = strlen(columnValue[11])>=0?atoi(columnValue[11]):0;
		}
	}

	return 0;
}

void DB_variableLoadFromDb()
{
	char sql[512];
	char* errMsg = NULL;

	sprintf(sql,"select * from ocpp20_variable order by idx;");

	/* Execute SQL statement */
	if(sqlite3_exec(db, sql, DB_cbVariableLoadFromDb, 0, &errMsg) != SQLITE_OK )
	{
		DEBUG_INFO("SQL error: %s\n", errMsg);
	}
}

int DB_cbGetNetworkProfileFromDb(void *para, int columnCount, char **columnValue, char **columnName)
{
	memset(&ShmOCPP20Data->NetworkConnectionProfile[0], 0x00, ARRAY_SIZE(ShmOCPP20Data->NetworkConnectionProfile));

	if(columnCount > 0)
	{
		for(int idx=0;idx<columnCount;idx++)
		{
			json_object *SetNetworkProfile;

			SetNetworkProfile = json_tokener_parse(columnValue[2]);
			if(!is_error(SetNetworkProfile))
			{
				// Required data
				if(json_object_object_get(SetNetworkProfile, "ocppVersion") != NULL)
					sprintf((char*)ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.ocppVersion, "%s", json_object_get_string(json_object_object_get(SetNetworkProfile, "ocppVersion")));

				if(json_object_object_get(SetNetworkProfile, "ocppTransport") != NULL)
					sprintf((char*)ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.ocppTransport, "%s", json_object_get_string(json_object_object_get(SetNetworkProfile, "ocppTransport")));

				if(json_object_object_get(SetNetworkProfile, "ocppCsmsUrl") != NULL)
					sprintf((char*)ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.ocppCsmsUrl, "%s", json_object_get_string(json_object_object_get(SetNetworkProfile, "ocppCsmsUrl")));

				if(json_object_object_get(SetNetworkProfile, "messageTimeout") != NULL)
					ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.messageTimeout = json_object_get_int(json_object_object_get(SetNetworkProfile, "messageTimeout"));

				if(json_object_object_get(SetNetworkProfile, "ocppInterface") != NULL)
					sprintf((char*)ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.ocppInterface, "%s", json_object_get_string(json_object_object_get(SetNetworkProfile, "ocppInterface")));

				if(json_object_object_get(SetNetworkProfile, "vpn") != NULL)
				{
					if(json_object_object_get(json_object_object_get(SetNetworkProfile, "vpn"), "server") != NULL)
						sprintf((char*)ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.vpn.server, "%s", json_object_get_string(json_object_object_get(json_object_object_get(SetNetworkProfile, "vpn"), "server")));

					if(json_object_object_get(json_object_object_get(SetNetworkProfile, "vpn"), "user") != NULL)
						sprintf((char*)ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.vpn.user, "%s", json_object_get_string(json_object_object_get(json_object_object_get(SetNetworkProfile, "vpn"), "user")));

					if(json_object_object_get(json_object_object_get(SetNetworkProfile, "vpn"), "group") != NULL)
						sprintf((char*)ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.vpn.group, "%s", json_object_get_string(json_object_object_get(json_object_object_get(SetNetworkProfile, "vpn"), "group")));

					if(json_object_object_get(json_object_object_get(SetNetworkProfile, "vpn"), "password") != NULL)
						sprintf((char*)ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.vpn.password, "%s", json_object_get_string(json_object_object_get(json_object_object_get(SetNetworkProfile, "vpn"), "password")));

					if(json_object_object_get(json_object_object_get(SetNetworkProfile, "vpn"), "key") != NULL)
						sprintf((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.vpn.key, "%s", json_object_get_string(json_object_object_get(json_object_object_get(SetNetworkProfile, "vpn"), "key")));

					if(json_object_object_get(json_object_object_get(SetNetworkProfile, "vpn"), "type") != NULL)
						sprintf((char*)ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.vpn.type, "%s", json_object_get_string(json_object_object_get(json_object_object_get(SetNetworkProfile, "vpn"), "type")));
				}

				if(json_object_object_get(SetNetworkProfile, "apn") != NULL)
				{
					if(json_object_object_get(json_object_object_get(SetNetworkProfile, "apn"), "apn") != NULL)
					{
						memset(ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.apn.apn, 0x00, ARRAY_SIZE(ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.apn.apn));
						sprintf((char*)ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.apn.apn, "%s", json_object_get_string(json_object_object_get(json_object_object_get(SetNetworkProfile, "apn"), "apn")));
					}

					if(json_object_object_get(json_object_object_get(SetNetworkProfile, "apn"), "apnUserName") != NULL)
					{
						memset(ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.apn.apnUserName, 0x00, ARRAY_SIZE(ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.apn.apnUserName));
						sprintf((char*)ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.apn.apnUserName, "%s", json_object_get_string(json_object_object_get(json_object_object_get(SetNetworkProfile, "apn"), "apnUserName")));
					}

					if(json_object_object_get(json_object_object_get(SetNetworkProfile, "apn"), "apnPassword") != NULL)
					{
						memset(ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.apn.apnPassword, 0x00, ARRAY_SIZE(ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.apn.apnPassword));
						sprintf((char*)ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.apn.apnPassword, "%s", json_object_get_string(json_object_object_get(json_object_object_get(SetNetworkProfile, "apn"), "apnPassword")));
					}

					if(json_object_object_get(json_object_object_get(SetNetworkProfile, "apn"), "simPin") != NULL)
						ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.apn.simPin = json_object_get_int(json_object_object_get(json_object_object_get(SetNetworkProfile, "apn"), "simPin"));

					if(json_object_object_get(json_object_object_get(SetNetworkProfile, "apn"), "preferredNetwork") != NULL)
						sprintf((char*)ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.apn.preferredNetwork, "%s", json_object_get_string(json_object_object_get(json_object_object_get(SetNetworkProfile, "apn"), "preferredNetwork")));

					if(json_object_object_get(json_object_object_get(SetNetworkProfile, "apn"), "useOnlyPreferredNetwork") != NULL)
						ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.apn.useOnlyPreferredNetwork = json_object_get_boolean(json_object_object_get(json_object_object_get(SetNetworkProfile, "apn"), "useOnlyPreferredNetwork"));

					if(json_object_object_get(json_object_object_get(SetNetworkProfile, "apn"), "apnAuthentication") != NULL)
						sprintf((char*)ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.apn.apnAuthentication, "%s", json_object_get_string(json_object_object_get(json_object_object_get(SetNetworkProfile, "apn"), "apnAuthentication")));
				}
			}
			json_object_put(SetNetworkProfile);

			ShmOCPP20Data->NetworkConnectionProfile[idx].slot = atoi(columnValue[1]);
		}
	}

	return 0;
}

void DB_getNetworkProfileFromDb()
{
	char sql[512];
	char* errMsg = NULL;

	sprintf(sql,"select * from ocpp20_networkprofile order by slot;");

	/* Execute SQL statement */
	if(sqlite3_exec(db, sql, DB_cbGetNetworkProfileFromDb, 0, &errMsg) != SQLITE_OK )
	{
		DEBUG_INFO("SQL error: %s\n", errMsg);
	}
}

int DB_addNetworkProfile(int slot, char *data)
{
	 int result = PASS;
	 char sql[512];
	 char* errMsg = NULL;

	 sprintf(sql,"insert or replace into ocpp20_networkprofile (slot, connectionData) VALUES('%d', '%s');  SELECT * from ocpp20_networkprofile order by slot;",
			 	 slot,
				 data);

	 //* Execute SQL statement */
	 if(sqlite3_exec(db, sql, DB_cbGetNetworkProfileFromDb, 0, &errMsg) != SQLITE_OK)
	 {
		 DEBUG_INFO("SQL error: %s\n", errMsg);
		 result = FAIL;
	 }

	 return result;
}

int DB_deleteNetworkProfile(int slot)
{
	int result = PASS;
	char sql[512];
	char* errMsg = NULL;

	sprintf(sql,"DELETE from ocpp20_networkprofile where slot=%d; SELECT * from ocpp20_networkprofile order by slot;", slot);

	//* Execute SQL statement */
	if( sqlite3_exec(db, sql, DB_cbGetNetworkProfileFromDb, 0, &errMsg) != SQLITE_OK )
	{
		DEBUG_INFO("SQL error: %s", errMsg);
		result = FAIL;
	}

	return result;
}

int getCurrentYear()
{
	int result = 0;
	time_t CurrentTime;
	struct tm *tm;

	CurrentTime = time(NULL);
	tm=localtime(&CurrentTime);
	result = (tm->tm_year + 1900);

	return result;
}

int OCPP_insert_transaction_msg(uint8_t isStartTransaction, char *transactionMsg)
{
	int result = PASS;
	char* errMsg = NULL;
	char sqlStr[8192];

	sprintf(sqlStr, "insert into ocpp20_transaction_record(occurDatetime, message_type, message_content) values(CURRENT_TIMESTAMP, '%s', '%s');", (isStartTransaction?"startTransaction":"stopTransaction"), transactionMsg);

	if (sqlite3_exec(db, sqlStr, 0, 0, &errMsg) != SQLITE_OK)
	{
		result = FAIL;
		DEBUG_WARN( "Insert local transaction record error message: %s\n", errMsg);
	}

	sprintf(sqlStr, "delete from ocpp20_transaction_record where (idx < (select idx from ocpp_transaction_record order by idx desc limit 1)-2000) and (occurDatetime < '%04d-01-01 00:00:00');", (getCurrentYear()-3));
	if (sqlite3_exec(db, sqlStr, 0, 0, &errMsg) != SQLITE_OK)
	{
		result = FAIL;
		DEBUG_WARN( "delete local transaction record error message: %s\n", errMsg);
	}

	return result;
}
//==========================================
// Check time passed since today
//==========================================
long long DiffTimebWithNow(struct timeb ST)
{
	//return milli-second
	struct timeb ET;
	long long StartTime,StopTime;

	ftime(&ET);
	StartTime=(long long)ST.time;
	StopTime=(long long)ET.time;
	return ((StopTime-StartTime)*1000) + (ET.millitm-ST.millitm);
}

int getTimePassSinceToday(uint8_t gun_index)
{
	int result = -1;
	static time_t lastTime[4];
	time_t t;
	struct tm *tmStartToday;
	struct timeb tbStartToday;

	t=time(NULL);
	if(difftime(t, lastTime[gun_index])>0)
	{
		tmStartToday=localtime(&t);

		tmStartToday->tm_hour = 0;
		tmStartToday->tm_min = 0;
		tmStartToday->tm_sec = 0;

		tbStartToday.time = mktime(tmStartToday);
		tbStartToday.millitm = 0;
		result = DiffTimebWithNow(tbStartToday)/1000;
		lastTime[gun_index] = t;
	}

	return result;
}

int syncDateTimeRTC(uint8_t *data)
{
	struct ParsingResult
	{
		int result;
		int scanedElement;
		int year;
		int month;
		int mday;
		int hour;
		int min;
		int sec;
		int tz_hour;
		int tz_min;
		float minSec;
	}result;
	struct tm tmOrg;
	struct tm *tmTarget;
	struct timeb tbTarget;
	char buf[128];

	memset(&result, 0x00, sizeof(struct ParsingResult));
	result.result = PASS;

	if(strstr((char*)data, ".") != NULL)
	{
		// Original data with mini second
		if(strstr((char*)data, "Z") != NULL)
		{
			// Original data with Z
			result.scanedElement = sscanf((char*)data, "%d-%d-%dT%d:%d:%d.%fZ",
														&result.year,
														&result.month,
														&result.mday,
														&result.hour,
														&result.min,
														&result.sec,
														&result.minSec);
		}
		else
		{
			// Original data without Z
			result.scanedElement = sscanf((char*)data, "%d-%d-%dT%d:%d:%d.%f%d:%d",
														&result.year,
														&result.month,
														&result.mday,
														&result.hour,
														&result.min,
														&result.sec,
														&result.minSec,
														&result.tz_hour,
														&result.tz_min);
		}
	}
	else
	{
		// Original data without mini second
		if(strstr((char*)data, "Z") != NULL)
		{
			// Original data with Z
			result.scanedElement = sscanf((char*)data, "%d-%d-%dT%d:%d:%dZ",
														&result.year,
														&result.month,
														&result.mday,
														&result.hour,
														&result.min,
														&result.sec);
		}
		else
		{
			// Original data without Z
			result.scanedElement = sscanf((char*)data, "%d-%d-%dT%d:%d:%d%d:%d",
														&result.year,
														&result.month,
														&result.mday,
														&result.hour,
														&result.min,
														&result.sec,
														&result.tz_hour,
														&result.tz_min);
		}
	}

	tmOrg.tm_year = result.year - 1900;
	tmOrg.tm_mon = result.month - 1;
	tmOrg.tm_mday = result.mday;
	tmOrg.tm_hour = result.hour;
	tmOrg.tm_min = result.min;
	tmOrg.tm_sec = result.sec;
	tmOrg.tm_gmtoff = 0;
	tbTarget.time = mktime(&tmOrg);
	tbTarget.timezone = 0;

	tbTarget.time -= (result.tz_hour*3600) + (result.tz_min*60*(result.tz_hour>=0?1:-1));
	tmTarget = gmtime(&tbTarget.time);

    sprintf(buf, "date -s '%04d-%02d-%02d %02d:%02d:%02d'", (tmTarget->tm_year+1900), (tmTarget->tm_mon+1), tmTarget->tm_mday, tmTarget->tm_hour, tmTarget->tm_min, tmTarget->tm_sec);
    //DEBUG_INFO("  org date time: %s\n", data);
    //DEBUG_INFO("parse date time: %s\n", buf);

	system(buf);
	system("/sbin/hwclock -w --systohc");

	if(result.scanedElement < 6)
		result.result = FAIL;

	return result.result;
}

//==========================================
// GetCompositeSchedule logic related function
//==========================================
int DiffTimebSec(struct timeb ST, struct timeb ET)
{
	//return milli-second
	unsigned int StartTime,StopTime;

	StartTime=(unsigned int)ST.time;
	StopTime=(unsigned int)ET.time;
	return (StopTime-StartTime);
}

int DiffTimebWithNowSec(struct timeb ST)
{
	//return milli-second
	struct timeb ET;
	unsigned int StartTime,StopTime;

	ftime(&ET);
	StartTime=(unsigned int)ST.time;
	StopTime=(unsigned int)ET.time;
	return (StopTime-StartTime);
}

int getStartStop(uint8_t *start, uint8_t *stop)
{
	struct ParsingResult
	{
		int result;
		int scanedElement;
		int year;
		int month;
		int mday;
		int hour;
		int min;
		int sec;
		int tz_hour;
		int tz_min;
		float minSec;
	};

	struct ParsingResult parseStart;
	struct ParsingResult parseStop;

	int result = -1;
	struct tm tmStart;
	struct timeb tbStart;
	struct tm tmStop;
	struct timeb tbStop;

	memset(&parseStart, 0x00, sizeof(struct ParsingResult));
	memset(&parseStop, 0x00, sizeof(struct ParsingResult));

	// Scan start & stop date time
	if(strstr((char*)start, ".") != NULL)
	{
		// Original data with mini second
		if(strstr((char*)start, "Z") != NULL)
		{
			// Original data with Z
			parseStart.scanedElement = sscanf((char*)start, "%d-%d-%dT%d:%d:%d.%fZ",
														&parseStart.year,
														&parseStart.month,
														&parseStart.mday,
														&parseStart.hour,
														&parseStart.min,
														&parseStart.sec,
														&parseStart.minSec);
		}
		else
		{
			// Original data without Z
			parseStart.scanedElement = sscanf((char*)start, "%d-%d-%dT%d:%d:%d.%f%d:%d",
														&parseStart.year,
														&parseStart.month,
														&parseStart.mday,
														&parseStart.hour,
														&parseStart.min,
														&parseStart.sec,
														&parseStart.minSec,
														&parseStart.tz_hour,
														&parseStart.tz_min);
		}
	}
	else
	{
		// Original data without mini second
		if(strstr((char*)start, "Z") != NULL)
		{
			// Original data with Z
			parseStart.scanedElement = sscanf((char*)start, "%d-%d-%dT%d:%d:%dZ",
														&parseStart.year,
														&parseStart.month,
														&parseStart.mday,
														&parseStart.hour,
														&parseStart.min,
														&parseStart.sec);
		}
		else
		{
			// Original data without Z
			parseStart.scanedElement = sscanf((char*)start, "%d-%d-%dT%d:%d:%d%d:%d",
														&parseStart.year,
														&parseStart.month,
														&parseStart.mday,
														&parseStart.hour,
														&parseStart.min,
														&parseStart.sec,
														&parseStart.tz_hour,
														&parseStart.tz_min);
		}
	}

	if(strstr((char*)stop, ".") != NULL)
	{
		// Original data with mini second
		if(strstr((char*)stop, "Z") != NULL)
		{
			// Original data with Z
			parseStop.scanedElement = sscanf((char*)stop, "%d-%d-%dT%d:%d:%d.%fZ",
														&parseStop.year,
														&parseStop.month,
														&parseStop.mday,
														&parseStop.hour,
														&parseStop.min,
														&parseStop.sec,
														&parseStop.minSec);
		}
		else
		{
			// Original data without Z
			parseStop.scanedElement = sscanf((char*)stop, "%d-%d-%dT%d:%d:%d.%f%d:%d",
														&parseStop.year,
														&parseStop.month,
														&parseStop.mday,
														&parseStop.hour,
														&parseStop.min,
														&parseStop.sec,
														&parseStop.minSec,
														&parseStop.tz_hour,
														&parseStop.tz_min);
		}
	}
	else
	{
		// Original data without mini second
		if(strstr((char*)stop, "Z") != NULL)
		{
			// Original data with Z
			parseStop.scanedElement = sscanf((char*)stop, "%d-%d-%dT%d:%d:%dZ",
														&parseStop.year,
														&parseStop.month,
														&parseStop.mday,
														&parseStop.hour,
														&parseStop.min,
														&parseStop.sec);
		}
		else
		{
			// Original data without Z
			parseStop.scanedElement = sscanf((char*)stop, "%d-%d-%dT%d:%d:%d%d:%d",
														&parseStop.year,
														&parseStop.month,
														&parseStop.mday,
														&parseStop.hour,
														&parseStop.min,
														&parseStop.sec,
														&parseStop.tz_hour,
														&parseStop.tz_min);
		}
	}

	// Calculate date time difference
	if((parseStart.scanedElement >=6) &&
	   (parseStop.scanedElement >=6))
	{
		//DEBUG_INFO("Start: %04d-%02d-%02d %02d:%02d:%02d(%02d:%02d)\n", parseStart.year, parseStart.month, parseStart.mday, parseStart.hour, parseStart.min, parseStart.sec, parseStart.tz_hour, parseStart.tz_min);
		//DEBUG_INFO("Stop: %04d-%02d-%02d %02d:%02d:%02d(%02d:%02d)\n", parseStop.year, parseStop.month, parseStop.mday, parseStop.hour, parseStop.min, parseStop.sec, parseStop.tz_hour, parseStop.tz_min);

		tmStart.tm_year = parseStart.year - 1900;
		tmStart.tm_mon = parseStart.month - 1;
		tmStart.tm_mday = parseStart.mday;
		tmStart.tm_hour = parseStart.hour;
		tmStart.tm_min = parseStart.min;
		tmStart.tm_sec = parseStart.sec;
		tmStart.tm_gmtoff = 0;
		tbStart.time = mktime(&tmStart);
		tbStart.timezone = 0;
		tbStart.time -= (parseStart.tz_hour*3600) + (parseStart.tz_min*60*(parseStart.tz_hour>=0?1:-1));

		tmStop.tm_year = parseStop.year - 1900;
		tmStop.tm_mon = parseStop.month - 1;
		tmStop.tm_mday = parseStop.mday;
		tmStop.tm_hour = parseStop.hour;
		tmStop.tm_min = parseStop.min;
		tmStop.tm_sec = parseStop.sec;
		tmStop.tm_gmtoff = 0;
		tbStop.time = mktime(&tmStop);
		tbStop.timezone = 0;
		tbStop.time -= (parseStop.tz_hour*3600) + (parseStop.tz_min*60*(parseStop.tz_hour>=0?1:-1));

		result = DiffTimebSec(tbStart, tbStop);

		//DEBUG_INFO("getStartStop(): %d\n", result);

	}
	else
	{
		DEBUG_WARN("Start or stop date parsing error.\r\n");
	}

	return result;
}

int isOvertNow(uint8_t *start)
{
	int result = NO;
	struct ParsingResult
	{
		int result;
		int scanedElement;
		int year;
		int month;
		int mday;
		int hour;
		int min;
		int sec;
		int tz_hour;
		int tz_min;
		float minSec;
	}parsingResult;

	struct tm tmStart;
	struct timeb tbStart;

	memset(&parsingResult, 0x00, sizeof(struct ParsingResult));

	if(strstr((char*)start, ".") != NULL)
	{
		// Original data with mini second
		if(strstr((char*)start, "Z") != NULL)
		{
			// Original data with Z
			parsingResult.scanedElement = sscanf((char*)start, "%d-%d-%dT%d:%d:%d.%fZ",
																&parsingResult.year,
																&parsingResult.month,
																&parsingResult.mday,
																&parsingResult.hour,
																&parsingResult.min,
																&parsingResult.sec,
																&parsingResult.minSec);
		}
		else
		{
			// Original data without Z
			parsingResult.scanedElement = sscanf((char*)start, "%d-%d-%dT%d:%d:%d.%f%d:%d",
												&parsingResult.year,
												&parsingResult.month,
												&parsingResult.mday,
												&parsingResult.hour,
												&parsingResult.min,
												&parsingResult.sec,
												&parsingResult.minSec,
												&parsingResult.tz_hour,
												&parsingResult.tz_min);
		}
	}
	else
	{
		// Original data without mini second
		if(strstr((char*)start, "Z") != NULL)
		{
			// Original data with Z
			parsingResult.scanedElement = sscanf((char*)start, "%d-%d-%dT%d:%d:%dZ",
												&parsingResult.year,
												&parsingResult.month,
												&parsingResult.mday,
												&parsingResult.hour,
												&parsingResult.min,
												&parsingResult.sec);
		}
		else
		{
			// Original data without Z
			parsingResult.scanedElement = sscanf((char*)start, "%d-%d-%dT%d:%d:%d%d:%d",
												&parsingResult.year,
												&parsingResult.month,
												&parsingResult.mday,
												&parsingResult.hour,
												&parsingResult.min,
												&parsingResult.sec,
												&parsingResult.tz_hour,
												&parsingResult.tz_min);
		}
	}

	if(parsingResult.scanedElement >= 6)
	{
		tmStart.tm_year = parsingResult.year - 1900;
		tmStart.tm_mon = parsingResult.month - 1;
		tmStart.tm_mday = parsingResult.mday;
		tmStart.tm_hour = parsingResult.hour;
		tmStart.tm_min = parsingResult.min;
		tmStart.tm_sec = parsingResult.sec;
		tmStart.tm_gmtoff = 0;
		tbStart.time = mktime(&tmStart);
		tbStart.timezone = 0;
		tbStart.millitm = 0;

		tbStart.time -= (parsingResult.tz_hour*3600) + (parsingResult.tz_min*60*(parsingResult.tz_hour>=0?1:-1));

		if(DiffTimebWithNowSec(tbStart) <= 0)
			result = NO;
		else
			result = YES;
	}
	else
	{
		DEBUG_WARN("Start date parsing error.\n");
	}

	return result;
}

int getStartSinceRecurring(uint8_t *start, uint8_t *stop, uint8_t isDaily)
{
	struct ParsingResult
	{
		int result;
		int scanedElement;
		int year;
		int month;
		int mday;
		int hour;
		int min;
		int sec;
		int tz_hour;
		int tz_min;
		float minSec;
	};

	struct ParsingResult parseStart;
	struct ParsingResult parseStop;

	int result = -1;
	struct tm tmStart;
	struct timeb tbStart;
	struct tm tmStop;
	struct timeb tbStop;

	memset(&parseStart, 0x00, sizeof(struct ParsingResult));
	memset(&parseStop, 0x00, sizeof(struct ParsingResult));

	// Scan start & stop date time
	if(strstr((char*)start, ".") != NULL)
	{
		// Original data with mini second
		if(strstr((char*)start, "Z") != NULL)
		{
			// Original data with Z
			parseStart.scanedElement = sscanf((char*)start, "%d-%d-%dT%d:%d:%d.%fZ",
														&parseStart.year,
														&parseStart.month,
														&parseStart.mday,
														&parseStart.hour,
														&parseStart.min,
														&parseStart.sec,
														&parseStart.minSec);
		}
		else
		{
			// Original data without Z
			parseStart.scanedElement = sscanf((char*)start, "%d-%d-%dT%d:%d:%d.%f%d:%d",
														&parseStart.year,
														&parseStart.month,
														&parseStart.mday,
														&parseStart.hour,
														&parseStart.min,
														&parseStart.sec,
														&parseStart.minSec,
														&parseStart.tz_hour,
														&parseStart.tz_min);
		}
	}
	else
	{
		// Original data without mini second
		if(strstr((char*)start, "Z") != NULL)
		{
			// Original data with Z
			parseStart.scanedElement = sscanf((char*)start, "%d-%d-%dT%d:%d:%dZ",
														&parseStart.year,
														&parseStart.month,
														&parseStart.mday,
														&parseStart.hour,
														&parseStart.min,
														&parseStart.sec);
		}
		else
		{
			// Original data without Z
			parseStart.scanedElement = sscanf((char*)start, "%d-%d-%dT%d:%d:%d%d:%d",
														&parseStart.year,
														&parseStart.month,
														&parseStart.mday,
														&parseStart.hour,
														&parseStart.min,
														&parseStart.sec,
														&parseStart.tz_hour,
														&parseStart.tz_min);
		}
	}

	if(strstr((char*)stop, ".") != NULL)
	{
		// Original data with mini second
		if(strstr((char*)stop, "Z") != NULL)
		{
			// Original data with Z
			parseStop.scanedElement = sscanf((char*)stop, "%d-%d-%dT%d:%d:%d.%fZ",
														&parseStop.year,
														&parseStop.month,
														&parseStop.mday,
														&parseStop.hour,
														&parseStop.min,
														&parseStop.sec,
														&parseStop.minSec);
		}
		else
		{
			// Original data without Z
			parseStop.scanedElement = sscanf((char*)stop, "%d-%d-%dT%d:%d:%d.%f%d:%d",
														&parseStop.year,
														&parseStop.month,
														&parseStop.mday,
														&parseStop.hour,
														&parseStop.min,
														&parseStop.sec,
														&parseStop.minSec,
														&parseStop.tz_hour,
														&parseStop.tz_min);
		}
	}
	else
	{
		// Original data without mini second
		if(strstr((char*)stop, "Z") != NULL)
		{
			// Original data with Z
			parseStop.scanedElement = sscanf((char*)stop, "%d-%d-%dT%d:%d:%dZ",
														&parseStop.year,
														&parseStop.month,
														&parseStop.mday,
														&parseStop.hour,
														&parseStop.min,
														&parseStop.sec);
		}
		else
		{
			// Original data without Z
			parseStop.scanedElement = sscanf((char*)stop, "%d-%d-%dT%d:%d:%d%d:%d",
														&parseStop.year,
														&parseStop.month,
														&parseStop.mday,
														&parseStop.hour,
														&parseStop.min,
														&parseStop.sec,
														&parseStop.tz_hour,
														&parseStop.tz_min);
		}
	}

	// Calculate date time difference
	if((parseStart.scanedElement >=6) &&
	   (parseStop.scanedElement >=6))
	{
		//DEBUG_INFO("Start: %04d-%02d-%02d %02d:%02d:%02d(%02d:%02d)\n", parseStart.year, parseStart.month, parseStart.mday, parseStart.hour, parseStart.min, parseStart.sec, parseStart.tz_hour, parseStart.tz_min);
		//DEBUG_INFO("Stop: %04d-%02d-%02d %02d:%02d:%02d(%02d:%02d)\n", parseStop.year, parseStop.month, parseStop.mday, parseStop.hour, parseStop.min, parseStop.sec, parseStop.tz_hour, parseStop.tz_min);

		tmStart.tm_year = parseStart.year - 1900;
		tmStart.tm_mon = parseStart.month - 1;
		tmStart.tm_mday = parseStart.mday;
		tmStart.tm_hour = parseStart.hour;
		tmStart.tm_min = parseStart.min;
		tmStart.tm_sec = parseStart.sec;
		tmStart.tm_gmtoff = 0;
		tbStart.time = mktime(&tmStart);
		tbStart.timezone = 0;
		tbStart.time -= (parseStart.tz_hour*3600) + (parseStart.tz_min*60*(parseStart.tz_hour>=0?1:-1));

		tmStop.tm_year = parseStop.year - 1900;
		tmStop.tm_mon = parseStop.month - 1;
		tmStop.tm_mday = parseStop.mday;
		tmStop.tm_hour = parseStop.hour;
		tmStop.tm_min = parseStop.min;
		tmStop.tm_sec = parseStop.sec;
		tmStop.tm_gmtoff = 0;
		tbStop.time = mktime(&tmStop);
		tbStop.timezone = 0;
		tbStop.time -= (parseStop.tz_hour*3600) + (parseStop.tz_min*60*(parseStop.tz_hour>=0?1:-1));

		result = DiffTimebSec(tbStart, tbStop)%(isDaily?86400:604800);

		//DEBUG_INFO("getStartStop(): %d\n", result);

	}
	else
	{
		DEBUG_WARN("Start or stop date parsing error.\r\n");
	}

	return result;
}

void checkChargingStationMaxProfile(uint32_t durationReq, struct ChargingProfileType *targetCompositeProfile, uint8_t idxSchedule, uint8_t isUnitA)
{
	FILE *fp;
	char profileFileName[128];
	char *line = NULL;
	size_t len = 0;
	time_t CurrentTime;
	struct tm *tmComposite;

	struct ChargingProfileType maxProfile;
	struct ChargingProfileType compositeProfile;

	uint8_t limitMax=0;
	int compositePeriodIdx = 0;

	CurrentTime = time(NULL);
	tmComposite=localtime(&CurrentTime);
	sprintf((char*)compositeProfile.chargingSchedule[idxSchedule].startSchedule, "%04d-%02d-%02dT%02d:%02d:%02dZ", tmComposite->tm_year+1900, tmComposite->tm_mon+1, tmComposite->tm_mday, tmComposite->tm_hour, tmComposite->tm_min, tmComposite->tm_sec);
	if(isUnitA)
		sprintf((char*)compositeProfile.chargingSchedule[idxSchedule].chargingRateUnit, "A");
	else
		sprintf((char*)compositeProfile.chargingSchedule[idxSchedule].chargingRateUnit, "W");
	compositeProfile.chargingSchedule[idxSchedule].duration = durationReq;
	for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
	{
		compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = -1;
		compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = -1;
		compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = 3;
	}
	compositeProfile.id = 0;
	compositeProfile.stackLevel = 99 ;
	sprintf((char*)compositeProfile.chargingProfileKind ,"Absolute");

	maxProfile.id = -1;

	maxProfile.chargingSchedule[idxSchedule].duration = -1;

	system("rm -f /tmp/*.json");
	system("cp /Storage/OCPP/*.json /tmp 2>/dev/null");

	// Search max profile
	sprintf(profileFileName, "/tmp/ChargingStationMaxProfile_OCPP20.json");
	if((access(profileFileName, F_OK))!=-1)
	{
		fp = fopen(profileFileName, "r");

		while(getline(&line, &len, fp) != -1)
		{
			json_object *obj = NULL;

			obj = json_tokener_parse(line);
			if(is_error(obj))
			{
				DEBUG_ERROR("Parse MaxProfile from file error.\n");
			}
			else
			{
				if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "id")) != maxProfile.id) &&
				   (json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "stackLevel")) >= maxProfile.stackLevel)
				  )
				{
					if((json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom") != NULL) &&
					   (json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo") != NULL)
					  )
					{
						struct tm tmFrom, tmTo;
						struct timeb tbFrom, tbTo;

						if((sscanf((char*)json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom")), "%4d-%2d-%2dT%2d:%2d:%2d", &tmFrom.tm_year, &tmFrom.tm_mon, &tmFrom.tm_mday, &tmFrom.tm_hour, &tmFrom.tm_min, &tmFrom.tm_sec) == 6) &&
						   (sscanf((char*)json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo")), "%4d-%2d-%2dT%2d:%2d:%2d", &tmTo.tm_year, &tmTo.tm_mon, &tmTo.tm_mday, &tmTo.tm_hour, &tmTo.tm_min, &tmTo.tm_sec) == 6))
						{
							tmFrom.tm_year -= 1900;
							tmFrom.tm_mon -= 1;
							tbFrom.time = mktime(&tmFrom);

							tmTo.tm_year -= 1900;
							tmTo.tm_mon -= 1;
							tbTo.time = mktime(&tmTo);

							if((DiffTimebWithNowSec(tbFrom)>=0) && (DiffTimebWithNowSec(tbTo)<=0))
							{
								for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
								{
									maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = -1;
									maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = -1;
									maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = 3;
								}

								if(maxProfile.id == -1)
									DEBUG_INFO("MaxProfile found.\n");
								else
									DEBUG_INFO("MaxProfile updated.\n");

								// Required item
								maxProfile.id = json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "id"));
								maxProfile.stackLevel = json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "stackLevel"));
								sprintf((char*)maxProfile.chargingProfileKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingProfileKind")));

								if(isUnitA)
								{
									sprintf((char*)maxProfile.chargingSchedule[idxSchedule].chargingRateUnit, "A");

									for(int idxPeriod=0;idxPeriod<json_object_array_length(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"));idxPeriod++)
									{
										maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "startPeriod"));
										maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = (json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0 ), "chargingSchedulePeriod"), idxPeriod), "numberPhases")==NULL?
																														 3:
																														 json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")));
										maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = (strstr(json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingRateUnit")),ChargingRateUnitEnumTypeStr[ChargingRateUnitEnumType_W])!=NULL?json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit"))/(220*maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases):json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit")));
									}
								}
								else
								{
									sprintf((char*)maxProfile.chargingSchedule[idxSchedule].chargingRateUnit, "W");

									for(int idxPeriod=0;idxPeriod<json_object_array_length(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"));idxPeriod++)
									{
										maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "startPeriod"));
										maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = (json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")==NULL?
																														 3:
																														 json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")));
										maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = (strstr(json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingRateUnit")),ChargingRateUnitEnumTypeStr[ChargingRateUnitEnumType_W])!=NULL?json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit")):json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit"))*(220*maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases));
									}
								}

								// Optional item
								if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom") != NULL)
								{
									sprintf((char*)maxProfile.validFrom, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom")));
								}
								else
								{
									sprintf((char*)maxProfile.validFrom, " ");
								}

								if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo") != NULL)
								{
									sprintf((char*)maxProfile.validTo, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo")));
								}
								else
								{
									sprintf((char*)maxProfile.validTo, " ");
								}

								if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "recurrencyKind") != NULL)
								{
									sprintf((char*)maxProfile.recurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "recurrencyKind")));
								}
								else
								{
									sprintf((char*)maxProfile.recurrencyKind, " ");
								}

								if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "transactionId") != NULL)
								{
									sprintf((char*)maxProfile.transactionId, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "transactionId")));
								}
								else
								{
									sprintf((char*)maxProfile.transactionId, " ");
								}

								if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "duration") != NULL)
								{
									maxProfile.chargingSchedule[idxSchedule].duration = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "duration"));
								}
								else
								{
									maxProfile.chargingSchedule[idxSchedule].duration = 86400;
								}

								if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "startSchedule") != NULL)
								{
									sprintf((char*)maxProfile.chargingSchedule[idxSchedule].startSchedule, "%s", json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "startSchedule")));
								}
								else
								{
									sprintf((char*)maxProfile.chargingSchedule[idxSchedule].startSchedule, "%s", compositeProfile.chargingSchedule[idxSchedule].startSchedule);
								}

								if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "minChargingRate") != NULL)
								{
									maxProfile.chargingSchedule[idxSchedule].minChargingRate = json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "minChargingRate"));
								}
								else
								{
									maxProfile.chargingSchedule[idxSchedule].minChargingRate = -1;
								}
							}
						}
					}
					else
					{
						for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
						{
							maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = -1;
							maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = -1;
							maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = 3;
						}

						if(maxProfile.id == -1)
							DEBUG_INFO("MaxProfile found.\n");
						else
							DEBUG_INFO("MaxProfile updated.\n");

						// Required item
						maxProfile.id = json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "id"));
						maxProfile.stackLevel = json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "stackLevel"));
						sprintf((char*)maxProfile.chargingProfileKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingProfileKind")));
						if(isUnitA)
						{
							sprintf((char*)maxProfile.chargingSchedule[idxSchedule].chargingRateUnit, "A");
							for(int idxPeriod=0;idxPeriod<json_object_array_length(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"));idxPeriod++)
							{
								maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "startPeriod"));
								maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = (json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")==NULL?
																												 3:
																												 json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")));
								maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = (strstr((char*)json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingRateUnit")),ChargingRateUnitEnumTypeStr[ChargingRateUnitEnumType_W])!=NULL?json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit"))/(220*maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases):json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit")));
							}
						}
						else
						{
							sprintf((char*)maxProfile.chargingSchedule[idxSchedule].chargingRateUnit, "W");

							for(int idxPeriod=0;idxPeriod<json_object_array_length(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"));idxPeriod++)
							{
								maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "startPeriod"));
								maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = (json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")==NULL?
																												 3:
																												 json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")));
								maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = (strstr((char*)json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingRateUnit")),ChargingRateUnitEnumTypeStr[ChargingRateUnitEnumType_W])!=NULL?json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit")):json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit"))*(220*maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases));
							}
						}

						// Optional item
						if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom") != NULL)
						{
							sprintf((char*)maxProfile.validFrom, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom")));
						}
						else
						{
							sprintf((char*)maxProfile.validFrom, " ");
						}

						if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo") != NULL)
						{
							sprintf((char*)maxProfile.validTo, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo")));
						}
						else
						{
							sprintf((char*)maxProfile.validTo, " ");
						}

						if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "recurrencyKind") != NULL)
						{
							sprintf((char*)maxProfile.recurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "recurrencyKind")));
						}
						else
						{
							sprintf((char*)maxProfile.recurrencyKind, " ");
						}

						if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "transactionId") != NULL)
						{
							sprintf((char*)maxProfile.transactionId,"%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "transactionId")));
						}
						else
						{
							sprintf((char*)maxProfile.transactionId, " ");
						}

						if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "duration") != NULL)
						{
							maxProfile.chargingSchedule[idxSchedule].duration = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "duration"));
						}
						else
						{
							maxProfile.chargingSchedule[idxSchedule].duration = 86400;
						}

						if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "startSchedule") != NULL)
						{
							sprintf((char*)maxProfile.chargingSchedule[idxSchedule].startSchedule, "%s", json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "startSchedule")));
						}
						else
						{
							sprintf((char*)maxProfile.chargingSchedule[idxSchedule].startSchedule, "%s", compositeProfile.chargingSchedule[idxSchedule].startSchedule);
						}

						if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "minChargingRate") != NULL)
						{
							maxProfile.chargingSchedule[idxSchedule].minChargingRate = json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "minChargingRate"));
						}
						else
						{
							maxProfile.chargingSchedule[idxSchedule].minChargingRate = -1;
						}
					}
				}
			}
			json_object_put(obj);
		}
		fclose(fp);
/*
		if(maxProfile.id !=-1)
		{
			DEBUG_INFO("Profile ID: %d\n", maxProfile.id);
			DEBUG_INFO("Profile stackLevel: %d\n", maxProfile.StackLevel);
			DEBUG_INFO("Profile TransactionId: %d\n", maxProfile.TransactionId);
			DEBUG_INFO("Profile valid from: %s\n", maxProfile.ValidFrom);
			DEBUG_INFO("Profile valid to: %s\n", maxProfile.ValidTo);
			DEBUG_INFO("Profile ChargingProfileKind: %s\n", maxProfile.ChargingProfileKind);
			DEBUG_INFO("Profile recurrencyKind: %s\n", maxProfile.recurrencyKind);

			DEBUG_INFO("Profile start schedule: %s\n", maxProfile.chargingSchedule[idxSchedule].StartSchedule);
			DEBUG_INFO("Profile schedule duration: %d\n", maxProfile.chargingSchedule[idxSchedule].Duration);
			DEBUG_INFO("Profile charging rate unit: %s\n", maxProfile.chargingSchedule[idxSchedule].ChargingRateUnit);
			DEBUG_INFO("Profile charging min rate: %f\n", maxProfile.chargingSchedule[idxSchedule].MinChargingRate);

			for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod);idxPeriod++)
			{
				if(maxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].StartPeriod >= 0)
				{
					DEBUG_INFO("Period-%02d startPeriod: %d\n", idxPeriod, maxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].StartPeriod);
					DEBUG_INFO("Period-%02d limit: %f\n", idxPeriod, maxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].Limit);
					DEBUG_INFO("Period-%02d NumberPhases: %d\n", idxPeriod, maxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].NumberPhases);
				}
			}
		}
		else
			DEBUG_INFO("MaxProfile not found.\n");
		DEBUG_INFO("------------------------------------\n");*/
	}

	if(maxProfile.id != -1)
	{
		if(strstr((char*)maxProfile.chargingProfileKind, ChargingProfileKindEnumTypeStr[ChargingProfileKindEnumType_Absolute]) != NULL)
		{
			if(maxProfile.chargingSchedule[idxSchedule].duration != -1)
			{
				maxProfile.chargingSchedule[idxSchedule].duration = ((maxProfile.chargingSchedule[idxSchedule].duration-getStartStop(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule))<0?
														0:
														(maxProfile.chargingSchedule[idxSchedule].duration-getStartStop(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule)));
			}

			for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
			{
				if(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod != -1)
				{
					maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = ((maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartStop(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule))<0?
																								 0:
																								 (maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartStop(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule)));

					if(idxPeriod > 0)
					{
						if(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].startPeriod == maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod)
						{
							maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].limit = maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit;
						}
					}
				}
			}
		}
		else if(strstr((char*)maxProfile.chargingProfileKind, ChargingProfileKindEnumTypeStr[ChargingProfileKindEnumType_Relative]) != NULL)
		{
			if(maxProfile.chargingSchedule[idxSchedule].duration != -1)
			{
				maxProfile.chargingSchedule[idxSchedule].duration = maxProfile.chargingSchedule[idxSchedule].duration;
			}

			for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
			{
				if(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod != -1)
				{
					maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod;

					if(idxPeriod > 0)
					{
						if(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].startPeriod == maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod)
						{
							maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].limit = maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit;
						}
					}
				}
			}
		}
		else
		{
			if(strstr((char*)maxProfile.recurrencyKind, RecurrencyKindEnumTypeStr[RecurrencyKindEnumType_Weekly]) != NULL)
			{
				if(maxProfile.chargingSchedule[idxSchedule].duration != -1)
				{
					maxProfile.chargingSchedule[idxSchedule].duration = ((maxProfile.chargingSchedule[idxSchedule].duration-getStartSinceRecurring(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, FALSE))<0?
															0:
															(maxProfile.chargingSchedule[idxSchedule].duration-getStartSinceRecurring(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, FALSE)));
				}

				for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
				{
					if(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod != -1)
					{
						maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = ((maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartSinceRecurring(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, FALSE))<0?
																									 0:
																									 (maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartSinceRecurring(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, FALSE)));

						if(idxPeriod > 0)
						{
							if(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].startPeriod == maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod)
							{
								maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].limit = maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit;
							}
						}
					}
				}
			}
			else
			{
				if(maxProfile.chargingSchedule[idxSchedule].duration != -1)
				{
					maxProfile.chargingSchedule[idxSchedule].duration = ((maxProfile.chargingSchedule[idxSchedule].duration-getStartSinceRecurring(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, TRUE))<0?
															0:
															(maxProfile.chargingSchedule[idxSchedule].duration-getStartSinceRecurring(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, TRUE)));
				}

				for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
				{
					if(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod != -1)
					{
						maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = ((maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartSinceRecurring(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, TRUE))<0?
																									 0:
																									 (maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartSinceRecurring(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, TRUE)));

						if(idxPeriod > 0)
						{
							if(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].startPeriod == maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod)
							{
								maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].limit = maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit;
							}
						}
					}
				}
			}
		}
/*
		DEBUG_INFO("MaxProfile after align.\n");
		DEBUG_INFO("Profile ID: %d\n", maxProfile.id);
		DEBUG_INFO("Profile stackLevel: %d\n", maxProfile.StackLevel);
		DEBUG_INFO("Profile TransactionId: %d\n", maxProfile.TransactionId);
		DEBUG_INFO("Profile valid from: %s\n", maxProfile.ValidFrom);
		DEBUG_INFO("Profile valid to: %s\n", maxProfile.ValidTo);
		DEBUG_INFO("Profile ChargingProfileKind: %s\n", maxProfile.ChargingProfileKind);
		DEBUG_INFO("Profile recurrencyKind: %s\n", maxProfile.recurrencyKind);

		DEBUG_INFO("Profile start schedule: %s\n", compositeProfile.ChargingSchedule.StartSchedule);
		DEBUG_INFO("Profile schedule duration: %d\n", maxProfile.chargingSchedule[idxSchedule].Duration);
		DEBUG_INFO("Profile charging rate unit: %s\n", maxProfile.chargingSchedule[idxSchedule].ChargingRateUnit);
		DEBUG_INFO("Profile charging min rate: %f\n", maxProfile.chargingSchedule[idxSchedule].MinChargingRate);

		for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod);idxPeriod++)
		{
			if(maxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].StartPeriod >= 0)
			{
				DEBUG_INFO("Period-%02d startPeriod: %d\n", idxPeriod, maxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].StartPeriod);
				DEBUG_INFO("Period-%02d limit: %f\n", idxPeriod, maxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].Limit);
				DEBUG_INFO("Period-%02d NumberPhases: %d\n", idxPeriod, maxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].NumberPhases);
			}
		}
		DEBUG_INFO("------------------------------------\n");*/
	}

	// Find each profile period quantity
	for(int idx=0;idx<ARRAY_SIZE(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idx++)
	{
		if(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idx].limit != -1)
			limitMax = idx+1;
	}

	if(maxProfile.id != -1)
	{
		for(int idxMaxPeriod=0;idxMaxPeriod<limitMax;idxMaxPeriod++)
		{
			if((maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod].limit != -1) &&
			   (maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod].startPeriod < durationReq) &&
			   (maxProfile.chargingSchedule[idxSchedule].duration > 0))
			{
				if(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod].startPeriod != compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)].startPeriod)
				{
					memcpy(&compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx], &maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod],sizeof(struct ChargingSchedulePeriodType));
					compositePeriodIdx++;
				}
				else
				{
					memcpy(&compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)], &maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod],sizeof(struct ChargingSchedulePeriodType));
				}
			}
		}
	}

	DEBUG_INFO("ChargePointMaxProfile ready.\n");
	DEBUG_INFO("Schedule start: %s\n", compositeProfile.chargingSchedule[idxSchedule].startSchedule);
	DEBUG_INFO("Schedule duration: %d\n", compositeProfile.chargingSchedule[idxSchedule].duration);
	DEBUG_INFO("Rate unit: %s\n", compositeProfile.chargingSchedule[idxSchedule].chargingRateUnit);
	for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
	{
		if(compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod >= 0)
		{
			compositeProfile.id = 1;
			DEBUG_INFO("Period-%02d startPeriod: %d\n", idxPeriod, compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod);
			DEBUG_INFO("Period-%02d limit: %f\n", idxPeriod, compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit);
			DEBUG_INFO("Period-%02d NumberPhases: %d\n", idxPeriod, compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases);
		}

		if(compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit == -1)
			compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit =0;

		if(compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod == -1)
			compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod =0;
	}

	memcpy(targetCompositeProfile, &compositeProfile, sizeof(struct StructChargingProfile));

	if(line)
		free(line);
}

void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct ChargingProfileType *targetCompositeProfile, uint8_t idxSchedule, uint8_t isUnitA)
{
	FILE *fp;
	char profileFileName[128];
	char *line = NULL;
	size_t len = 0;
	time_t CurrentTime;
	struct tm *tmComposite;

	struct ChargingProfileType maxProfile;
	struct ChargingProfileType defaultTxProfile;
	struct ChargingProfileType txProfile;
	struct ChargingProfileType compositeProfile;

	struct ChargingSchedulePeriodType tmpPeriod;
	uint8_t limitMax=0;
	uint8_t limitDef=0;
	uint8_t limitTx=0;

	int compositePeriodIdx = 0;

	CurrentTime = time(NULL);
	tmComposite=localtime(&CurrentTime);
	sprintf((char*)compositeProfile.chargingSchedule[idxSchedule].startSchedule, "%04d-%02d-%02dT%02d:%02d:%02dZ", tmComposite->tm_year+1900, tmComposite->tm_mon+1, tmComposite->tm_mday, tmComposite->tm_hour, tmComposite->tm_min, tmComposite->tm_sec);
	if(isUnitA)
		sprintf((char*)compositeProfile.chargingSchedule[idxSchedule].chargingRateUnit, "A");
	else
		sprintf((char*)compositeProfile.chargingSchedule[idxSchedule].chargingRateUnit, "W");
	compositeProfile.chargingSchedule[idxSchedule].duration = durationReq;
	for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
	{
		compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = -1;
		compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = -1;
		compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = 3;
		compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = 0;
	}
	compositeProfile.id = 0;
	compositeProfile.stackLevel = 99 ;
	sprintf((char*)compositeProfile.chargingProfileKind ,ChargingProfileKindEnumTypeStr[ChargingProfileKindEnumType_Absolute]);

	maxProfile.id = -1;
	defaultTxProfile.id = -1;
	txProfile.id = -1;

	maxProfile.chargingSchedule[idxSchedule].duration = -1;
	defaultTxProfile.chargingSchedule[idxSchedule].duration = -1;
	txProfile.chargingSchedule[idxSchedule].duration = -1;

	system("rm -f /tmp/*.json");
	system("cp /Storage/OCPP/*.json /tmp 2>/dev/null");
	/*
	 * Search valid charging profile
	 */
	//DEBUG_INFO("====================================\n");
	// Search tx profile
	sprintf(profileFileName, "/tmp/TxProfile_%d_OCPP20.json", connectorId);
	if((access(profileFileName, F_OK))!=-1)
	{
		fp = fopen(profileFileName, "r");

		while(getline(&line, &len, fp) != -1)
		{
			json_object *obj = NULL;

			obj = json_tokener_parse(line);
			if(is_error(obj))
			{
				DEBUG_ERROR("Parse txProfile from file error.\n");
			}
			else
			{
				if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "id")) != txProfile.id) &&
				   (json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "stackLevel")) >= txProfile.stackLevel)
				  )
				{
					if((json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom") != NULL) &&
					   (json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo") != NULL)
					  )
					{
						struct tm tmFrom, tmTo;
						struct timeb tbFrom, tbTo;

						if((sscanf((char*)json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom")), "%4d-%2d-%2dT%2d:%2d:%2d", &tmFrom.tm_year, &tmFrom.tm_mon, &tmFrom.tm_mday, &tmFrom.tm_hour, &tmFrom.tm_min, &tmFrom.tm_sec) == 6) &&
						   (sscanf((char*)json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo")), "%4d-%2d-%2dT%2d:%2d:%2d", &tmTo.tm_year, &tmTo.tm_mon, &tmTo.tm_mday, &tmTo.tm_hour, &tmTo.tm_min, &tmTo.tm_sec) == 6))
						{
							tmFrom.tm_year -= 1900;
							tmFrom.tm_mon -= 1;
							tbFrom.time = mktime(&tmFrom);

							tmTo.tm_year -= 1900;
							tmTo.tm_mon -= 1;
							tbTo.time = mktime(&tmTo);

							if((DiffTimebWithNowSec(tbFrom)>=0) && (DiffTimebWithNowSec(tbTo)<=0))
							{
								for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
								{
									txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = -1;
									txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = -1;
									txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = 3;
									txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].phaseToUse = 0;
								}

								if(txProfile.id == -1)
									DEBUG_INFO("TxProfile found.\n");
								else
									DEBUG_INFO("TxProfile updated.\n");

								// Required item
								txProfile.id = json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "id"));
								txProfile.stackLevel = json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "stackLevel"));
								sprintf((char*)txProfile.chargingProfileKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingProfileKind")));
								if(isUnitA)
								{
									sprintf((char*)txProfile.chargingSchedule[idxSchedule].chargingRateUnit, "A");

									for(int idxPeriod=0;idxPeriod<json_object_array_length(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"));idxPeriod++)
									{
										txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "startPeriod"));
										txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = (json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")==NULL?
																													    3:
																														json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")));
										txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = (strstr(json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingRateUnit")),ChargingRateUnitEnumTypeStr[ChargingRateUnitEnumType_W])!=NULL?json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit"))/(220*txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases):json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit")));
									}
								}
								else
								{
									sprintf((char*)txProfile.chargingSchedule[idxSchedule].chargingRateUnit, "W");

									for(int idxPeriod=0;idxPeriod<json_object_array_length(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"));idxPeriod++)
									{
										txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "startPeriod"));
										txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = (json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")==NULL?
																													    3:
																														json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")));
										txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = (strstr(json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingRateUnit")),ChargingRateUnitEnumTypeStr[ChargingRateUnitEnumType_W])!=NULL?json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit")):json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit"))*(220*txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases));
									}
								}

								// Optional item
								if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom") != NULL)
								{
									sprintf((char*)txProfile.validFrom, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom")));
								}
								else
								{
									sprintf((char*)txProfile.validFrom, " ");
								}

								if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo") != NULL)
								{
									sprintf((char*)txProfile.validTo, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo")));
								}
								else
								{
									sprintf((char*)txProfile.validTo, " ");
								}

								if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "recurrencyKind") != NULL)
								{
									sprintf((char*)txProfile.recurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "recurrencyKind")));
								}
								else
								{
									sprintf((char*)txProfile.recurrencyKind, " ");
								}

								if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "transactionId") != NULL)
								{
									sprintf((char*)txProfile.transactionId, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "transactionId")));
								}
								else
								{
									sprintf((char*)txProfile.transactionId, " ");
								}

								if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "duration") != NULL)
								{
									txProfile.chargingSchedule[idxSchedule].duration = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "duration"));
								}
								else
								{
									txProfile.chargingSchedule[idxSchedule].duration = 86400;
								}

								if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "startSchedule") != NULL)
								{
									sprintf((char*)txProfile.chargingSchedule[idxSchedule].startSchedule, "%s", json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "startSchedule")));
								}
								else
								{
									sprintf((char*)txProfile.chargingSchedule[idxSchedule].startSchedule, "%s", (!cpinitateMsg.bits[(connectorId==0?0:connectorId-1)].isOnCharging ? compositeProfile.chargingSchedule[idxSchedule].startSchedule : ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp));
								}

								if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "minChargingRate") != NULL)
								{
									txProfile.chargingSchedule[idxSchedule].minChargingRate = json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "minChargingRate"));
								}
								else
								{
									txProfile.chargingSchedule[idxSchedule].minChargingRate = -1;
								}
							}
						}
					}
					else
					{
						for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
						{
							txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = -1;
							txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = -1;
							txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = 3;
							txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].phaseToUse = 0;
						}

						if(txProfile.id == -1)
							DEBUG_INFO("TxProfile found.\n");
						else
							DEBUG_INFO("TxProfile updated.\n");

						// Required item
						txProfile.id = json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "id"));
						txProfile.stackLevel = json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "stackLevel"));
						sprintf((char*)txProfile.chargingProfileKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingProfileKind")));

						if(isUnitA)
						{
							sprintf((char*)txProfile.chargingSchedule[idxSchedule].chargingRateUnit, "A");

							for(int idxPeriod=0;idxPeriod<json_object_array_length(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"));idxPeriod++)
							{
								txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "startPeriod"));
								txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = (json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")==NULL?
																												3:
																												json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")));
								txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = (strstr(json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingRateUnit")),ChargingRateUnitEnumTypeStr[ChargingRateUnitEnumType_W])!=NULL?json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit"))/(220*txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases):json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit")));
							}
						}
						else
						{
							sprintf((char*)txProfile.chargingSchedule[idxSchedule].chargingRateUnit, "W");

							for(int idxPeriod=0;idxPeriod<json_object_array_length(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"));idxPeriod++)
							{
								txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "startPeriod"));
								txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = (json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")==NULL?
																												3:
																												json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")));
								txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = (strstr(json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingRateUnit")),ChargingRateUnitEnumTypeStr[ChargingRateUnitEnumType_W])!=NULL?json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit")):json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit"))*(220*txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases));
							}
						}

						// Optional item
						if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom") != NULL)
						{
							sprintf((char*)txProfile.validFrom, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom")));
						}
						else
						{
							sprintf((char*)txProfile.validFrom, " ");
						}

						if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo") != NULL)
						{
							sprintf((char*)txProfile.validTo, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo")));
						}
						else
						{
							sprintf((char*)txProfile.validTo, " ");
						}

						if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "recurrencyKind") != NULL)
						{
							sprintf((char*)txProfile.recurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "recurrencyKind")));
						}
						else
						{
							sprintf((char*)txProfile.recurrencyKind, " ");
						}

						if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "transactionId") != NULL)
						{
							sprintf((char*)txProfile.transactionId, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "transactionId")));
						}
						else
						{
							sprintf((char*)txProfile.transactionId, " ");
						}

						if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "duration") != NULL)
						{
							txProfile.chargingSchedule[idxSchedule].duration = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "duration"));
						}
						else
						{
							txProfile.chargingSchedule[idxSchedule].duration = 86400;
						}

						if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "startSchedule") != NULL)
						{
							sprintf((char*)txProfile.chargingSchedule[idxSchedule].startSchedule, "%s", json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "startSchedule")));
						}
						else
						{
							sprintf((char*)txProfile.chargingSchedule[idxSchedule].startSchedule, "%s", (!cpinitateMsg.bits[(connectorId==0?0:connectorId-1)].isOnCharging ? compositeProfile.chargingSchedule[idxSchedule].startSchedule : ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp));
						}

						if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "minChargingRate") != NULL)
						{
							txProfile.chargingSchedule[idxSchedule].minChargingRate = json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "minChargingRate"));
						}
						else
						{
							txProfile.chargingSchedule[idxSchedule].minChargingRate = -1;
						}
					}
				}
			}
			json_object_put(obj);
		}
		fclose(fp);
/*
		if(txProfile.id != -1)
		{
			DEBUG_INFO("Profile ID: %d\n", txProfile.id);
			DEBUG_INFO("Profile stackLevel: %d\n", txProfile.StackLevel);
			DEBUG_INFO("Profile TransactionId: %d\n", txProfile.TransactionId);
			DEBUG_INFO("Profile valid from: %s\n", txProfile.ValidFrom);
			DEBUG_INFO("Profile valid to: %s\n", txProfile.ValidTo);
			DEBUG_INFO("Profile ChargingProfileKind: %s\n", txProfile.ChargingProfileKind);
			DEBUG_INFO("Profile recurrencyKind: %s\n", txProfile.recurrencyKind);

			DEBUG_INFO("Profile start schedule: %s\n", txProfile.chargingSchedule[idxSchedule].StartSchedule);
			DEBUG_INFO("Profile schedule duration: %d\n", txProfile.chargingSchedule[idxSchedule].Duration);
			DEBUG_INFO("Profile charging rate unit: %s\n", txProfile.chargingSchedule[idxSchedule].ChargingRateUnit);
			DEBUG_INFO("Profile charging min rate: %f\n", txProfile.chargingSchedule[idxSchedule].MinChargingRate);

			for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(txProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod);idxPeriod++)
			{
				if(txProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].StartPeriod >= 0)
				{
					DEBUG_INFO("Period-%02d startPeriod: %d\n", idxPeriod, txProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].StartPeriod);
					DEBUG_INFO("Period-%02d limit: %f\n", idxPeriod, txProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].Limit);
					DEBUG_INFO("Period-%02d NumberPhases: %d\n", idxPeriod, txProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].NumberPhases);
				}
			}
		}
		else
			DEBUG_INFO("TxProfile not found.\n");*/
	}

	// Search default tx profile
	sprintf(profileFileName, "/tmp/TxDefaultProfile_%d_OCPP20.json", connectorId);
	if((access(profileFileName, F_OK))==-1)
		sprintf(profileFileName, "/tmp/TxDefaultProfile_0.json");

	if((access(profileFileName, F_OK))!=-1)
	{
		fp = fopen(profileFileName, "r");

		while(getline(&line, &len, fp) != -1)
		{
			json_object *obj = NULL;

			obj = json_tokener_parse(line);
			if(is_error(obj))
			{
				DEBUG_ERROR("Parse TxDefaultProfile from file error.\n");
			}
			else
			{
				if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "id")) != defaultTxProfile.id) &&
				   (json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "stackLevel")) >= defaultTxProfile.stackLevel)
				  )
				{
					if((json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom") != NULL) &&
					   (json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo") != NULL)
					  )
					{
						struct tm tmFrom, tmTo;
						struct timeb tbFrom, tbTo;

						if((sscanf((char*)json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom")), "%4d-%2d-%2dT%2d:%2d:%2d", &tmFrom.tm_year, &tmFrom.tm_mon, &tmFrom.tm_mday, &tmFrom.tm_hour, &tmFrom.tm_min, &tmFrom.tm_sec) == 6) &&
						   (sscanf((char*)json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo")), "%4d-%2d-%2dT%2d:%2d:%2d", &tmTo.tm_year, &tmTo.tm_mon, &tmTo.tm_mday, &tmTo.tm_hour, &tmTo.tm_min, &tmTo.tm_sec) == 6))
						{
							tmFrom.tm_year -= 1900;
							tmFrom.tm_mon -= 1;
							tbFrom.time = mktime(&tmFrom);

							tmTo.tm_year -= 1900;
							tmTo.tm_mon -= 1;
							tbTo.time = mktime(&tmTo);

							if((DiffTimebWithNowSec(tbFrom)>=0) && (DiffTimebWithNowSec(tbTo)<=0))
							{
								for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
								{
									defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = -1;
									defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = -1;
									defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = 3;
									defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].phaseToUse = 0;
								}

								if(defaultTxProfile.id == -1)
									DEBUG_INFO("TxDefaultProfile found.\n");
								else
									DEBUG_INFO("TxDefaultProfile updated.\n");

								// Required item
								defaultTxProfile.id = json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "id"));
								defaultTxProfile.stackLevel = json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "stackLevel"));
								sprintf((char*)defaultTxProfile.chargingProfileKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingProfileKind")));
								if(isUnitA)
								{
									sprintf((char*)defaultTxProfile.chargingSchedule[idxSchedule].chargingRateUnit, "A");

									for(int idxPeriod=0;idxPeriod<json_object_array_length(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"));idxPeriod++)
									{
										defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "startPeriod"));
										defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = (json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")==NULL?
																															   3:
																															   json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")));
										defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = (strstr(json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingRateUnit")),ChargingRateUnitEnumTypeStr[ChargingRateUnitEnumType_W])!=NULL?json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit"))/(220*defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases):json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit")));
									}
								}
								else
								{
									sprintf((char*)defaultTxProfile.chargingSchedule[idxSchedule].chargingRateUnit, "W");

									for(int idxPeriod=0;idxPeriod<json_object_array_length(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"));idxPeriod++)
									{
										defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "startPeriod"));
										defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = (json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")==NULL?
																															   3:
																															   json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")));
										defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = (strstr(json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingRateUnit")),ChargingRateUnitEnumTypeStr[ChargingRateUnitEnumType_W])!=NULL?json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit")):json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit"))*(220*defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases));
									}
								}

								// Optional item
								if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom") != NULL)
								{
									sprintf((char*)defaultTxProfile.validFrom, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom")));
								}
								else
								{
									sprintf((char*)defaultTxProfile.validFrom, " ");
								}

								if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo") != NULL)
								{
									sprintf((char*)defaultTxProfile.validTo, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo")));
								}
								else
								{
									sprintf((char*)defaultTxProfile.validTo, " ");
								}

								if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "recurrencyKind") != NULL)
								{
									sprintf((char*)defaultTxProfile.recurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "recurrencyKind")));
								}
								else
								{
									sprintf((char*)defaultTxProfile.recurrencyKind, " ");
								}

								if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "transactionId") != NULL)
								{
									sprintf((char*)defaultTxProfile.transactionId, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "transactionId")));
								}
								else
								{
									sprintf((char*)defaultTxProfile.transactionId, " ");
								}

								if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "duration") != NULL)
								{
									defaultTxProfile.chargingSchedule[idxSchedule].duration = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "duration"));
								}
								else
								{
									defaultTxProfile.chargingSchedule[idxSchedule].duration = 86400;
								}

								if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "startSchedule") != NULL)
								{
									sprintf((char*)defaultTxProfile.chargingSchedule[idxSchedule].startSchedule, "%s", json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "startSchedule")));
								}
								else
								{
									sprintf((char*)defaultTxProfile.chargingSchedule[idxSchedule].startSchedule, "%s", (!cpinitateMsg.bits[(connectorId==0?0:connectorId-1)].isOnCharging ? compositeProfile.chargingSchedule[idxSchedule].startSchedule : ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp));
								}

								if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "minChargingRate") != NULL)
								{
									defaultTxProfile.chargingSchedule[idxSchedule].minChargingRate = json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "minChargingRate"));
								}
								else
								{
									defaultTxProfile.chargingSchedule[idxSchedule].minChargingRate = -1;
								}
							}
						}
					}
					else
					{
						for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
						{
							defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = -1;
							defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = -1;
							defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = 3;
							defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].phaseToUse = 0;
						}

						if(defaultTxProfile.id == -1)
							DEBUG_INFO("TxDefaultProfile found.\n");
						else
							DEBUG_INFO("TxDefaultProfile updated.\n");

						// Required item
						defaultTxProfile.id = json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "id"));
						defaultTxProfile.stackLevel = json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "stackLevel"));
						sprintf((char*)defaultTxProfile.chargingProfileKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingProfileKind")));
						if(isUnitA)
						{
							sprintf((char*)defaultTxProfile.chargingSchedule[idxSchedule].chargingRateUnit, "A");

							for(int idxPeriod=0;idxPeriod<json_object_array_length(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"));idxPeriod++)
							{
								defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "startPeriod"));
								defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = (json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")==NULL?
																											  	  	   3:
																													   json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")));
								defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = (strstr(json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingRateUnit")),ChargingRateUnitEnumTypeStr[ChargingRateUnitEnumType_W])!=NULL?json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit"))/(220*defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases):json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit")));
							}
						}
						else
						{
							sprintf((char*)defaultTxProfile.chargingSchedule[idxSchedule].chargingRateUnit, "W");

							for(int idxPeriod=0;idxPeriod<json_object_array_length(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"));idxPeriod++)
							{
								defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "startPeriod"));
								defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = (json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")==NULL?
																											  	  	   3:
																													   json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")));
								defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = (strstr(json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingRateUnit")),ChargingRateUnitEnumTypeStr[ChargingRateUnitEnumType_W])!=NULL?json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit")):json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit"))*(220*defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases));
							}
						}

						// Optional item
						if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom") != NULL)
						{
							sprintf((char*)defaultTxProfile.validFrom, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom")));
						}
						else
						{
							sprintf((char*)defaultTxProfile.validFrom, " ");
						}

						if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo") != NULL)
						{
							sprintf((char*)defaultTxProfile.validTo, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo")));
						}
						else
						{
							sprintf((char*)defaultTxProfile.validTo, " ");
						}

						if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "recurrencyKind") != NULL)
						{
							sprintf((char*)defaultTxProfile.recurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "recurrencyKind")));
						}
						else
						{
							sprintf((char*)defaultTxProfile.recurrencyKind, " ");
						}

						if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "transactionId") != NULL)
						{
							sprintf((char*)defaultTxProfile.transactionId, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "transactionId")));
						}
						else
						{
							sprintf((char*)defaultTxProfile.transactionId, " ");
						}

						if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "duration") != NULL)
						{
							defaultTxProfile.chargingSchedule[idxSchedule].duration = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "duration"));
						}
						else
						{
							defaultTxProfile.chargingSchedule[idxSchedule].duration = 86400;
						}

						if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "startSchedule") != NULL)
						{
							sprintf((char*)defaultTxProfile.chargingSchedule[idxSchedule].startSchedule, "%s", json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "startSchedule")));
						}
						else
						{
							sprintf((char*)defaultTxProfile.chargingSchedule[idxSchedule].startSchedule, "%s", (!cpinitateMsg.bits[(connectorId==0?0:connectorId-1)].isOnCharging ? compositeProfile.chargingSchedule[idxSchedule].startSchedule : ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp));
						}

						if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "minChargingRate") != NULL)
						{
							defaultTxProfile.chargingSchedule[idxSchedule].minChargingRate = json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "minChargingRate"));
						}
						else
						{
							defaultTxProfile.chargingSchedule[idxSchedule].minChargingRate = -1;
						}
					}
				}
			}
			json_object_put(obj);
		}
		fclose(fp);
/*
		if(defaultTxProfile.id != -1)
		{
			DEBUG_INFO("Profile ID: %d\n", defaultTxProfile.id);
			DEBUG_INFO("Profile stackLevel: %d\n", defaultTxProfile.StackLevel);
			DEBUG_INFO("Profile TransactionId: %d\n", defaultTxProfile.TransactionId);
			DEBUG_INFO("Profile valid from: %s\n", defaultTxProfile.ValidFrom);
			DEBUG_INFO("Profile valid to: %s\n", defaultTxProfile.ValidTo);
			DEBUG_INFO("Profile ChargingProfileKind: %s\n", defaultTxProfile.ChargingProfileKind);
			DEBUG_INFO("Profile recurrencyKind: %s\n", defaultTxProfile.recurrencyKind);

			DEBUG_INFO("Profile start schedule: %s\n", defaultTxProfile.chargingSchedule[idxSchedule].StartSchedule);
			DEBUG_INFO("Profile schedule duration: %d\n", defaultTxProfile.chargingSchedule[idxSchedule].Duration);
			DEBUG_INFO("Profile charging rate unit: %s\n", defaultTxProfile.chargingSchedule[idxSchedule].ChargingRateUnit);
			DEBUG_INFO("Profile charging min rate: %f\n", defaultTxProfile.chargingSchedule[idxSchedule].MinChargingRate);

			for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(defaultTxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod);idxPeriod++)
			{
				if(defaultTxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].StartPeriod >= 0)
				{
					DEBUG_INFO("Period-%02d startPeriod: %d\n", idxPeriod, defaultTxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].StartPeriod);
					DEBUG_INFO("Period-%02d limit: %f\n", idxPeriod, defaultTxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].Limit);
					DEBUG_INFO("Period-%02d NumberPhases: %d\n", idxPeriod, defaultTxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].NumberPhases);
				}
			}
		}
		else
			DEBUG_INFO("TxDefaultProfile not found.\n");

		DEBUG_INFO("------------------------------------\n");*/
	}

	// Search max profile
	sprintf(profileFileName, "/tmp/ChargingStationMaxProfile_OCPP20.json");
	if((access(profileFileName, F_OK))!=-1)
	{
		fp = fopen(profileFileName, "r");

		while(getline(&line, &len, fp) != -1)
		{
			json_object *obj = NULL;

			obj = json_tokener_parse(line);
			if(is_error(obj))
			{
				DEBUG_ERROR("Parse MaxProfile from file error.\n");
			}
			else
			{
				if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "id")) != maxProfile.id) &&
				   (json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "stackLevel")) >= maxProfile.stackLevel)
				  )
				{
					if((json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom") != NULL) &&
					   (json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo") != NULL)
					  )
					{
						struct tm tmFrom, tmTo;
						struct timeb tbFrom, tbTo;

						if((sscanf((char*)json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom")), "%4d-%2d-%2dT%2d:%2d:%2d", &tmFrom.tm_year, &tmFrom.tm_mon, &tmFrom.tm_mday, &tmFrom.tm_hour, &tmFrom.tm_min, &tmFrom.tm_sec) == 6) &&
						   (sscanf((char*)json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo")), "%4d-%2d-%2dT%2d:%2d:%2d", &tmTo.tm_year, &tmTo.tm_mon, &tmTo.tm_mday, &tmTo.tm_hour, &tmTo.tm_min, &tmTo.tm_sec) == 6))
						{
							tmFrom.tm_year -= 1900;
							tmFrom.tm_mon -= 1;
							tbFrom.time = mktime(&tmFrom);

							tmTo.tm_year -= 1900;
							tmTo.tm_mon -= 1;
							tbTo.time = mktime(&tmTo);

							if((DiffTimebWithNowSec(tbFrom)>=0) && (DiffTimebWithNowSec(tbTo)<=0))
							{
								for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
								{
									maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = -1;
									maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = -1;
									maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = 3;
								}

								if(maxProfile.id == -1)
									DEBUG_INFO("MaxProfile found.\n");
								else
									DEBUG_INFO("MaxProfile updated.\n");

								// Required item
								maxProfile.id = json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "id"));
								maxProfile.stackLevel = json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "stackLevel"));
								sprintf((char*)maxProfile.chargingProfileKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingProfileKind")));

								if(isUnitA)
								{
									sprintf((char*)maxProfile.chargingSchedule[idxSchedule].chargingRateUnit, "A");

									for(int idxPeriod=0;idxPeriod<json_object_array_length(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"));idxPeriod++)
									{
										maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "startPeriod"));
										maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = (json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")==NULL?
																														 3:
																														 json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")));
										maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = (strstr(json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingRateUnit")),ChargingRateUnitEnumTypeStr[ChargingRateUnitEnumType_W])!=NULL?json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit"))/(220*maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases):json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit")));
									}
								}
								else
								{
									sprintf((char*)maxProfile.chargingSchedule[idxSchedule].chargingRateUnit, "W");

									for(int idxPeriod=0;idxPeriod<json_object_array_length(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"));idxPeriod++)
									{
										maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "startPeriod"));
										maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = (json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")==NULL?
																														 3:
																														 json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")));
										maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = (strstr(json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingRateUnit")),ChargingRateUnitEnumTypeStr[ChargingRateUnitEnumType_W])!=NULL?json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit")):json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit"))*(220*maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases));
									}
								}

								// Optional item
								if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom") != NULL)
								{
									sprintf((char*)maxProfile.validFrom, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom")));
								}
								else
								{
									sprintf((char*)maxProfile.validFrom, " ");
								}

								if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo") != NULL)
								{
									sprintf((char*)maxProfile.validTo, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo")));
								}
								else
								{
									sprintf((char*)maxProfile.validTo, " ");
								}

								if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "recurrencyKind") != NULL)
								{
									sprintf((char*)maxProfile.recurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "recurrencyKind")));
								}
								else
								{
									sprintf((char*)maxProfile.recurrencyKind, " ");
								}

								if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "transactionId") != NULL)
								{
									sprintf((char*)maxProfile.transactionId, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "transactionId")));
								}
								else
								{
									sprintf((char*)maxProfile.transactionId, " ");
								}

								if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "duration") != NULL)
								{
									maxProfile.chargingSchedule[idxSchedule].duration = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "duration"));
								}
								else
								{
									maxProfile.chargingSchedule[idxSchedule].duration = 86400;
								}

								if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "startSchedule") != NULL)
								{
									sprintf((char*)maxProfile.chargingSchedule[idxSchedule].startSchedule, "%s", json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "startSchedule")));
								}
								else
								{
									sprintf((char*)maxProfile.chargingSchedule[idxSchedule].startSchedule, "%s", (!cpinitateMsg.bits[(connectorId==0?0:connectorId-1)].isOnCharging ? compositeProfile.chargingSchedule[idxSchedule].startSchedule : ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp));
								}

								if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "minChargingRate") != NULL)
								{
									maxProfile.chargingSchedule[idxSchedule].minChargingRate = json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "minChargingRate"));
								}
								else
								{
									maxProfile.chargingSchedule[idxSchedule].minChargingRate = -1;
								}
							}
						}
					}
					else
					{
						for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
						{
							maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = -1;
							maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = -1;
							maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = 3;
						}

						if(maxProfile.id == -1)
							DEBUG_INFO("MaxProfile found.\n");
						else
							DEBUG_INFO("MaxProfile updated.\n");

						// Required item
						maxProfile.id = json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "id"));
						maxProfile.stackLevel = json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "stackLevel"));
						sprintf((char*)maxProfile.chargingProfileKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingProfileKind")));
						if(isUnitA)
						{
							sprintf((char*)maxProfile.chargingSchedule[idxSchedule].chargingRateUnit, "A");

							for(int idxPeriod=0;idxPeriod<json_object_array_length(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"));idxPeriod++)
							{
								maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "startPeriod"));
								maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = (json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")==NULL?
																												 3:
																												 json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")));
								maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = (strstr((char*)json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingRateUnit")),ChargingRateUnitEnumTypeStr[ChargingRateUnitEnumType_W])!=NULL?json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit"))/(220*maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases):json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit")));
							}
						}
						else
						{
							sprintf((char*)maxProfile.chargingSchedule[idxSchedule].chargingRateUnit, "W");

							for(int idxPeriod=0;idxPeriod<json_object_array_length(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"));idxPeriod++)
							{
								maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "startPeriod"));
								maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = (json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")==NULL?
																												 3:
																												 json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "numberPhases")));
								maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = (strstr((char*)json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingRateUnit")),ChargingRateUnitEnumTypeStr[ChargingRateUnitEnumType_W])!=NULL?json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit")):json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "chargingSchedulePeriod"), idxPeriod), "limit"))*(220*maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases));
							}
						}

						// Optional item
						if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom") != NULL)
						{
							sprintf((char*)maxProfile.validFrom, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validFrom")));
						}
						else
						{
							sprintf((char*)maxProfile.validFrom, " ");
						}

						if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo") != NULL)
						{
							sprintf((char*)maxProfile.validTo, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "validTo")));
						}
						else
						{
							sprintf((char*)maxProfile.validTo, " ");
						}

						if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "recurrencyKind") != NULL)
						{
							sprintf((char*)maxProfile.recurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "recurrencyKind")));
						}
						else
						{
							sprintf((char*)maxProfile.recurrencyKind, " ");
						}

						if(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "transactionId") != NULL)
						{
							sprintf((char*)maxProfile.transactionId,"%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "transactionId")));
						}
						else
						{
							sprintf((char*)maxProfile.transactionId, " ");
						}

						if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "duration") != NULL)
						{
							maxProfile.chargingSchedule[idxSchedule].duration = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "duration"));
						}
						else
						{
							maxProfile.chargingSchedule[idxSchedule].duration = 86400;
						}

						if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "startSchedule") != NULL)
						{
							sprintf((char*)maxProfile.chargingSchedule[idxSchedule].startSchedule, "%s", json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "startSchedule")));
						}
						else
						{
							sprintf((char*)maxProfile.chargingSchedule[idxSchedule].startSchedule, "%s", (!cpinitateMsg.bits[(connectorId==0?0:connectorId-1)].isOnCharging ? compositeProfile.chargingSchedule[idxSchedule].startSchedule : ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp));
						}

						if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "minChargingRate") != NULL)
						{
							maxProfile.chargingSchedule[idxSchedule].minChargingRate = json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "chargingSchedule"), 0), "minChargingRate"));
						}
						else
						{
							maxProfile.chargingSchedule[idxSchedule].minChargingRate = -1;
						}
					}
				}
			}
			json_object_put(obj);
		}
		fclose(fp);
/*
		if(maxProfile.id !=-1)
		{
			DEBUG_INFO("Profile ID: %d\n", maxProfile.id);
			DEBUG_INFO("Profile stackLevel: %d\n", maxProfile.StackLevel);
			DEBUG_INFO("Profile TransactionId: %d\n", maxProfile.TransactionId);
			DEBUG_INFO("Profile valid from: %s\n", maxProfile.ValidFrom);
			DEBUG_INFO("Profile valid to: %s\n", maxProfile.ValidTo);
			DEBUG_INFO("Profile ChargingProfileKind: %s\n", maxProfile.ChargingProfileKind);
			DEBUG_INFO("Profile recurrencyKind: %s\n", maxProfile.recurrencyKind);

			DEBUG_INFO("Profile start schedule: %s\n", maxProfile.chargingSchedule[idxSchedule].StartSchedule);
			DEBUG_INFO("Profile schedule duration: %d\n", maxProfile.chargingSchedule[idxSchedule].Duration);
			DEBUG_INFO("Profile charging rate unit: %s\n", maxProfile.chargingSchedule[idxSchedule].ChargingRateUnit);
			DEBUG_INFO("Profile charging min rate: %f\n", maxProfile.chargingSchedule[idxSchedule].MinChargingRate);

			for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod);idxPeriod++)
			{
				if(maxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].StartPeriod >= 0)
				{
					DEBUG_INFO("Period-%02d startPeriod: %d\n", idxPeriod, maxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].StartPeriod);
					DEBUG_INFO("Period-%02d limit: %f\n", idxPeriod, maxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].Limit);
					DEBUG_INFO("Period-%02d NumberPhases: %d\n", idxPeriod, maxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].NumberPhases);
				}
			}
		}
		else
			DEBUG_INFO("MaxProfile not found.\n");
		DEBUG_INFO("------------------------------------\n");*/
	}

	/*
	 * Align found profile start schedule & periods
	 */
	//DEBUG_INFO("====================================\n");
	/*
	// For local test usage, force modify found profile start schedule info
	sprintf((char*)maxProfile.chargingSchedule[idxSchedule].StartSchedule, "%04d-%02d-%02dT%02d:%02d:%02dZ", tmComposite->tm_year+1900, tmComposite->tm_mon+1, tmComposite->tm_mday, tmComposite->tm_hour, tmComposite->tm_min, tmComposite->tm_sec-10);
	sprintf((char*)defaultTxProfile.chargingSchedule[idxSchedule].StartSchedule, "%04d-%02d-%02dT%02d:%02d:%02dZ", tmComposite->tm_year+1900, tmComposite->tm_mon+1, tmComposite->tm_mday, tmComposite->tm_hour, tmComposite->tm_min, tmComposite->tm_sec-5);
	sprintf((char*)txProfile.chargingSchedule[idxSchedule].StartSchedule, "%04d-%02d-%02dT%02d:%02d:%02dZ", tmComposite->tm_year+1900, tmComposite->tm_mon+1, tmComposite->tm_mday, tmComposite->tm_hour, tmComposite->tm_min, tmComposite->tm_sec-3);
*/

	if(txProfile.id != -1)
	{
		if(strstr((char*)txProfile.chargingProfileKind, ChargingProfileKindEnumTypeStr[ChargingProfileKindEnumType_Absolute]) != NULL)
		{
			if(txProfile.chargingSchedule[idxSchedule].duration != -1)
			{
				txProfile.chargingSchedule[idxSchedule].duration = ((txProfile.chargingSchedule[idxSchedule].duration-getStartStop(txProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule))<0?
														0:
														(txProfile.chargingSchedule[idxSchedule].duration-getStartStop(txProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule)));
			}

			for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
			{
				if(txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod != -1)
				{
					txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = ((txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartStop(txProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule))<0?
																								 0:
																								 (txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartStop(txProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule)));

					if(idxPeriod > 0)
					{
						if(txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].startPeriod == txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod)
						{
							txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].limit = txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit;
						}
					}
				}
			}
		}
		else if(strstr((char*)txProfile.chargingProfileKind, ChargingProfileKindEnumTypeStr[ChargingProfileKindEnumType_Relative]) != NULL)
		{
			if(txProfile.chargingSchedule[idxSchedule].duration != -1)
			{
				txProfile.chargingSchedule[idxSchedule].duration = !cpinitateMsg.bits[(connectorId==0?0:connectorId-1)].isOnCharging?txProfile.chargingSchedule[idxSchedule].duration:((txProfile.chargingSchedule[idxSchedule].duration-getStartStop(ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp, compositeProfile.chargingSchedule[idxSchedule].startSchedule))<0?
																																								  0:
																																								 (txProfile.chargingSchedule[idxSchedule].duration-getStartStop(ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp, compositeProfile.chargingSchedule[idxSchedule].startSchedule)));
			}

			for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
			{
				if(txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod != -1)
				{
					txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = !cpinitateMsg.bits[(connectorId==0?0:connectorId-1)].isOnCharging?txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod:((txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartStop(ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp, compositeProfile.chargingSchedule[idxSchedule].startSchedule))<0?
																																																												0:
																																																											   (txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartStop(ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp, compositeProfile.chargingSchedule[idxSchedule].startSchedule)));

					if(idxPeriod > 0)
					{
						if(txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].startPeriod == txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod)
						{
							txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].limit = txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit;
						}
					}
				}
			}
		}
		else
		{
			if(strstr((char*)txProfile.recurrencyKind, RecurrencyKindEnumTypeStr[RecurrencyKindEnumType_Weekly]) != NULL)
			{
				if(txProfile.chargingSchedule[idxSchedule].duration != -1)
				{
					txProfile.chargingSchedule[idxSchedule].duration = ((txProfile.chargingSchedule[idxSchedule].duration-getStartSinceRecurring(txProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, FALSE))<0?
															0:
															(txProfile.chargingSchedule[idxSchedule].duration-getStartSinceRecurring(txProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, FALSE)));
				}

				for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
				{
					if(txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod != -1)
					{
						txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = ((txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartSinceRecurring(txProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, FALSE))<0?
																									 0:
																									 (txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartSinceRecurring(txProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, FALSE)));

						if(idxPeriod > 0)
						{
							if(txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].startPeriod == txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod)
							{
								txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].limit = txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit;
							}
						}
					}
				}
			}
			else
			{
				if(txProfile.chargingSchedule[idxSchedule].duration != -1)
				{
					txProfile.chargingSchedule[idxSchedule].duration = ((txProfile.chargingSchedule[idxSchedule].duration-getStartSinceRecurring(txProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, TRUE))<0?
															0:
															(txProfile.chargingSchedule[idxSchedule].duration-getStartSinceRecurring(txProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, TRUE)));
				}

				for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
				{
					if(txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod != -1)
					{
						txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = ((txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartSinceRecurring(txProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, TRUE))<0?
																									 0:
																									 (txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartSinceRecurring(txProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, TRUE)));

						if(idxPeriod > 0)
						{
							if(txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].startPeriod == txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod)
							{
								txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].limit = txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit;
							}
						}
					}
				}
			}
		}
/*
		DEBUG_INFO("txProfile after align.\n");
		DEBUG_INFO("Profile ID: %d\n", txProfile.id);
		DEBUG_INFO("Profile stackLevel: %d\n", txProfile.StackLevel);
		DEBUG_INFO("Profile TransactionId: %d\n", txProfile.TransactionId);
		DEBUG_INFO("Profile valid from: %s\n", txProfile.ValidFrom);
		DEBUG_INFO("Profile valid to: %s\n", txProfile.ValidTo);
		DEBUG_INFO("Profile ChargingProfileKind: %s\n", txProfile.ChargingProfileKind);
		DEBUG_INFO("Profile recurrencyKind: %s\n", txProfile.recurrencyKind);

		DEBUG_INFO("Profile start schedule: %s\n", compositeProfile.ChargingSchedule.StartSchedule);
		DEBUG_INFO("Profile schedule duration: %d\n", txProfile.chargingSchedule[idxSchedule].Duration);
		DEBUG_INFO("Profile charging rate unit: %s\n", txProfile.chargingSchedule[idxSchedule].ChargingRateUnit);
		DEBUG_INFO("Profile charging min rate: %f\n", txProfile.chargingSchedule[idxSchedule].MinChargingRate);

		for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(txProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod);idxPeriod++)
		{
			if(txProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].StartPeriod >= 0)
			{
				DEBUG_INFO("Period-%02d startPeriod: %d\n", idxPeriod, txProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].StartPeriod);
				DEBUG_INFO("Period-%02d limit: %f\n", idxPeriod, txProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].Limit);
				DEBUG_INFO("Period-%02d NumberPhases: %d\n", idxPeriod, txProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].NumberPhases);
			}
		}*/
	}

	if(defaultTxProfile.id != -1)
	{
		if(strstr((char*)defaultTxProfile.chargingProfileKind, ChargingProfileKindEnumTypeStr[ChargingProfileKindEnumType_Absolute]) != NULL)
		{
			if(defaultTxProfile.chargingSchedule[idxSchedule].duration != -1)
			{
				defaultTxProfile.chargingSchedule[idxSchedule].duration = ((defaultTxProfile.chargingSchedule[idxSchedule].duration-getStartStop(defaultTxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule))<0?
														0:
														(defaultTxProfile.chargingSchedule[idxSchedule].duration-getStartStop(defaultTxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule)));
			}

			for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
			{
				if(defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod != -1)
				{
					defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = ((defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartStop(defaultTxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule))<0?
																								 0:
																								 (defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartStop(defaultTxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule)));

					if(idxPeriod > 0)
					{
						if(defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].startPeriod == defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod)
						{
							defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].limit = defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit;
						}
					}
				}
			}
		}
		else if(strstr((char*)defaultTxProfile.chargingProfileKind, ChargingProfileKindEnumTypeStr[ChargingProfileKindEnumType_Relative]) != NULL)
		{
			if(defaultTxProfile.chargingSchedule[idxSchedule].duration != -1)
			{
				defaultTxProfile.chargingSchedule[idxSchedule].duration = !cpinitateMsg.bits[(connectorId==0?0:connectorId-1)].isOnCharging?defaultTxProfile.chargingSchedule[idxSchedule].duration:((defaultTxProfile.chargingSchedule[idxSchedule].duration-getStartStop(ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp, compositeProfile.chargingSchedule[idxSchedule].startSchedule))<0?
																																								  0:
																																								 (defaultTxProfile.chargingSchedule[idxSchedule].duration-getStartStop(ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp, compositeProfile.chargingSchedule[idxSchedule].startSchedule)));
			}

			for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
			{
				if(defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod != -1)
				{
					defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = !cpinitateMsg.bits[(connectorId==0?0:connectorId-1)].isOnCharging?defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod:((defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartStop(ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp, compositeProfile.chargingSchedule[idxSchedule].startSchedule))<0?
																																																												0:
																																																											   (defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartStop(ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp, compositeProfile.chargingSchedule[idxSchedule].startSchedule)));

					if(idxPeriod > 0)
					{
						if(defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].startPeriod == defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod)
						{
							defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].limit = defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit;
						}
					}
				}
			}
		}
		else
		{
			if(strstr((char*)defaultTxProfile.recurrencyKind, RecurrencyKindEnumTypeStr[RecurrencyKindEnumType_Weekly]) != NULL)
			{
				if(defaultTxProfile.chargingSchedule[idxSchedule].duration != -1)
				{
					defaultTxProfile.chargingSchedule[idxSchedule].duration = ((defaultTxProfile.chargingSchedule[idxSchedule].duration-getStartSinceRecurring(defaultTxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, FALSE))<0?
															0:
															(defaultTxProfile.chargingSchedule[idxSchedule].duration-getStartSinceRecurring(defaultTxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, FALSE)));
				}

				for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
				{
					if(defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod != -1)
					{
						defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = ((defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartSinceRecurring(defaultTxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, FALSE))<0?
																									 0:
																									 (defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartSinceRecurring(defaultTxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, FALSE)));

						if(idxPeriod > 0)
						{
							if(defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].startPeriod == defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod)
							{
								defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].limit = defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit;
							}
						}
					}
				}
			}
			else
			{
				if(defaultTxProfile.chargingSchedule[idxSchedule].duration != -1)
				{
					defaultTxProfile.chargingSchedule[idxSchedule].duration = ((defaultTxProfile.chargingSchedule[idxSchedule].duration-getStartSinceRecurring(defaultTxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, TRUE))<0?
															0:
															(defaultTxProfile.chargingSchedule[idxSchedule].duration-getStartSinceRecurring(defaultTxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, TRUE)));
				}

				for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
				{
					if(defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod != -1)
					{
						defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = ((defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartSinceRecurring(defaultTxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, TRUE))<0?
																									 0:
																									 (defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartSinceRecurring(defaultTxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, TRUE)));

						if(idxPeriod > 0)
						{
							if(defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].startPeriod == defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod)
							{
								defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].limit = defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit;
							}
						}
					}
				}
			}
		}
/*
		DEBUG_INFO("defaultTxProfile after align.\n");
		DEBUG_INFO("Profile ID: %d\n", defaultTxProfile.id);
		DEBUG_INFO("Profile stackLevel: %d\n", defaultTxProfile.StackLevel);
		DEBUG_INFO("Profile TransactionId: %d\n", defaultTxProfile.TransactionId);
		DEBUG_INFO("Profile valid from: %s\n", defaultTxProfile.ValidFrom);
		DEBUG_INFO("Profile valid to: %s\n", defaultTxProfile.ValidTo);
		DEBUG_INFO("Profile ChargingProfileKind: %s\n", defaultTxProfile.ChargingProfileKind);
		DEBUG_INFO("Profile recurrencyKind: %s\n", defaultTxProfile.recurrencyKind);

		DEBUG_INFO("Profile start schedule: %s\n", compositeProfile.ChargingSchedule.StartSchedule);
		DEBUG_INFO("Profile schedule duration: %d\n", defaultTxProfile.chargingSchedule[idxSchedule].Duration);
		DEBUG_INFO("Profile charging rate unit: %s\n", defaultTxProfile.chargingSchedule[idxSchedule].ChargingRateUnit);
		DEBUG_INFO("Profile charging min rate: %f\n", defaultTxProfile.chargingSchedule[idxSchedule].MinChargingRate);

		for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(defaultTxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod);idxPeriod++)
		{
			if(defaultTxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].StartPeriod >= 0)
			{
				DEBUG_INFO("Period-%02d startPeriod: %d\n", idxPeriod, defaultTxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].StartPeriod);
				DEBUG_INFO("Period-%02d limit: %f\n", idxPeriod, defaultTxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].Limit);
				DEBUG_INFO("Period-%02d NumberPhases: %d\n", idxPeriod, defaultTxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].NumberPhases);
			}
		}
		DEBUG_INFO("------------------------------------\n");*/
	}

	if(maxProfile.id != -1)
	{
		if(strstr((char*)maxProfile.chargingProfileKind, ChargingProfileKindEnumTypeStr[ChargingProfileKindEnumType_Absolute]) != NULL)
		{
			if(maxProfile.chargingSchedule[idxSchedule].duration != -1)
			{
				maxProfile.chargingSchedule[idxSchedule].duration = ((maxProfile.chargingSchedule[idxSchedule].duration-getStartStop(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule))<0?
														0:
														(maxProfile.chargingSchedule[idxSchedule].duration-getStartStop(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule)));
			}

			for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
			{
				if(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod != -1)
				{
					maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = ((maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartStop(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule))<0?
																								 0:
																								 (maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartStop(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule)));

					if(idxPeriod > 0)
					{
						if(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].startPeriod == maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod)
						{
							maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].limit = maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit;
						}
					}
				}
			}
		}
		else if(strstr((char*)maxProfile.chargingProfileKind, ChargingProfileKindEnumTypeStr[ChargingProfileKindEnumType_Relative]) != NULL)
		{
			if(maxProfile.chargingSchedule[idxSchedule].duration != -1)
			{
				maxProfile.chargingSchedule[idxSchedule].duration = !cpinitateMsg.bits[(connectorId==0?0:connectorId-1)].isOnCharging?maxProfile.chargingSchedule[idxSchedule].duration:((maxProfile.chargingSchedule[idxSchedule].duration-getStartStop(ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp, compositeProfile.chargingSchedule[idxSchedule].startSchedule))<0?
																																								  0:
																																								 (maxProfile.chargingSchedule[idxSchedule].duration-getStartStop(ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp, compositeProfile.chargingSchedule[9].startSchedule)));
			}

			for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
			{
				if(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod != -1)
				{
					maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = !cpinitateMsg.bits[(connectorId==0?0:connectorId-1)].isOnCharging?maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod:((maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartStop(ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp, compositeProfile.chargingSchedule[idxSchedule].startSchedule))<0?
																																																											    0:
																																																											   (maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartStop(ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp, compositeProfile.chargingSchedule[idxSchedule].startSchedule)));

					if(idxPeriod > 0)
					{
						if(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].startPeriod == maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod)
						{
							maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].limit = maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit;
						}
					}
				}
			}
		}
		else
		{
			if(strstr((char*)maxProfile.recurrencyKind, RecurrencyKindEnumTypeStr[RecurrencyKindEnumType_Weekly]) != NULL)
			{
				if(maxProfile.chargingSchedule[idxSchedule].duration != -1)
				{
					maxProfile.chargingSchedule[idxSchedule].duration = ((maxProfile.chargingSchedule[idxSchedule].duration-getStartSinceRecurring(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, FALSE))<0?
															0:
															(maxProfile.chargingSchedule[idxSchedule].duration-getStartSinceRecurring(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, FALSE)));
				}

				for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
				{
					if(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod != -1)
					{
						maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = ((maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartSinceRecurring(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, FALSE))<0?
																									 0:
																									 (maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartSinceRecurring(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, FALSE)));

						if(idxPeriod > 0)
						{
							if(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].startPeriod == maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod)
							{
								maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].limit = maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit;
							}
						}
					}
				}
			}
			else
			{
				if(maxProfile.chargingSchedule[idxSchedule].duration != -1)
				{
					maxProfile.chargingSchedule[idxSchedule].duration = ((maxProfile.chargingSchedule[idxSchedule].duration-getStartSinceRecurring(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, TRUE))<0?
															0:
															(maxProfile.chargingSchedule[idxSchedule].duration-getStartSinceRecurring(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, TRUE)));
				}

				for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
				{
					if(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod != -1)
					{
						maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = ((maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartSinceRecurring(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, TRUE))<0?
																									 0:
																									 (maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod-getStartSinceRecurring(maxProfile.chargingSchedule[idxSchedule].startSchedule, compositeProfile.chargingSchedule[idxSchedule].startSchedule, TRUE)));

						if(idxPeriod > 0)
						{
							if(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].startPeriod == maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod)
							{
								maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod-1].limit = maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit;
							}
						}
					}
				}
			}
		}
/*
		DEBUG_INFO("MaxProfile after align.\n");
		DEBUG_INFO("Profile ID: %d\n", maxProfile.id);
		DEBUG_INFO("Profile stackLevel: %d\n", maxProfile.StackLevel);
		DEBUG_INFO("Profile TransactionId: %d\n", maxProfile.TransactionId);
		DEBUG_INFO("Profile valid from: %s\n", maxProfile.ValidFrom);
		DEBUG_INFO("Profile valid to: %s\n", maxProfile.ValidTo);
		DEBUG_INFO("Profile ChargingProfileKind: %s\n", maxProfile.ChargingProfileKind);
		DEBUG_INFO("Profile recurrencyKind: %s\n", maxProfile.recurrencyKind);

		DEBUG_INFO("Profile start schedule: %s\n", compositeProfile.ChargingSchedule.StartSchedule);
		DEBUG_INFO("Profile schedule duration: %d\n", maxProfile.chargingSchedule[idxSchedule].Duration);
		DEBUG_INFO("Profile charging rate unit: %s\n", maxProfile.chargingSchedule[idxSchedule].ChargingRateUnit);
		DEBUG_INFO("Profile charging min rate: %f\n", maxProfile.chargingSchedule[idxSchedule].MinChargingRate);

		for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod);idxPeriod++)
		{
			if(maxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].StartPeriod >= 0)
			{
				DEBUG_INFO("Period-%02d startPeriod: %d\n", idxPeriod, maxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].StartPeriod);
				DEBUG_INFO("Period-%02d limit: %f\n", idxPeriod, maxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].Limit);
				DEBUG_INFO("Period-%02d NumberPhases: %d\n", idxPeriod, maxProfile.chargingSchedule[idxSchedule].ChargingSchedulePeriod[idxPeriod].NumberPhases);
			}
		}
		DEBUG_INFO("------------------------------------\n");*/
	}

	/*
	 * Merge to conposite schedule
	 */
	//DEBUG_INFO("====================================\n");
	// Find each profile period quantity
	for(int idx=0;idx<ARRAY_SIZE(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idx++)
	{
		if(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idx].limit != -1)
			limitMax = idx+1;
	}

	for(int idx=0;idx<ARRAY_SIZE(defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idx++)
	{
		if(defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idx].limit != -1)
			limitDef = idx+1;
	}

	for(int idx=0;idx<ARRAY_SIZE(txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idx++)
	{
		if(txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idx].limit != -1)
			limitTx = idx+1;
	}

	// TxProfile found, composite schedule based on it
	if(txProfile.id != -1)
	{
		compositeProfile.chargingSchedule[idxSchedule].duration = txProfile.chargingSchedule[idxSchedule].duration;
		for(int idxTxPeriod=0;idxTxPeriod<limitTx;idxTxPeriod++)
		{
			if((txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxTxPeriod].limit != -1) &&
			   (txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxTxPeriod].startPeriod < durationReq) &&
			   (txProfile.chargingSchedule[idxSchedule].duration > 0))
			{
				if(maxProfile.id != -1)
				{
					for(int idxMaxPeriod=0;idxMaxPeriod<limitMax;idxMaxPeriod++)
					{
						if((txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxTxPeriod].startPeriod >= maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod].startPeriod))
						{
							if((maxProfile.chargingSchedule[idxSchedule].duration > 0))
							{
								tmpPeriod.startPeriod = txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxTxPeriod].startPeriod;
								tmpPeriod.numberPhases = txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxTxPeriod].numberPhases;
								tmpPeriod.limit = (txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxTxPeriod].limit>maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod].limit?maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod].limit:txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxTxPeriod].limit);
							}
							else
							{
								tmpPeriod.startPeriod = txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxTxPeriod].startPeriod;
								tmpPeriod.numberPhases = txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxTxPeriod].numberPhases;
								tmpPeriod.limit = txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxTxPeriod].limit;
							}
						}

						if(idxMaxPeriod == (limitMax-1))
						{
							if(tmpPeriod.limit != compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)].limit)
							{
								if(tmpPeriod.startPeriod != compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)].startPeriod)
								{
									memcpy(&compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx], &tmpPeriod , sizeof(struct ChargingSchedulePeriodType));
									compositePeriodIdx++;
								}
								else
								{
									memcpy(&compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)], &tmpPeriod , sizeof(struct ChargingSchedulePeriodType));
								}
							}
						}
					}
				}
				else
				{
					if(txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxTxPeriod].startPeriod != compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)].startPeriod)
					{
						memcpy(&compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx], &txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxTxPeriod],sizeof(struct ChargingSchedulePeriodType));
						compositePeriodIdx++;
					}
					else
					{
						memcpy(&compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)], &txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxTxPeriod],sizeof(struct ChargingSchedulePeriodType));
					}
				}
			}

			if(idxTxPeriod == (limitTx-1))
			{
				if(defaultTxProfile.id != -1)
				{
					compositeProfile.chargingSchedule[idxSchedule].duration = (defaultTxProfile.chargingSchedule[idxSchedule].duration>compositeProfile.chargingSchedule[idxSchedule].duration)?defaultTxProfile.chargingSchedule[idxSchedule].duration:compositeProfile.chargingSchedule[idxSchedule].duration;
					for(int idxDefPeriod=0;idxDefPeriod<limitDef;idxDefPeriod++)
					{
						if((defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod].startPeriod >= (txProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxTxPeriod].startPeriod + (txProfile.chargingSchedule[idxSchedule].duration-defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod].startPeriod))) &&
						   (defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod].startPeriod < durationReq) &&
						   (defaultTxProfile.chargingSchedule[idxSchedule].duration>0))
						{
							if(maxProfile.id != -1)
							{
								for(int idxMaxPeriod=0;idxMaxPeriod<limitMax;idxMaxPeriod++)
								{
									if(defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod].startPeriod >= maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod].startPeriod)
									{
										if((maxProfile.chargingSchedule[idxSchedule].duration > 0))
										{
											tmpPeriod.startPeriod = defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod].startPeriod;
											tmpPeriod.numberPhases = defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod].numberPhases;
											tmpPeriod.limit = (defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod].limit>maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod].limit?maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod].limit:defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxTxPeriod].limit);
										}
										else
										{
											tmpPeriod.startPeriod = defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod].startPeriod;
											tmpPeriod.numberPhases = defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod].numberPhases;
											tmpPeriod.limit = defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod].limit;
										}

										if(tmpPeriod.limit != compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)].limit)
										{
											if(tmpPeriod.startPeriod != compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)].startPeriod)
											{
												memcpy(&compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx], &tmpPeriod , sizeof(struct ChargingSchedulePeriodType));
												compositePeriodIdx++;
											}
											else
											{
												memcpy(&compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)], &tmpPeriod , sizeof(struct ChargingSchedulePeriodType));
											}
										}

										// Delete duplicate period
										if(compositePeriodIdx > 1)
										{
											if(compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx-1].limit == compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx-2].limit)
											{
												compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx-1].startPeriod = -1;
												compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx-1].limit = -1;
												compositePeriodIdx -= 1;
											}
										}
									}
									else
									{
										if(defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod].startPeriod != compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)].startPeriod)
										{
											memcpy(&compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx], &defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod],sizeof(struct ChargingSchedulePeriodType));
											compositePeriodIdx++;
										}
										else
										{
											memcpy(&compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)], &defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod],sizeof(struct ChargingSchedulePeriodType));
										}
										break;
									}
								}
							}
							else
							{
								if(defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod].startPeriod != compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)].startPeriod)
								{
									memcpy(&compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx], &defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod],sizeof(struct ChargingSchedulePeriodType));
									compositePeriodIdx++;
								}
								else
								{
									memcpy(&compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)], &defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod],sizeof(struct ChargingSchedulePeriodType));
								}
							}
						}
					}
				}
			}
		}
	}
	// TxProfile not found but defaultTxProfile found, composite schedule based on it
	else if(defaultTxProfile.id != -1)
	{
		compositeProfile.chargingSchedule[idxSchedule].duration = defaultTxProfile.chargingSchedule[idxSchedule].duration;
		for(int idxDefPeriod=0;idxDefPeriod<limitDef;idxDefPeriod++)
		{
			if((defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod].limit != -1) &&
			   (defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod].startPeriod < durationReq) &&
			   (defaultTxProfile.chargingSchedule[idxSchedule].duration > 0))
			{
				if(maxProfile.id != -1)
				{
					for(int idxMaxPeriod=0;idxMaxPeriod<limitMax;idxMaxPeriod++)
					{
						if(defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod].startPeriod >= maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod].startPeriod)
						{
							tmpPeriod.startPeriod = defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod].startPeriod;
							tmpPeriod.numberPhases = defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod].numberPhases;

							if((maxProfile.chargingSchedule[idxSchedule].duration > 0))
							{
								tmpPeriod.limit = (defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod].limit>maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod].limit?maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod].limit:defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod].limit);
							}
							else
							{
								tmpPeriod.limit = defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod].limit;
							}

							if(tmpPeriod.limit != compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)].limit)
							{
								if(tmpPeriod.startPeriod != compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)].startPeriod)
								{
									memcpy(&compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx], &tmpPeriod , sizeof(struct ChargingSchedulePeriodType));
									compositePeriodIdx++;
								}
								else
								{
									memcpy(&compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)], &tmpPeriod , sizeof(struct ChargingSchedulePeriodType));
								}
							}

							// Delete duplicate period
							if(compositePeriodIdx > 1)
							{
								if(compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx-1].limit == compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx-2].limit)
								{
									compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx-1].startPeriod = -1;
									compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx-1].limit = -1;
									compositePeriodIdx -= 1;
								}
							}
						}
						else
						{
							if(defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod].startPeriod != compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)].startPeriod)
							{
								memcpy(&compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx], &defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod],sizeof(struct ChargingSchedulePeriodType));
								compositePeriodIdx++;
							}
							else
							{
								memcpy(&compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)], &defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod],sizeof(struct ChargingSchedulePeriodType));
							}
							break;
						}
					}
				}
				else
				{
					if(defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod].startPeriod != compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)].startPeriod)
					{
						memcpy(&compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx], &defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod],sizeof(struct ChargingSchedulePeriodType));
						compositePeriodIdx++;
					}
					else
					{
						memcpy(&compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)], &defaultTxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxDefPeriod],sizeof(struct ChargingSchedulePeriodType));
					}
				}
			}
		}
	}

	// Fill other period by MaxProfile
	if(maxProfile.id != -1)
	{
		if(compositePeriodIdx==0)
		{
			compositeProfile.chargingSchedule[idxSchedule].duration = maxProfile.chargingSchedule[idxSchedule].duration;
			for(int idxMaxPeriod=0;idxMaxPeriod<limitDef;idxMaxPeriod++)
			{
				if((maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod].limit != -1) &&
				   (maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod].startPeriod < durationReq) &&
				   (maxProfile.chargingSchedule[idxSchedule].duration > 0))
				{
					if(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod].startPeriod != compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)].startPeriod)
					{
						memcpy(&compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx], &maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod],sizeof(struct StructChargingSchedulePeriod));
						compositePeriodIdx++;
					}
					else
					{
						memcpy(&compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)], &maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod],sizeof(struct StructChargingSchedulePeriod));
					}
				}
			}
		}
		else
		{
			int lastCompositePeriodIdx = compositePeriodIdx;
			for(int idxMaxPeriod=0;idxMaxPeriod<limitMax;idxMaxPeriod++)
			{
				if((maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod].limit != -1) &&
				   (maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod].startPeriod < durationReq) &&
				   (maxProfile.chargingSchedule[idxSchedule].duration > 0))
				{
					if((maxProfile.chargingSchedule[idxSchedule].duration >= compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx-1].startPeriod))
					{
						if(maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod].limit > compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[lastCompositePeriodIdx-1].limit)
						{
							tmpPeriod.startPeriod = maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod].startPeriod;
							tmpPeriod.numberPhases = maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod].numberPhases;
							tmpPeriod.limit = compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[lastCompositePeriodIdx-1].limit;
						}
						else
						{
							tmpPeriod.startPeriod = maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod].startPeriod;
							tmpPeriod.numberPhases = maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod].numberPhases;
							tmpPeriod.limit = maxProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxMaxPeriod].limit;
						}
					}

					if(tmpPeriod.limit != -1)
					{
						if(tmpPeriod.limit != compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx-1)].limit)
						{
							if(tmpPeriod.startPeriod != compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx-1)].startPeriod)
							{
								memcpy(&compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx], &tmpPeriod , sizeof(struct ChargingSchedulePeriodType));
								compositePeriodIdx++;
							}
							else
							{
								memcpy(&compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[(compositePeriodIdx-1)], &tmpPeriod , sizeof(struct ChargingSchedulePeriodType));
							}
						}

						// Delete duplicate period
						if(compositePeriodIdx > 1)
						{
							if(compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx-1].limit == compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx-2].limit)
							{
								compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx-1].startPeriod = -1;
								compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[compositePeriodIdx-1].limit = -1;
								compositePeriodIdx -= 1;
							}
						}
					}
				}
			}
		}
	}

	compositeProfile.chargingSchedule[idxSchedule].duration = durationReq;
	DEBUG_INFO("Connector-%d composite schedule ready.\n", connectorId);
	DEBUG_INFO("Schedule start: %s\n", compositeProfile.chargingSchedule[idxSchedule].startSchedule);
	DEBUG_INFO("Schedule duration: %d\n", compositeProfile.chargingSchedule[idxSchedule].duration);
	DEBUG_INFO("Rate unit: %s\n", compositeProfile.chargingSchedule[idxSchedule].chargingRateUnit);
	for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
	{
		if(compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod >= 0)
		{
			compositeProfile.id = 1;
			DEBUG_INFO("Period-%02d startPeriod: %d\n", idxPeriod, compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod);
			DEBUG_INFO("Period-%02d limit: %f\n", idxPeriod, compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit);
			DEBUG_INFO("Period-%02d NumberPhases: %d\n", idxPeriod, compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases);
		}

		if(compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit == -1)
			compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit =0;

		if(compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod == -1)
			compositeProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod =0;
	}

	memcpy(targetCompositeProfile, &compositeProfile, sizeof(struct StructChargingProfile));

	if(line)
		free(line);

	ShmOCPP20Data->CSUMsg.bits[(connectorId==0?0:connectorId-1)].ChargingProfileConf = ON;
}

//==========================================
// Init all share memory
//==========================================
int InitShareMemory()
{
	int result = PASS;
	int MeterSMId;

	//creat ShmSysConfigAndInfo
	if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo),  0777)) < 0)
    {
		DEBUG_ERROR("shmget ShmSysConfigAndInfo NG\n");
		result = FAIL;
	}
    else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
    	DEBUG_ERROR("shmat ShmSysConfigAndInfo NG\n");
    	result = FAIL;
   	 }
    else
    {}

   	if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData),  0777)) < 0)
    {
   		DEBUG_ERROR("shmget ShmStatusCodeData NG\n");
   		result = FAIL;
	}
    else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
    	DEBUG_ERROR("shmat ShmStatusCodeData NG\n");
    	result = FAIL;
   	}
    else
    {}

	//creat ShmPsuData
   	if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData), 0777)) < 0)
    {
   		DEBUG_ERROR("shmget ShmPsuData NG\n");
   		result = FAIL;
	}
    else if ((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
    {
    	DEBUG_ERROR("shmat ShmPsuData NG\n");
    	result = FAIL;
   	}
    else
    {}

   	//creat ShmOCPP20Data
   	if ((MeterSMId = shmget(ShmOcpp20ModuleKey, sizeof(struct OCPP20Data),  0777)) < 0)
	{
		DEBUG_ERROR("shmget ShmOCPP20Data NG\n");
		result = FAIL;
	}
	else if ((ShmOCPP20Data = shmat(MeterSMId, NULL, 0)) == (void *) -1)
	{
		DEBUG_ERROR("shmat ShmOCPP20Data NG\n");
		result = FAIL;
	}
	else
	{}

    /****************************** For Initial Settings************************************************/
	/*
	DEBUG_INFO("Authorize_20 size: %d\n", sizeof(struct Authorize_20));
	DEBUG_INFO("BootNotification_20 size: %d\n", sizeof(struct BootNotification_20));
	DEBUG_INFO("CancelReservation_20 size: %d\n", sizeof(struct CancelReservation_20));
	DEBUG_INFO("CertificateSigned_20 size: %d\n", sizeof(struct CertificateSigned_20));
	DEBUG_INFO("ChangeAvailability_20 size: %d\n", sizeof(struct ChangeAvailability_20));
	DEBUG_INFO("ClearCache_20 size: %d\n", sizeof(struct ClearCache_20));
	DEBUG_INFO("ClearChargingProfile_20 size: %d\n", sizeof(struct ClearChargingProfile_20));
	DEBUG_INFO("ClearDisplayMessage_20 size: %d\n", sizeof(struct ClearDisplayMessage_20));
	DEBUG_INFO("ClearedChargingLimit_20 size: %d\n", sizeof(struct ClearedChargingLimit_20));
	DEBUG_INFO("ClearVariableMonitoring_20 size: %d\n", sizeof(struct ClearVariableMonitoring_20));
	DEBUG_INFO("CostUpdated_20 size: %d\n", sizeof(struct CostUpdated_20));
	DEBUG_INFO("CustomerInformation_20 size: %d\n", sizeof(struct CustomerInformation_20));
	DEBUG_INFO("DeleteCertificate_20 size: %d\n", sizeof(struct DeleteCertificate_20));
	DEBUG_INFO("FirmwareStatusNotification_20 size: %d\n", sizeof(struct FirmwareStatusNotification_20));
	DEBUG_INFO("Get15118EVCertificate_20 size: %d\n", sizeof(struct Get15118EVCertificate_20));
	DEBUG_INFO("GetBaseReport_20 size: %d\n", sizeof(struct GetBaseReport_20));
	DEBUG_INFO("GetCertificateStatus_20 size: %d\n", sizeof(struct GetCertificateStatus_20));
	DEBUG_INFO("GetChargingProfiles_20 size: %d\n", sizeof(struct GetChargingProfiles_20));
	DEBUG_INFO("GetCompositeSchedule_20 size: %d\n", sizeof(struct GetCompositeSchedule_20));
	DEBUG_INFO("GetDisplayMessages_20 size: %d\n", sizeof(struct GetDisplayMessages_20));
	DEBUG_INFO("GetInstalledCertificateIds_20 size: %d\n", sizeof(struct GetInstalledCertificateIds_20));
	DEBUG_INFO("GetLog_20 size: %d\n", sizeof(struct GetLog_20));
	DEBUG_INFO("GetMonitoringReport_20 size: %d\n", sizeof(struct GetMonitoringReport_20));
	DEBUG_INFO("GetReport_20 size: %d\n", sizeof(struct GetReport_20));
	DEBUG_INFO("GetTransactionStatus_20 size: %d\n", sizeof(struct GetTransactionStatus_20));
	DEBUG_INFO("GetVariables_20 size: %d\n", sizeof(struct GetVariables_20));
	DEBUG_INFO("InstallCertificate_20 size: %d\n", sizeof(struct InstallCertificate_20));
	DEBUG_INFO("LogStatusNotification_20 size: %d\n", sizeof(struct LogStatusNotification_20));
	DEBUG_INFO("MeterValues_20 size: %d\n", sizeof(struct MeterValues_20));
	DEBUG_INFO("NotifyChargingLimit_20 size: %d\n", sizeof(struct NotifyChargingLimit_20));
	DEBUG_INFO("NotifyCustomerInformation_20 size: %d\n", sizeof(struct NotifyCustomerInformation_20));
	DEBUG_INFO("NotifyDisplayMessages_20 size: %d\n", sizeof(struct NotifyDisplayMessages_20));
	DEBUG_INFO("NotifyEVChargingNeeds_20 size: %d\n", sizeof(struct NotifyEVChargingNeeds_20));
	DEBUG_INFO("NotifyEVChargingSchedule_20 size: %d\n", sizeof(struct NotifyEVChargingSchedule_20));
	DEBUG_INFO("NotifyEvent_20 size: %d\n", sizeof(struct NotifyEvent_20));
	DEBUG_INFO("NotifyMonitoringReport_20 size: %d\n", sizeof(struct NotifyMonitoringReport_20));
	DEBUG_INFO("NotifyReport_20 size: %d\n", sizeof(struct NotifyReport_20));
	DEBUG_INFO("PublishFirmware_20 size: %d\n", sizeof(struct PublishFirmware_20));
	DEBUG_INFO("PublishFirmwareStatusNotification_20 size: %d\n", sizeof(struct PublishFirmwareStatusNotification_20));
	DEBUG_INFO("ReportChargingProfiles_20 size: %d\n", sizeof(struct ReportChargingProfiles_20));
	DEBUG_INFO("RequestStartTransaction_20 size: %d\n", sizeof(struct RequestStartTransaction_20));
	DEBUG_INFO("RequestStopTransaction_20 size: %d\n", sizeof(struct RequestStopTransaction_20));
	DEBUG_INFO("ReservationStatusUpdate_20 size: %d\n", sizeof(struct ReservationStatusUpdate_20));
	DEBUG_INFO("ReserveNow_20 size: %d\n", sizeof(struct ReserveNow_20));
	DEBUG_INFO("Reset_20 size: %d\n", sizeof(struct Reset_20));
	DEBUG_INFO("SecurityEventNotification_20 size: %d\n", sizeof(struct SecurityEventNotification_20));
	DEBUG_INFO("SendLocalList_20 size: %d\n", sizeof(struct SendLocalList_20));
	DEBUG_INFO("SetChargingProfile_20 size: %d\n", sizeof(struct SetChargingProfile_20));
	DEBUG_INFO("SetDisplayMessage_20 size: %d\n", sizeof(struct SetDisplayMessage_20));
	DEBUG_INFO("SetMonitoringBase_20 size: %d\n", sizeof(struct SetMonitoringBase_20));
	DEBUG_INFO("SetMonitoringLevel_20 size: %d\n", sizeof(struct SetMonitoringLevel_20));
	DEBUG_INFO("SetNetworkProfile_20 size: %d\n", sizeof(struct SetNetworkProfile_20));
	DEBUG_INFO("SetVariableMonitoring_20 size: %d\n", sizeof(struct SetVariableMonitoring_20));
	DEBUG_INFO("SetVariables_20 size: %d\n", sizeof(struct SetVariables_20));
	DEBUG_INFO("SignCertificate_20 size: %d\n", sizeof(struct SignCertificate_20));
	DEBUG_INFO("StatusNotification_20 size: %d\n", sizeof(struct StatusNotification_20));
	DEBUG_INFO("TransactionEvent_20 size: %d\n", sizeof(struct TransactionEvent_20));
	DEBUG_INFO("TriggerMessage_20 size: %d\n", sizeof(struct TriggerMessage_20));
	DEBUG_INFO("UnlockConnector_20 size: %d\n", sizeof(struct UnlockConnector_20));
	DEBUG_INFO("UnpublishFirmware_20 size: %d\n", sizeof(struct UnpublishFirmware_20));
	DEBUG_INFO("UpdateFirmware_20 size: %d\n", sizeof(struct UpdateFirmware_20));
	DEBUG_INFO("ChargingProfileType size: %d\n", sizeof(struct ChargingProfileType));
*/
	return result;
}

int ProcessShareMemory()
{
	int result = PASS;

	if(InitShareMemory() == FAIL)
	{
		DEBUG_ERROR("InitShareMemory NG\n");

		if(ShmStatusCodeData!=NULL)
		{
			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=1;
		}

		result = FAIL;
	}

	if(RatedCurrentParsing((char*)ShmSysConfigAndInfo->SysConfig.ModelName, &modelnameInfo) != -1)
	{
		DEBUG_INFO("Model name rated power: %d\n", modelnameInfo.ratedPower);
	 	if((ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D') &&
	 	   ((ShmSysConfigAndInfo->SysConfig.ModelName[1]=='B') ||
		    (ShmSysConfigAndInfo->SysConfig.ModelName[1]=='K') ||
			(ShmSysConfigAndInfo->SysConfig.ModelName[1]=='O'))
		   ) // 'D' means DC
		{
			// DO series
			for(int gun_index=0; gun_index<GENERAL_GUN_QUANTITY ; gun_index++)
			{
				gunTotalNumber += 1;
				gunType[gun_index] = GUN_TYPE_DO;

 				switch(modelnameInfo.ParsingInfo[gun_index].GunType)
 				{
 					case Gun_Type_Chademo:
 						DEBUG_INFO("Gun-%02d type: Cabinet CHAdeMO\n", gun_index);
 						break;
 					case Gun_Type_CCS_2:
 						DEBUG_INFO("Gun-%02d type: Cabinet CCS\n", gun_index);
						break;
 					case Gun_Type_GB:
 						DEBUG_INFO("Gun-%02d type: Cabinet GBT\n", gun_index);
						break;
 					case Gun_Type_AC:
 						DEBUG_INFO("Gun-%02d type: Cabinet AC\n", gun_index);
						break;
 					default:
 						DEBUG_WARN("Gun-%02d type: Cabinet unknown\n", gun_index);
 						break;
 				}
			}
		}
		else
		{
 			for(int gun_index=0;gun_index<modelnameInfo.GetGunCount;gun_index++)
 			{
				gunTotalNumber += 1;

 				switch(modelnameInfo.ParsingInfo[gun_index].GunType)
 				{
 					case Gun_Type_Chademo:
 						gunType[gun_index] = GUN_TYPE_CHAdeMO;
 						DEBUG_INFO("Gun-%02d type: CHAdeMO\n", gun_index);
 						break;
 					case Gun_Type_CCS_2:
 						gunType[gun_index] = GUN_TYPE_CCS;
 						DEBUG_INFO("Gun-%02d type: CCS\n", gun_index);
						break;
 					case Gun_Type_GB:
 						gunType[gun_index] = GUN_TYPE_GBT;
 						DEBUG_INFO("Gun-%02d type: GBT\n", gun_index);
						break;
 					case Gun_Type_AC:
 						gunType[gun_index] = GUN_TYPE_AC;
 						DEBUG_INFO("Gun-%02d type: AC\n", gun_index);
						break;
 					default:
 						DEBUG_WARN("Gun-%02d type: Unknown\n", gun_index);
 						break;
 				}
 			}
		}
	}
	else
	{
		DEBUG_ERROR("Model name parsing fail.\n");
		result = FAIL;
	}

	if(result != PASS)sleep(5);

	return result;
}

//---------------------common routine---------------------------//
void checkNetworkProfile(void)
{
	memcpy(ShmOCPP20Data->OcppServerURL, ShmSysConfigAndInfo->SysConfig.OcppServerURL, ARRAY_SIZE(ShmOCPP20Data->OcppServerURL));

	json_object *priority;
	priority = json_tokener_parse((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_NetworkConfigurationPriority].variableAttribute[0].value);
	if(!is_error(priority))
	{
		for(uint8_t idxPriority=0;idxPriority<json_object_array_length(priority);idxPriority++)
		{
			for(uint8_t idx=0;idx<ARRAY_SIZE(ShmOCPP20Data->NetworkConnectionProfile);idx++)
			{
				if((ShmOCPP20Data->NetworkConnectionProfile[idx].slot == json_object_get_int(json_object_array_get_idx(priority, idxPriority))) &&
				   (strlen((char*)ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.ocppCsmsUrl) > 0) &&
				   (ShmOCPP20Data->NetworkConnectionProfile[idx].retryCount < 3))
				{
					memcpy(ShmOCPP20Data->OcppServerURL, ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.ocppCsmsUrl, ARRAY_SIZE(ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.ocppCsmsUrl));
					ShmOCPP20Data->NetworkConnectionProfile[idx].retryCount++;
					break;
				}
			}
		}
	}
	json_object_put(priority);

	DEBUG_INFO("Get network profile URL: %s\n", ShmOCPP20Data->OcppServerURL);
}

void checkRemoteStart(uint8_t connectorIdx)
{
	uint8_t tempIndex;
	int isAllowStart = TRUE;
	char cmdBuf[512];

	//check Transaction active
	if(gunType[connectorIdx-1] == GUN_TYPE_CHAdeMO)
	{
		if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
		{
			tempIndex =  ((connectorIdx-1) == 2) ? 1: 0;
		}
		else
		{
			tempIndex = (connectorIdx-1);
		}

		for (int index = 0; index < CHAdeMO_QUANTITY; index++)
		{
			if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex )
			{

				if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ReservationId != -1)&&(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ReservationId >= 0)&&(strcmp((const char *)ShmOCPP20Data->ReserveNow[index].idToken.idToken, (char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].idToken.idToken) == 0))
				{
					//Reserved
					DEBUG_INFO("CHAdeMO connector already reserved and idTag match.\n");
				}
				else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ReservationId != -1)&&(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ReservationId >= 0)&&(strcmp((const char *)ShmOCPP20Data->ReserveNow[index].idToken.idToken, (char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].idToken.idToken) != 0))
				{
					//Reserved
					DEBUG_INFO("CHAdeMO connector already reserved and idTag does not match.\n");
					isAllowStart = FALSE;
				}
				else
				{
					if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus != SYS_MODE_IDLE)				//S_IDLE
						&& (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus != SYS_MODE_PREPARING ) 	//S_PRECHARGE
						&& (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus != SYS_MODE_PREPARE_FOR_EV ) 	//S_PREPARING_FOR_EV
						&& (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus != SYS_MODE_PREPARE_FOR_EVSE ))   // S_PREPARING_FOR_EVSE
					{
						DEBUG_WARN("CHAdeMO connector not allow start cause busy.\n.");
						isAllowStart = FALSE;
					}
				}//END FOR ELSE
			}
		}// END FOR CHAdeMO_QUANTITY
	}
	else if(gunType[connectorIdx-1] == GUN_TYPE_CCS)
	{
		if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
		{
			tempIndex =  ((connectorIdx-1) == 2) ? 1: 0;
		}
		else
		{
			tempIndex = (connectorIdx-1);
		}

		for (int index = 0; index < CCS_QUANTITY; index++)
		{
			if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
			{
				if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ReservationId != -1)&&(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ReservationId >= 0)&&(strcmp((const char *)ShmOCPP20Data->ReserveNow[index].idToken.idToken, (char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].idToken.idToken) == 0))
				{
					//Reserved
					DEBUG_INFO("CCS connector already reserved and idTag match.\n");
				}
				else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ReservationId != -1)&&(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ReservationId >= 0)&&(strcmp((const char *)ShmOCPP20Data->ReserveNow[index].idToken.idToken, (char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].idToken.idToken) != 0))
				{
					//Reserved
					DEBUG_INFO("CCS connector already reserved and idTag does not match.\n");
					isAllowStart = FALSE;
				}
				else
				{
					if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != SYS_MODE_IDLE)          //S_IDLE
						&& (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != SYS_MODE_PREPARING)   	//S_PRECHARGE
						&& (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != SYS_MODE_PREPARE_FOR_EV)   	//S_PREPARING_FOR_EV
						&& (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != SYS_MODE_PREPARE_FOR_EVSE)) 	// S_PREPARING_FOR_EVSE
					{
						DEBUG_WARN("CCS connector not allow start cause busy.\n.");
						isAllowStart = FALSE;
					}

				}// END FOR ELSE
			}
		}// END FOR CCS_QUANTITY
	}
	else if(gunType[connectorIdx-1] == GUN_TYPE_GBT)
	{
		if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
		{
			tempIndex =  ((connectorIdx-1) == 2) ? 1: 0;
		}
		else
		{
			tempIndex = (connectorIdx-1);
		}

		for (int index = 0; index < GB_QUANTITY; index++)
		{
			if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex )
			{
				if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ReservationId != -1)&&(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ReservationId >= 0)&&(strcmp((const char *)ShmOCPP20Data->ReserveNow[index].idToken.idToken, (char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].idToken.idToken) == 0))
				{
					//Reserved
					DEBUG_INFO("GBT connector already reserved and idTag match.\n");
				}
				else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ReservationId != -1)&&(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ReservationId >= 0)&&(strcmp((const char *)ShmOCPP20Data->ReserveNow[index].idToken.idToken, (char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].idToken.idToken) != 0))
				{
					//Reserved
					DEBUG_INFO("GBT connector already reserved and idTag does not match.\n");
					isAllowStart = FALSE;
				}
				else
				{
					if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus != SYS_MODE_IDLE)         	//S_IDLE
						&& (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus != SYS_MODE_PREPARING)		//S_PRECHARGE
						&& (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus != SYS_MODE_PREPARE_FOR_EV)		//S_PREPARING_FOR_EV
						&& (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus != SYS_MODE_PREPARE_FOR_EVSE)) 		// S_PREPARING_FOR_EVSE
					{
						DEBUG_WARN("GBT connector not allow start cause busy.\n");
						isAllowStart = FALSE;
					}

				}// END FOR ELSE
			}
		} // END FOR GB_QUANTITY
	}
	else if(gunType[connectorIdx-1] == GUN_TYPE_DO)
	{
		tempIndex = (connectorIdx-1);

		for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
		{
			if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex )
			{
				if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ReservationId != -1)&&(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ReservationId >= 0)&&(strcmp((const char *)ShmOCPP20Data->ReserveNow[index].idToken.idToken, (char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].idToken.idToken) == 0))
				{
					//Reserved
					DEBUG_INFO("Dispenser connector already reserved and idTag match.\n");
				}
				else if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ReservationId != -1)&&(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ReservationId >= 0)&&(strcmp((const char *)ShmOCPP20Data->ReserveNow[index].idToken.idToken, (char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].idToken.idToken) != 0))
				{
					//Reserved
					DEBUG_INFO("Dispenser connector already reserved and idTag does not match.\n");
					isAllowStart = FALSE;
				}
				else
				{
					if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus != SYS_MODE_IDLE)         	//S_IDLE
						&& (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus != SYS_MODE_PREPARING)		//S_PRECHARGE
						&& (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus != SYS_MODE_PREPARE_FOR_EV)		//S_PREPARING_FOR_EV
						&& (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus != SYS_MODE_PREPARE_FOR_EVSE)) 		// S_PREPARING_FOR_EVSE
					{
						DEBUG_WARN("Dispenser connector not allow start cause busy.\n");
						isAllowStart = FALSE;
					}

				}// END FOR ELSE
			}
		} // END FOR GB_QUANTITY
	}
	else
	{
		if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D') // 'D' means DC
		{
			tempIndex = 2;
		}
		else
		{
			tempIndex = (connectorIdx-1);
		}

		for (int index = 0; index < AC_QUANTITY; index++)
		{
			if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex )
			{

				if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].ReservationId != -1)&&(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].ReservationId >= 0)&&(strcmp((const char *)ShmOCPP20Data->ReserveNow[index].idToken.idToken, (char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].idToken.idToken) == 0))
				{
					//Reserved
					DEBUG_INFO("AC connector already reserved and idTag match.\n");
				}
				else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].ReservationId != -1)&&(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].ReservationId >= 0)&&(strcmp((const char *)ShmOCPP20Data->ReserveNow[index].idToken.idToken, (char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].idToken.idToken) != 0))
				{
					//Reserved
					DEBUG_INFO("AC connector already reserved and idTag does not match.\n");
					isAllowStart = FALSE;
				}
				else
				{
					if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != SYS_MODE_IDLE)				//S_IDLE
						&& (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != SYS_MODE_PREPARING) 	//S_PRECHARGE
						&& (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != SYS_MODE_PREPARE_FOR_EV) 	//S_PREPARING_FOR_EV
						&& (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != SYS_MODE_PREPARE_FOR_EVSE))   // S_PREPARING_FOR_EVSE
					{
						DEBUG_WARN("AC connector not allow start cause busy.\n");
						isAllowStart = FALSE;
					}

				}//END FOR ELSE
			}
		}// END FOR AC_QUANTITY
	}

	if(isAllowStart == TRUE)
	{
		if(ShmOCPP20Data->RequestStartTransaction[connectorIdx -1].chargingProfile.id > 0)
		{
			if((access("/Storage/OCPP/TxProfile_Tmp_OCPP20.json", F_OK))!=-1)
			{
				sprintf(cmdBuf, "mv /Storage/OCPP/TxProfile_Tmp_OCPP20.json /Storage/OCPP/TxProfile_%d_OCPP20.json", connectorIdx);
				system(cmdBuf);
			}
		}

		ShmOCPP20Data->CsMsg.bits[connectorIdx-1].RequestStartTransactionReq = ON;
	}
}

void CheckSystemValue(void)
{
	char filenmae[100]={0};
	char str[100]={0};
	int tempIndex = 0;

	//===============================
	// EVSE operation check
	//===============================
	//===============================
	// Heartbeat check
	//===============================
	if((server_sign == TRUE) && (getDiffSecNow(clientTime.Heartbeat) >= (HeartBeatWaitTime + HeartBeatWithNOResponse)))
	{
		//parameter for test
		sendHeartbeatRequest(0);
	    //==============================================
		// Reset Waiting Time
		//==============================================
		HeartBeatWithNOResponse += 1;
	}

	//===============================
	// CSU Trigger Authorize Request
	//===============================
	if(isWebsocketSendable &&
	   (server_sign == TRUE) &&
	   (ShmOCPP20Data->SpMsg.bits.AuthorizeReq == ON) &&
	   (authorizeRetryTimes < 3))
	{
		sendAuthorizeRequest(0);
		authorizeRetryTimes = authorizeRetryTimes + 1;

		if(authorizeRetryTimes < 3)
			ShmOCPP20Data->SpMsg.bits.AuthorizeReq = OFF;

	}
	else if((server_sign == TRUE) &&
			(ShmOCPP20Data->SpMsg.bits.AuthorizeReq == ON) &&
			(authorizeRetryTimes >= 3))
	{
		authorizeRetryTimes = 0;
		SetOcppConnStatus(FALSE);
		server_sign = FALSE;
	}
	else if((server_sign == FALSE) &&
			(strcmp((const char *)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalAuthorizeOffline].variableAttribute[0].value, "TRUE") == 0) &&
			(strcmp((const char *)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_Enabled].variableAttribute[0].value, "TRUE") == 0) &&
			(ShmOCPP20Data->OcppConnStatus == OFF) &&
			(ShmOCPP20Data->SpMsg.bits.AuthorizeReq == ON))
	{
		sendAuthorizeRequest(0);
	}


	if(isWebsocketSendable &&
		   (server_sign == TRUE) &&
		   (ShmOCPP20Data->GetMonitoringReport.requestId > 0))
	{
		for(uint8_t idxCriterion=0;idxCriterion<ARRAY_SIZE(ShmOCPP20Data->GetMonitoringReport.monitoringCriteria);idxCriterion++)
		{
			if(strcmp((char*)ShmOCPP20Data->GetMonitoringReport.monitoringCriteria[idxCriterion],  MonitoringCriterionEnumTypeStr[MonitoringCriterionEnumType_ThresholdMonitoring]) == 0)
			{
				/*
				 * TODO:
				 * 	1. Report component that are ThresholdMonitoring
				 */
			}
			else if(strcmp((char*)ShmOCPP20Data->GetMonitoringReport.monitoringCriteria[idxCriterion], MonitoringCriterionEnumTypeStr[MonitoringCriterionEnumType_DeltaMonitoring]) == 0)
			{
				/*
				 * TODO:
				 * 	1. Report component that are DeltaMonitoring
				 */
			}
			else if(strcmp((char*)ShmOCPP20Data->GetMonitoringReport.monitoringCriteria[idxCriterion], MonitoringCriterionEnumTypeStr[MonitoringCriterionEnumType_PeriodicMonitoring]) == 0)
			{
				/*
				 * TODO:
				 * 	1. Report component that are PeriodicMonitoring
				 */
			}
			else
			{
				/*
				 * TODO:
				 * 	1. Process unknown criteria condition
				 */
			}
		}

		ShmOCPP20Data->GetMonitoringReport.requestId = 0;
	}

	if(isWebsocketSendable &&
	   (server_sign == TRUE) &&
	   (ShmOCPP20Data->GetReport.requestId > 0))
	{
		for(uint8_t idxCriterion=0;idxCriterion<ARRAY_SIZE(ShmOCPP20Data->GetReport.componentCriteria);idxCriterion++)
		{
			if(strcmp((char*)ShmOCPP20Data->GetReport.componentCriteria[idxCriterion], ComponentCriterionEnumTypeStr[ComponentCriterionEnumType_Active]) == 0)
			{
				/*
				 * TODO:
				 * 	1. Report component that are active
				 */
			}
			else if(strcmp((char*)ShmOCPP20Data->GetReport.componentCriteria[idxCriterion], ComponentCriterionEnumTypeStr[ComponentCriterionEnumType_Available]) == 0)
			{
				/*
				 * TODO:
				 * 	1. Report component that are available
				 */
			}
			else if(strcmp((char*)ShmOCPP20Data->GetReport.componentCriteria[idxCriterion], ComponentCriterionEnumTypeStr[ComponentCriterionEnumType_Enabled]) == 0)
			{
				/*
				 * TODO:
				 * 	1. Report component that are enable
				 */
			}
			else if(strcmp((char*)ShmOCPP20Data->GetReport.componentCriteria[idxCriterion], ComponentCriterionEnumTypeStr[ComponentCriterionEnumType_Problem]) == 0)
			{
				/*
				 * TODO:
				 * 	1. Report component that are problem
				 */
			}
			else
			{
				/*
				 * TODO:
				 * 	1. Process unknown criteria condition
				 */
			}
		}

		ShmOCPP20Data->GetReport.requestId = 0;
	}

	if(isWebsocketSendable &&
	   (server_sign == TRUE) &&
	   (ShmOCPP20Data->GetBaseReport.requestId > 0))
	{
		uint8_t reportIdx = 0;

		ShmOCPP20Data->NotifyReport.requestId = ShmOCPP20Data->GetBaseReport.requestId;

		if(strcmp((char*)ShmOCPP20Data->GetBaseReport.reportBase, ReportBaseEnumTypeStr[ReportBaseEnumType_ConfigurationInventory]) == 0)
		{
			for(uint8_t idx_var=0;idx_var<CtrlrVariable_CNT;idx_var++)
			{
				if(reportIdx < ARRAY_SIZE(ShmOCPP20Data->NotifyReport.reportData))
				{
					if((strcmp((char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableAttribute[0].mutability, MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]) == 0) || (strcmp((char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableAttribute[0].mutability, MutabilityEnumTypeStr[MutabilityEnumType_WriteOnly]) == 0))
					{
						memcpy(&ShmOCPP20Data->NotifyReport.reportData[reportIdx], &ShmOCPP20Data->ControllerComponentVariable[idx_var], sizeof(struct ReportDataType));
						reportIdx++;
					}
				}
				else
				{
					getNowDatetime(ShmOCPP20Data->NotifyReport.generatedAt);
					if(ShmOCPP20Data->NotifyReport.seqNo < INT_MAX)
						ShmOCPP20Data->NotifyReport.seqNo += 1;
					else
						ShmOCPP20Data->NotifyReport.seqNo = 0;

					sendNotifyReportRequest();
					memset(&ShmOCPP20Data->NotifyReport.reportData[0], 0x00, ARRAY_SIZE(ShmOCPP20Data->NotifyReport.reportData)*sizeof(struct ReportDataType));
					reportIdx = 0;
				}
			}
		}
		else if(strcmp((char*)ShmOCPP20Data->GetBaseReport.reportBase, ReportBaseEnumTypeStr[ReportBaseEnumType_FullInventory]) == 0)
		{
			for(uint8_t idx_var=0;idx_var<CtrlrVariable_CNT;idx_var++)
			{
				if(reportIdx < ARRAY_SIZE(ShmOCPP20Data->NotifyReport.reportData))
				{
					memcpy(&ShmOCPP20Data->NotifyReport.reportData[reportIdx], &ShmOCPP20Data->ControllerComponentVariable[idx_var], sizeof(struct ReportDataType));
					reportIdx++;
				}
				else
				{
					getNowDatetime(ShmOCPP20Data->NotifyReport.generatedAt);
					if(ShmOCPP20Data->NotifyReport.seqNo < INT_MAX)
						ShmOCPP20Data->NotifyReport.seqNo += 1;
					else
						ShmOCPP20Data->NotifyReport.seqNo = 0;

					sendNotifyReportRequest();
					memset(&ShmOCPP20Data->NotifyReport.reportData[0], 0x00, ARRAY_SIZE(ShmOCPP20Data->NotifyReport.reportData)*sizeof(struct ReportDataType));
					reportIdx = 0;
				}
			}
		}
		else
		{
			/*
			 * TODO:
			 * 	1. Fill out summary inventory to response message, currently not support
			 */
		}

		if(reportIdx > 0)
		{
			getNowDatetime(ShmOCPP20Data->NotifyReport.generatedAt);
			if(ShmOCPP20Data->NotifyReport.seqNo < INT_MAX)
				ShmOCPP20Data->NotifyReport.seqNo += 1;
			else
				ShmOCPP20Data->NotifyReport.seqNo = 0;

			sendNotifyReportRequest();
			memset(&ShmOCPP20Data->NotifyReport.reportData[0], 0x00, ARRAY_SIZE(ShmOCPP20Data->NotifyReport.reportData)*sizeof(struct ReportDataType));
			reportIdx = 0;
		}

		ShmOCPP20Data->GetBaseReport.requestId = 0;
	}

	if(isWebsocketSendable &&
	   (server_sign == TRUE) &&
	   ShmOCPP20Data->SpMsg.bits.NotifyEventReq)
	{
		getNowDatetime(ShmOCPP20Data->NotifyEvent.generatedAt);
		ShmOCPP20Data->NotifyEvent.tbc = FALSE;
		if(ShmOCPP20Data->NotifyEvent.seqNo < INT_MAX)
			ShmOCPP20Data->NotifyEvent.seqNo += 1;
		else
			ShmOCPP20Data->NotifyEvent.seqNo = 0;

		sendNotifyEventRequest();
		memset(&ShmOCPP20Data->NotifyEvent.eventData[0], 0x00, ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)* sizeof(struct EventDataType ));
		ShmOCPP20Data->SpMsg.bits.NotifyEventReq = OFF;
	}

	if(isWebsocketSendable &&
	   (server_sign == TRUE) &&
	   ShmOCPP20Data->SpMsg.bits.Get15118EVCertificateReq)
	{
		if(strcmp((char*)ShmOCPP20Data->Get15118EVCertificate.action, CertificateActionEnumTypeStr[CertificateActionEnumType_Install]) == 0)
		{
			/*
			 *	TODO:
			 *		1.
			 */
		}
		else if(strcmp((char*)ShmOCPP20Data->Get15118EVCertificate.action, CertificateActionEnumTypeStr[CertificateActionEnumType_Update]) == 0)
		{
			/*
			 *	TODO:
			 *		1.
			 */
		}
		else
		{
			/*
			 *	TODO:
			 *		1.
			 */
		}

		sendGet15118EVCertificateRequest();
		ShmOCPP20Data->SpMsg.bits.Get15118EVCertificateReq = OFF;
	}

	if(isWebsocketSendable &&
	   (server_sign == TRUE) &&
	   (ShmOCPP20Data->SpMsg.bits.SecurityEventNotificationReq == ON))
	{
		sendSecurityEventNotificationRequest();
		ShmOCPP20Data->SpMsg.bits.SecurityEventNotificationReq = OFF;
	}

	if(isWebsocketSendable &&
	   (server_sign == TRUE) &&
	   (ShmOCPP20Data->SpMsg.bits.NotifyCustomerInformationReq == ON))
	{
		sendNotifyCustomerInformationRequest();
		ShmOCPP20Data->SpMsg.bits.NotifyCustomerInformationReq = OFF;
	}

	for(int gun_index=0;gun_index < gunTotalNumber;gun_index++)
	{
		// ClockAlign MeterValue
		if(isWebsocketSendable && (server_sign == TRUE) && ((atoi((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Interval].variableAttribute[0].value) > 0)?((getTimePassSinceToday(gun_index)%(atoi((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Interval].variableAttribute[0].value)))==0):FALSE))
		{
			//check Transaction active
			if(gunType[gun_index] == GUN_TYPE_CHAdeMO)
			{
				if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
				{
					tempIndex = ((gun_index==2) ? 1: 0);
				}
				else
				{
					tempIndex = gun_index;
				}

				for (int index = 0; index < CHAdeMO_QUANTITY; index++)
				{
					// 0: Booting, 1: idle, 2: authorizing, 3: preparing, 4: charging, 5: terminating, 6: alarm, 7: fault
					if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex)
					{
						cpinitateMsg.bits[gun_index].ClockAlignMeterReq = ON;
					}
				}// End for CHAdeMO
			}
			else if(gunType[gun_index] == GUN_TYPE_CCS)
			{
				if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
				{
					tempIndex = ((gun_index==2) ? 1: 0);
				}
				else
				{
					tempIndex = gun_index;
				}

				for (int index = 0; index < CCS_QUANTITY; index++)
				{
					// 0: Booting, 1: idle, 2: authorizing, 3: preparing, 4: charging, 5: terminating, 6: alarm, 7: fault
					if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
					{
						cpinitateMsg.bits[gun_index].ClockAlignMeterReq = ON;
					}
				} // End for CCS
			}
			else if(gunType[gun_index] == GUN_TYPE_GBT)
			{
				if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
				{
					tempIndex = ((gun_index==2) ? 1: 0);
				}
				else
				{
					tempIndex = gun_index;
				}

				for (int index = 0; index < GB_QUANTITY; index++)
				{
					// 0: Booting, 1: idle, 2: authorizing, 3: preparing, 4: charging, 5: terminating, 6: alarm, 7: fault
					if(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex)
					{
						cpinitateMsg.bits[gun_index].SampleMeterReq = ON;
					}
				}// End for GB
			}
			else if(gunType[gun_index] == GUN_TYPE_DO)
			{
				tempIndex = gun_index;

				for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
				{
					// 0: Booting, 1: idle, 2: authorizing, 3: preparing, 4: charging, 5: terminating, 6: alarm, 7: fault
					if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
					{
						cpinitateMsg.bits[gun_index].ClockAlignMeterReq = ON;
					}
				}
			}
			else
			{

				if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
				{
					tempIndex = 2;
				}
				else
				{
					tempIndex = gun_index;
				}

				for (int index = 0; index < AC_QUANTITY; index++)
				{
					// 0: Booting, 1: idle, 2: authorizing, 3: preparing, 4: charging, 5: terminating, 6: alarm, 7: fault
					if(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
					{
						cpinitateMsg.bits[gun_index].ClockAlignMeterReq = ON;
					}
				}//End for AC
			}
		}
	}

	//===============================
	// Each connector operation check
	//===============================
	for(int gun_index=0;gun_index < gunTotalNumber ;gun_index++)
	{
		//==========================================
		// Check remote start without connector id
		//==========================================
		if(ShmOCPP20Data->MsMsg.bits.isRemoteStartWaitReq)
		{
			int connectorIdInt = -1;

			for(uint8_t gun_index=0;gun_index<gunTotalNumber;gun_index++)
			{
				if(!cpinitateMsg.bits[gun_index].isOnCharging && (strstr((char*)ShmOCPP20Data->StatusNotification[gun_index].connectorStatus, ConnectorStatusEnumTypeStr[ConnectorStatusEnumType_Occupied]) != NULL))
				{
					connectorIdInt = (gun_index+1);
					DEBUG_INFO("Detect connector-%02d connected ready to start.\n", connectorIdInt);
					checkRemoteStart(connectorIdInt);
					ShmOCPP20Data->MsMsg.bits.isRemoteStartWaitReq = OFF;
					break;
				}
			}

			if(getDiffSecNow(clientTime.RemoteStartWait) > atoi((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut].variableAttribute[0].value))
			{
				DEBUG_WARN("Remote start request without connector id wait link over %s seconds.\n", (char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut].variableAttribute[0].value);
				ShmOCPP20Data->MsMsg.bits.isRemoteStartWaitReq = OFF;
			}
		}

		//==========================================
		// csu trigger DataTransferReq
		//==========================================
		if(isWebsocketSendable && (server_sign == TRUE) && (ShmOCPP20Data->CsMsg.bits[gun_index].DataTransferReq == ON))
		{
			sendDataTransferRequest(gun_index);
			ShmOCPP20Data->CsMsg.bits[gun_index].DataTransferReq = OFF;
		}

		//==============================================
		// Charger status notification & Transaction event report
		//==============================================
		//--- Check Mode Change ---//
		// J: CHAdeMO  U: CCS1 combo  E: CCS2 combo  G: GBT DCcc
		if(gunType[gun_index] == GUN_TYPE_CHAdeMO)
		{

			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = ((gun_index==2) ? 1: 0);
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < CHAdeMO_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex)
				{
					if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus != ChademoPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ConnectorPlugIn != ChademoPreviousConnectorPlugIn[index]) )
					{
						ChademoPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus;
						ChademoPreviousConnectorPlugIn[index] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ConnectorPlugIn;
						cpinitateMsg.bits[gun_index].StatusNotificationReq = ON;

						if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus >= SYS_MODE_CHARGING) &&
						   (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus <= SYS_MODE_COMPLETE))
						{
							ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = ON;
						}

						if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex) && ((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_COMPLETE) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus <= SYS_MODE_IDLE))) // complete
						{
							sprintf(filenmae,"/Storage/OCPP/TxProfile_%d_OCPP20.json",(gun_index+1));
							if((access(filenmae,F_OK))!=-1)
							{
								DEBUG_INFO("TxProfile exist. OCPP will delete TX Charging Profile\n");

								sprintf(str,"rm -f %s",filenmae);
								system(str);
							}
						}
					}

					cpinitateMsg.bits[gun_index].isOnCharging = ((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_TERMINATING)?1:0);

				#if 1 // for TempStopTransaction
					if(((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_BOOTING) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_IDLE)) &&
					   (ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq == OFF))
					{
						checkTempStopTransaction(gun_index);
					}
				#endif
				}
			}
		}
		else if(gunType[gun_index] == GUN_TYPE_CCS)
		{

			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = ((gun_index==2) ? 1: 0);
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < CCS_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
				{
					if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != CcsPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ConnectorPlugIn != CcsPreviousConnectorPlugIn[index]) )//if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != CcsPreviousSystemStatus[index]/*PRE_SYS_MODE[gun_index]*/ )
					{
						CcsPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus;
						CcsPreviousConnectorPlugIn[index] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ConnectorPlugIn;
						cpinitateMsg.bits[gun_index].StatusNotificationReq = ON;

						if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus >= SYS_MODE_CHARGING) &&
						   (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus <= SYS_MODE_COMPLETE))
						{
							ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = ON;
						}

						if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex) && ((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_COMPLETE) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus <= SYS_MODE_IDLE))) // complete
						{
							sprintf(filenmae,"/Storage/OCPP/TxProfile_%d_OCPP20.json",(gun_index+1));
							if((access(filenmae,F_OK))!=-1)
							{
								DEBUG_INFO("TxProfile exist. OCPP will delete TX Charging Profile\n");
								sprintf(str,"rm -f %s",filenmae);
								system(str);
							}
						}
					}

					cpinitateMsg.bits[gun_index].isOnCharging = ((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_TERMINATING)?1:0);

				#if 1 // for TempStopTransaction
					if(((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_BOOTING) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_IDLE)) &&
					   (ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq == OFF))
					{
						checkTempStopTransaction(gun_index);
					}
				#endif
				}
			}
		}
		else if(gunType[gun_index] == GUN_TYPE_GBT)
		{

			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = ((gun_index==2) ? 1: 0);
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < GB_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex)
				{
					if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus != GbPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ConnectorPlugIn != GbPreviousConnectorPlugIn[index]) )
					{
						GbPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus;
						GbPreviousConnectorPlugIn[index] = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ConnectorPlugIn;
						cpinitateMsg.bits[gun_index].StatusNotificationReq = ON;

						if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus >= SYS_MODE_CHARGING) &&
						   (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus <= SYS_MODE_COMPLETE))
						{
							ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = ON;
						}

						if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex) && ((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_COMPLETE) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus <= SYS_MODE_IDLE))) // complete
						{
							sprintf(filenmae,"/Storage/OCPP/TxProfile_%d_OCPP20.json",(gun_index+1));
							if((access(filenmae,F_OK))!=-1)
							{
								DEBUG_INFO("TxProfile exist. OCPP will delete TX Charging Profile\n");
								sprintf(str,"rm -f %s",filenmae);
								system(str);
							}
						}
					}

					cpinitateMsg.bits[gun_index].isOnCharging = ((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_TERMINATING)?1:0);

				#if 1 // for TempStopTransaction
					if(((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_BOOTING) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_IDLE)) &&
					   (ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq == OFF))
					{
						checkTempStopTransaction(gun_index);
					}
				#endif
				}
			}

		}
		else if(gunType[gun_index] == GUN_TYPE_DO)
		{
			tempIndex = gun_index;

			for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
				{
					if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus != DoPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ConnectorPlugIn != DoPreviousConnectorPlugIn[index]) )
					{
						DoPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus;
						DoPreviousConnectorPlugIn[index] = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ConnectorPlugIn;
						cpinitateMsg.bits[gun_index].StatusNotificationReq = ON;

						if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus >= SYS_MODE_CHARGING) &&
						   (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus <= SYS_MODE_COMPLETE))
						{
							ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = ON;
						}

						if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex) && ((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_COMPLETE) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus <= SYS_MODE_IDLE))) // complete
						{
							sprintf(filenmae,"/Storage/OCPP/TxProfile_%d_OCPP20.json",(gun_index+1));
							if((access(filenmae,F_OK))!=-1)
							{
								DEBUG_INFO("TxProfile exist. OCPP will delete TX Charging Profile\n");
								sprintf(str,"rm -f %s",filenmae);
								system(str);
							}
						}
					}

					cpinitateMsg.bits[gun_index].isOnCharging = ((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_TERMINATING)?1:0);

				#if 1 // for TempStopTransaction
					if(((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_BOOTING) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_IDLE)) &&
					   (ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq == OFF))
					{
						checkTempStopTransaction(gun_index);
					}
				#endif
				}
			}
		}
		else
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
			{
				tempIndex = 2;
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < AC_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
				{
					if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != AcPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState != AcPreviousConnectorPlugIn[index]) )
					{
						AcPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus;
						AcPreviousConnectorPlugIn[index] = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState;

						if(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != SYS_MODE_AUTHORIZING)
							cpinitateMsg.bits[gun_index].StatusNotificationReq = ON;

						if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus >= SYS_MODE_PREPARING) &&
						   (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus <= SYS_MODE_COMPLETE))
						{
							ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = ON;
						}

						if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex) && ((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_COMPLETE) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus <= SYS_MODE_IDLE))) // complete
						{
							sprintf(filenmae,"/Storage/OCPP/TxProfile_%d_OCPP20.json",(gun_index+1));
							if((access(filenmae,F_OK))!=-1)
							{
								DEBUG_INFO("TxProfile exist. OCPP will delete TX Charging Profile\n");

								sprintf(str,"rm -f %s",filenmae);
								system(str);
							}
						}
					}

					cpinitateMsg.bits[gun_index].isOnCharging = ((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_TERMINATING)?1:0);

				#if 1 // for TempStopTransaction
					if(((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_BOOTING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_IDLE)) &&
					   (ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq == OFF))
					{
						checkTempStopTransaction(gun_index);
					}
				#endif
				}
			}// END

		}

		if(isWebsocketSendable && (server_sign == TRUE) && (getDiffSecNow(clientTime.StatusNotification[gun_index]) >= 5) && (ShmOCPP20Data->MsMsg.bits.ResetConf != ON) &&
		   ((cpinitateMsg.bits[gun_index].StatusNotificationReq == ON) || (cpinitateMsg.bits[gun_index].TriggerStatusNotificationReq == ON) ||
		   ((strcmp((const char *)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationPeriodically].variableAttribute[0].value, "TRUE") == 0) &&
			(getDiffSecNow(clientTime.StatusNotification[gun_index]) >= atoi((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationInterval].variableAttribute[0].value)))))
		{
			sendStatusNotificationRequest(gun_index);
			refreshStartTimer(&clientTime.StatusNotification[gun_index]);
		}

		//==============================================
		// CSU Trigger Smart Charging Profile
		//==============================================
		if(ShmOCPP20Data->CSUMsg.bits[gun_index].ChargingProfileReq == ON)
		{
			checkChargingStationMaxProfile(86400, &ShmOCPP20Data->MaxChargingProfile, 0, TRUE);
			checkCompositeSchedule(gun_index+1, 86400, &ShmOCPP20Data->SmartChargingProfile[gun_index], 0, TRUE);
			ShmOCPP20Data->CSUMsg.bits[gun_index].ChargingProfileReq = OFF;
		}

		//==============================================
		// CSU transaction event
		//==============================================
		if(ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq == ON)
		{
			sendTransactionEventRequest(gun_index);
			ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = OFF;
			//storeTempStopTransaction(gun_index);
			//memset(&ShmOCPP20Data->TransactionEvent[gun_index].meterValue[0], 0x00, sizeof(struct MeterValueType));
		}

		//==============================================
		// Meter report
		//==============================================
		if(isWebsocketSendable && (server_sign == TRUE) && cpinitateMsg.bits[gun_index].TriggerMeterValueReq)
		{
			sendMeterValuesRequest(gun_index, ReadingContextEnumType_Trigger);
			cpinitateMsg.bits[gun_index].TriggerMeterValueReq = OFF;
		}

		if(isWebsocketSendable && (cpinitateMsg.bits[gun_index].ClockAlignMeterReq == ON))
		{
			sendMeterValuesRequest(gun_index, ReadingContextEnumType_Sample_Clock);
			cpinitateMsg.bits[gun_index].ClockAlignMeterReq = OFF;
		}

		// Sample period MeterValue
		if(getDiffSecNow(clientTime.MeterValues[gun_index]) >= ((atoi((const char *)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedInterval].variableAttribute[0].value)>3)?(atoi((const char *)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedInterval].variableAttribute[0].value)- 1):3))
		{
			//check Transaction active
			if(gunType[gun_index] == GUN_TYPE_CHAdeMO)
			{
				if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
				{
					tempIndex = ((gun_index==2) ? 1: 0);
				}
				else
				{
					tempIndex = gun_index;
				}

				for (int index = 0; index < CHAdeMO_QUANTITY; index++)
				{
					// 0: Booting, 1: idle, 2: authorizing, 3: preparing, 4: charging, 5: terminating, 6: alarm, 7: fault
					if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex)
					{
						if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_CHARGING)
						{
							cpinitateMsg.bits[gun_index].SampleMeterReq = ON;
						}
					}
				}// End for CHAdeMO
			}
			else if(gunType[gun_index] == GUN_TYPE_CCS)
			{
				if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
				{
					tempIndex = ((gun_index==2) ? 1: 0);
				}
				else
				{
					tempIndex = gun_index;
				}

				for (int index = 0; index < CCS_QUANTITY; index++)
				{
					// 0: Booting, 1: idle, 2: authorizing, 3: preparing, 4: charging, 5: terminating, 6: alarm, 7: fault
					if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
					{
						if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_CHARGING)
						{
							cpinitateMsg.bits[gun_index].SampleMeterReq = ON;
						}
					}
				} // End for CCS
			}
			else if(gunType[gun_index] == GUN_TYPE_GBT)
			{
				if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
				{
					tempIndex = ((gun_index==2) ? 1: 0);
				}
				else
				{
					tempIndex = gun_index;
				}

				for (int index = 0; index < GB_QUANTITY; index++)
				{
					// 0: Booting, 1: idle, 2: authorizing, 3: preparing, 4: charging, 5: terminating, 6: alarm, 7: fault
					if(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex)
					{
						if(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_CHARGING)
						{
							cpinitateMsg.bits[gun_index].SampleMeterReq = ON;
						}
					}
				}// End for GB
			}
			else if(gunType[gun_index] == GUN_TYPE_DO)
			{
				tempIndex = gun_index;

				for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
				{
					// 0: Booting, 1: idle, 2: authorizing, 3: preparing, 4: charging, 5: terminating, 6: alarm, 7: fault
					if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
					{
						if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_CHARGING)
						{
							cpinitateMsg.bits[gun_index].SampleMeterReq = ON;
						}
					}
				}
			}
			else
			{
				if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
				{
					tempIndex = 2;
				}
				else
				{
					tempIndex = gun_index;
				}

				for (int index = 0; index < AC_QUANTITY; index++)
				{
					// 0: Booting, 1: idle, 2: authorizing, 3: preparing, 4: charging, 5: terminating, 6: alarm, 7: fault
					if(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
					{
						if(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_CHARGING)
						{
							cpinitateMsg.bits[gun_index].SampleMeterReq = ON;
						}
					}
				}//End for AC
			}

			if(cpinitateMsg.bits[gun_index].SampleMeterReq == ON)
			{
				if(atoi((const char *)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedInterval].variableAttribute[0].value) > 0)
					sendMeterValuesRequest(gun_index, ReadingContextEnumType_Sample_Periodic);

				cpinitateMsg.bits[gun_index].SampleMeterReq = OFF;
			}

			refreshStartTimer(&clientTime.MeterValues[gun_index]);
		}

		//==============================================
		// Check Connector reserved
		//==============================================
		//===============================
		// Check if Reserve is expired
		//===============================
		if((server_sign == TRUE) && (ShmOCPP20Data->ReserveNow[gun_index].expiryDateTime[0] != 0))
		{
			if(isOvertNow(ShmOCPP20Data->ReserveNow[gun_index].expiryDateTime))
			{
				DEBUG_INFO("reserve expired.\n");
				ShmOCPP20Data->ReservationStatusUpdate[gun_index].reservationId = ShmOCPP20Data->ReserveNow[gun_index].id;
				sprintf((char*)ShmOCPP20Data->ReservationStatusUpdate[gun_index].reservationUpdateStatus, ReservationUpdateStatusEnumTypeStr[ReservationUpdateStatusEnumType_Expired]);
				ShmOCPP20Data->CpMsg.bits[gun_index].ReservationStatusUpdateReq = ON;

				memset(ShmOCPP20Data->ReserveNow[gun_index].expiryDateTime,0,ARRAY_SIZE(ShmOCPP20Data->ReserveNow[gun_index].expiryDateTime));
			}

		}//END OF Check if Reserve is expired

		//==========================================
		// csu trigger FirmwareStatusNotificationReq
		//==========================================
		if(isWebsocketSendable && (server_sign == TRUE) && (ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq == ON))
		{
			sendFirmwareStatusNotificationRequest((char *)ShmOCPP20Data->FirmwareStatusNotification.status);
		}

		//==========================================
		// csu cleared charging limit request
		//==========================================
		if(isWebsocketSendable && (server_sign == TRUE) && (ShmOCPP20Data->CSUMsg.bits[gun_index].ClearedChargingLimitReq == ON))
		{
			sendClearedChargingLimitRequest(gun_index);
		}

		//==========================================
		// csu trigger CancelReservationConf
		//==========================================
		if(isWebsocketSendable && (server_sign == TRUE) && (ShmOCPP20Data->CsMsg.bits[gun_index].CancelReservationConf == ON))
		{
			sendCancelReservationConfirmation((char *)ShmOCPP20Data->CancelReservation[gun_index].guid, gun_index);
		}

		//==========================================
		// csu notify EV charging need request
		//==========================================
		if(isWebsocketSendable && (server_sign == TRUE) && (ShmOCPP20Data->CSUMsg.bits[gun_index].NotifyEVChargingNeedsReq == ON))
		{
			sendNotifyEVChargingNeedsRequest(gun_index);
		}

		//==========================================
		// csu trigger ChangeAvailabilityConf
		//==========================================
		if(isWebsocketSendable && (server_sign == TRUE) && (ShmOCPP20Data->CsMsg.bits[gun_index].ChangeAvailabilityConf == ON))
		{
			//sendChangeAvailabilityConfirmation(,(char *)ShmOCPP20Data->ChangeAvailability[gun_index].ResponseStatus);
		}

		//==========================================
		// csu trigger UnlockConnectorConf
		//==========================================
		if(isWebsocketSendable && (server_sign == TRUE) && (ShmOCPP20Data->CsMsg.bits[gun_index].UnlockConnectorConf == ON))
		{
			sendUnlockConnectorConfirmation((char *)ShmOCPP20Data->UnlockConnector[gun_index].guid, gun_index);
		}

		//==========================================
		// csu trigger ReserveNowConf
		//==========================================
		if(isWebsocketSendable && (server_sign == TRUE) && (ShmOCPP20Data->CsMsg.bits[gun_index].ReserveNowConf == ON))
		{
			sendReserveNowConfirmation((char *)ShmOCPP20Data->ReserveNow[gun_index].guid, gun_index);
		}

		//==========================================
		// csu trigger ReserveNowConf
		//==========================================
		if(isWebsocketSendable && (server_sign == TRUE) && (ShmOCPP20Data->CpMsg.bits[gun_index].ReservationStatusUpdateReq == ON))
		{
			sendReservationStatusUpdateRequest(gun_index);
		}

		//==========================================
		// csu trigger LogStatusNotificationReq
		//==========================================
		if(isWebsocketSendable && (server_sign == TRUE) && (ShmOCPP20Data->SpMsg.bits.LogStatusNotificationReq == ON))
		{
			sendLogStatusNotificationRequest((char *)ShmOCPP20Data->LogStatusNotification.status);
		}

		//==========================================
		// csu trigger SignCertificateReq
		//==========================================
		if(isWebsocketSendable && (server_sign == TRUE) && (ShmOCPP20Data->SpMsg.bits.SignCertificateReq == ON))
		{
			if((access("/Storage/OCPP/certCP.csr",F_OK) != -1) &&
			   (strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_SignChargingStationCertificate]) == 0) )
			{
				sendSignCertificateRequest(CertificateSignedStatusEnumType_ChargingStationCertificate);
			}
			else if((access("/Storage/OCPP/certV2G.csr",F_OK) != -1) &&
				  (strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[CertificateSignedStatusEnumType_V2GCertificate]) == 0))
			{
				sendSignCertificateRequest(CertificateSignedStatusEnumType_V2GCertificate);
			}
		}
	}
}

//==========================================
// send request routine
//==========================================
int sendAuthorizeRequest(int gun_index)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	char guid[37];
	char tempdata[128]={0};
	json_object *Authorize = json_object_new_object();
	json_object *idToken = json_object_new_object();

	DEBUG_INFO("sendAuthorizeRequest...\n");
	memset(&(ShmOCPP20Data->Authorize.Response_idTokenInfo),0,sizeof(struct IdTokenInfoType));

	//Local Authorize
	if	((strcmp((const char *)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_OfflineTxForUnknownIdEnabled].variableAttribute[0].value, "TRUE")==0) && (ShmOCPP20Data->OcppConnStatus == 0))
	{
		DEBUG_INFO("Allow OfflineTx UnknownId Pass !!!!\n");
		strcpy((char *)ShmOCPP20Data->Authorize.Response_idTokenInfo.cacheExpiryDateTime, "");
		strcpy((char *)ShmOCPP20Data->Authorize.Response_idTokenInfo.groupIdToken.idToken, "");
		strcpy((char *)ShmOCPP20Data->Authorize.Response_idTokenInfo.status, AuthorizationStatusEnumTypeStr[AuthorizationStatusEnumType_Accepted]);
		result = PASS;
		ShmOCPP20Data->SpMsg.bits.AuthorizeReq = OFF;
		ShmOCPP20Data->SpMsg.bits.AuthorizeConf = ON; // inform csu
		authorizeRetryTimes = 0;
		return result;

	}
	else if(((strcmp((const char *)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalAuthorizeOffline].variableAttribute[0].value, "TRUE") == 0)&&(strcmp((const char *)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Enabled].variableAttribute[0].value, "TRUE") == 0) && (ShmOCPP20Data->OcppConnStatus == 0)) ||
			((strcmp((const char *)ShmOCPP20Data->ControllerComponentVariable[AuthCtrlr_LocalPreAuthorize].variableAttribute[0].value, "TRUE") == 0)&&(strcmp((const char *)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Enabled].variableAttribute[0].value, "TRUE") == 0)))
	{
		// Query idtag from cache
		DB_getIdTag((char *)ShmSysConfigAndInfo->SysConfig.UserId, TRUE);

		// Query idtag from list
		if((strcmp((char*)idTagQuery.idToken.idToken,"") == 0) || (strcmp((char*)idTagQuery.idTokenInfo.status,AuthorizationStatusEnumTypeStr[AuthorizationStatusEnumType_Accepted]) != 0) )
			DB_getIdTag((char *)ShmSysConfigAndInfo->SysConfig.UserId, FALSE);

		if((strcmp((char*)idTagQuery.idToken.idToken,"") == 0) || (strcmp((char*)idTagQuery.idTokenInfo.status,AuthorizationStatusEnumTypeStr[AuthorizationStatusEnumType_Accepted]) != 0) )
		{
			if(strcmp((char*)idTagQuery.idToken.idToken,"") == 0)
			{
				DEBUG_INFO("Card %s does not find in list or cache\n", ShmSysConfigAndInfo->SysConfig.UserId);
			}

			if(strcmp((char*)idTagQuery.idTokenInfo.status,AuthorizationStatusEnumTypeStr[AuthorizationStatusEnumType_Accepted]) != 0)
			{
				DEBUG_INFO("Card %s does not accepted in list and cache\n", ShmSysConfigAndInfo->SysConfig.UserId);
			}

			// Return authorize result if does not connect to server
			if(!ShmOCPP20Data->OcppConnStatus)
			{
				DEBUG_INFO("Local Authorization Fail.\n");
				strcpy((char *)ShmOCPP20Data->Authorize.Response_idTokenInfo.cacheExpiryDateTime, "");
				strcpy((char *)ShmOCPP20Data->Authorize.Response_idTokenInfo.groupIdToken.idToken, (const char *)ShmSysConfigAndInfo->SysConfig.UserId);
				strcpy((char *)ShmOCPP20Data->Authorize.Response_idTokenInfo.status, AuthorizationStatusEnumTypeStr[AuthorizationStatusEnumType_Invalid]);
				DEBUG_INFO("ShmOCPP20Data->Authorize.ResponseIdTagInfo.Status: %s \n", ShmOCPP20Data->Authorize.Response_idTokenInfo.status);
				ShmOCPP20Data->SpMsg.bits.AuthorizeReq = OFF;
				ShmOCPP20Data->SpMsg.bits.AuthorizeConf = ON; // inform csu
				authorizeRetryTimes = 0;
				return result;
			}
		}
		else
		{
			DEBUG_INFO("Local Authorization get result.\n");
			strcpy((char *)ShmOCPP20Data->Authorize.Response_idTokenInfo.cacheExpiryDateTime, (char*)idTagQuery.idTokenInfo.cacheExpiryDateTime);
			strcpy((char *)ShmOCPP20Data->Authorize.Response_idTokenInfo.groupIdToken.idToken, (char *)ShmSysConfigAndInfo->SysConfig.UserId);

			if(isOvertNow((uint8_t*)&idTagQuery.idTokenInfo.cacheExpiryDateTime[0]))
				sprintf((char *)ShmOCPP20Data->Authorize.Response_idTokenInfo.status, AuthorizationStatusEnumTypeStr[AuthorizationStatusEnumType_Expired]);
			else
				strcpy((char *)ShmOCPP20Data->Authorize.Response_idTokenInfo.status, (char*)idTagQuery.idTokenInfo.status);

			DEBUG_INFO("ShmOCPP20Data->Authorize.ResponseIdTagInfo.Status: %s \n", ShmOCPP20Data->Authorize.Response_idTokenInfo.status);
			result = PASS;
			ShmOCPP20Data->SpMsg.bits.AuthorizeReq = OFF;
			ShmOCPP20Data->SpMsg.bits.AuthorizeConf = ON; // inform csu
			authorizeRetryTimes = 0;
			return result;
		}
	}

	//get data from shared memory
	strcpy((char *)ShmOCPP20Data->Authorize.idToken.idToken, (const char *)ShmSysConfigAndInfo->SysConfig.UserId);

	json_object_object_add(idToken, "idToken", json_object_new_string((char*)ShmOCPP20Data->Authorize.idToken.idToken));
	json_object_object_add(idToken, "type", json_object_new_string((char*)ShmOCPP20Data->Authorize.idToken.type));
	json_object_object_add(Authorize, "idToken", idToken);

	random_uuid(guid);
	sprintf(message,"[%d,\"%s\",\"Authorize\",%s]",MESSAGE_TYPE_CALL, guid, json_object_to_json_string_ext(Authorize, JSON_C_TO_STRING_PLAIN));
	json_object_put(Authorize);
	LWS_Send(message);

	sprintf(tempdata, "Authorize,%d", gun_index);
	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;
	}

	ShmOCPP20Data->SpMsg.bits.AuthorizeReq = OFF;
	return result;
}

int sendBootNotificationRequest()
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
    char guid[37]={0};
    char tempdata[128]={0};
    json_object *BootNotification = json_object_new_object();
    json_object *chargingStation = json_object_new_object();
    json_object *modem = json_object_new_object();

    DEBUG_INFO("sendBootNotificationRequest...\n");

    // Fill BootNotification fields
    DB_getBooType();

    sprintf((char *)ShmOCPP20Data->BootNotification.chargingStation.model, "%s", ShmSysConfigAndInfo->SysConfig.ModelName);
    sprintf((char *)ShmOCPP20Data->BootNotification.chargingStation.vendorName, "%s", ShmSysConfigAndInfo->SysConfig.chargePointVendor);

    sprintf((char *)ShmOCPP20Data->BootNotification.chargingStation.serialNumber, "%s", ShmSysConfigAndInfo->SysConfig.SerialNumber);
    sprintf((char *)ShmOCPP20Data->BootNotification.chargingStation.firmwareVersion, "%s", ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev);

    sprintf((char *)ShmOCPP20Data->BootNotification.chargingStation.modem.iccid, "%s", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimIccid);
    sprintf((char *)ShmOCPP20Data->BootNotification.chargingStation.modem.imsi, "%s", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimImsi);

    if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'T') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D'))
    {
    	json_object_object_add(modem, "iccid", json_object_new_string((char*)ShmOCPP20Data->BootNotification.chargingStation.modem.iccid));
		json_object_object_add(modem, "imsi", json_object_new_string((char*)ShmOCPP20Data->BootNotification.chargingStation.modem.imsi));
		json_object_object_add(chargingStation, "modem", modem);
    }

    json_object_object_add(chargingStation, "model", json_object_new_string((char*)ShmOCPP20Data->BootNotification.chargingStation.model));
    json_object_object_add(chargingStation, "vendorName", json_object_new_string((char*)ShmOCPP20Data->BootNotification.chargingStation.vendorName));
    json_object_object_add(chargingStation, "serialNumber", json_object_new_string((char*)ShmOCPP20Data->BootNotification.chargingStation.serialNumber));
    json_object_object_add(chargingStation, "firmwareVersion", json_object_new_string((char*)ShmOCPP20Data->BootNotification.chargingStation.firmwareVersion));

    json_object_object_add(BootNotification, "chargingStation", chargingStation);
    json_object_object_add(BootNotification, "reason", json_object_new_string((char*)ShmOCPP20Data->BootNotification.reason));

	random_uuid(guid);
	sprintf(message,"[%d,\"%s\",\"%s\",%s]",MESSAGE_TYPE_CALL, guid, "BootNotification", json_object_to_json_string_ext(BootNotification, JSON_C_TO_STRING_PLAIN));
	json_object_put(BootNotification);
	LWS_Send(message);

	sprintf(tempdata, "BootNotification,0");
	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;
	}

	return result;
}

int sendClearedChargingLimitRequest(int gun_index)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	char guid[37]={0};
	char tempdata[128]={0};
	json_object *ClearedChargingLimit = json_object_new_object();

	DEBUG_INFO("sendClearedChargingLimitRequest...\n");

	json_object_object_add(ClearedChargingLimit, "chargingLimitSource", json_object_new_string((char*)ShmOCPP20Data->ClearedChargingLimit[gun_index].chargingLimitSource));
	json_object_object_add(ClearedChargingLimit, "evseId", json_object_new_int(ShmOCPP20Data->ClearedChargingLimit[gun_index].evseId));

	random_uuid(guid);
	sprintf(message,"[%d,\"%s\",\"%s\",%s]",MESSAGE_TYPE_CALL, guid, "ClearedChargingLimit", json_object_to_json_string_ext(ClearedChargingLimit, JSON_C_TO_STRING_PLAIN));
	json_object_put(ClearedChargingLimit);
	LWS_Send(message);

	sprintf(tempdata, "ClearedChargingLimit,%d", gun_index);
	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;
	}

	ShmOCPP20Data->CSUMsg.bits[gun_index].ClearedChargingLimitReq = OFF;

	return result;
}

int sendDataTransferRequest(int gun_index)
{
	mtrace();
	char message[1000]={0};
	char guid[37]={0};
	char tempdata[65]={0};
	int result = FAIL;

	DEBUG_INFO("sendDataTransferRequest...\n");

	random_uuid(guid);
	sprintf(message,"[%d,\"%s\",\"DataTransfer\",{\"vendorId\":\"%s\",\"messageId\":\"%s\",\"data\":\"%s\"}]",
			MESSAGE_TYPE_CALL,
			guid,
			ShmOCPP20Data->DataTransfer[gun_index].vendorId,
			ShmOCPP20Data->DataTransfer[gun_index].messageId,
			ShmOCPP20Data->DataTransfer[gun_index].data);

	LWS_Send(message);

	sprintf(tempdata, "DataTransfer,%d", (gun_index + 1));
	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;
	}

	return result;
}

int sendFirmwareStatusNotificationRequest(char *status)
{
	mtrace();
	int result = FAIL;
	char message[110]={0};
	char guid[37]={0};
	char tempdata[65]={0};
	json_object *FirmwareStatusNotification = json_object_new_object();
	DEBUG_INFO("sendFirmwareStatusNotificationRequest...\n");

	sprintf((char *)ShmOCPP20Data->FirmwareStatusNotification.status, "%s", (const char *)status);
	ShmOCPP20Data->FirmwareStatusNotification.requestId = ShmOCPP20Data->UpdateFirmware.requestId;

	json_object_object_add(FirmwareStatusNotification, "status", json_object_new_string((char*)ShmOCPP20Data->FirmwareStatusNotification.status));
	json_object_object_add(FirmwareStatusNotification, "requestId", json_object_new_int(ShmOCPP20Data->FirmwareStatusNotification.requestId));

	random_uuid(guid);
	sprintf(message,"[%d,\"%s\",\"FirmwareStatusNotification\",%s]",MESSAGE_TYPE_CALL, guid, json_object_to_json_string_ext(FirmwareStatusNotification, JSON_C_TO_STRING_PLAIN));
	json_object_put(FirmwareStatusNotification);
	LWS_SendNow(message);

	sprintf(tempdata, "FirmwareStatusNotification,%d", 0);

	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;
	}

	ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = OFF;
	ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationConf = OFF;

	//record status
	if(strcmp(status,FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Downloaded])==0)
	{
		 FirmwareStatusNotificationStatus = FirmwareStatusEnumType_Downloaded;
	}
	else if(strcmp(status,FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_DownloadFailed])==0)
	{
		FirmwareStatusNotificationStatus = FirmwareStatusEnumType_DownloadFailed;
	}
	else if(strcmp(status,FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Downloading])==0)
	{
		FirmwareStatusNotificationStatus = FirmwareStatusEnumType_Downloading;
	}
	else if(strcmp(status,FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_DownloadScheduled])==0)
	{
		FirmwareStatusNotificationStatus = FirmwareStatusEnumType_DownloadScheduled;
	}
	else if(strcmp(status,FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_DownloadPaused])==0)
	{
		FirmwareStatusNotificationStatus = FirmwareStatusEnumType_DownloadPaused;
	}
	else if(strcmp(status,FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Idle])==0)
	{
		FirmwareStatusNotificationStatus = FirmwareStatusEnumType_Idle;
	}
	else if(strcmp(status,FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_InstallationFailed])==0)
	{
		FirmwareStatusNotificationStatus = FirmwareStatusEnumType_InstallationFailed;
		DB_updateBootType(BootReasonEnumType_FirmwareUpdate);
	}
	else if(strcmp(status,FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Installing])==0)
	{
		FirmwareStatusNotificationStatus = FirmwareStatusEnumType_Installing;
	}
	else if(strcmp(status,FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Installed])==0)
	{
		FirmwareStatusNotificationStatus = FirmwareStatusEnumType_Installed;
		DB_updateBootType(BootReasonEnumType_FirmwareUpdate);
		DB_updateSecurityEventType(SecurityEventEnumType_FirmwareUpdated);
	}
	else if(strcmp(status,FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_InstallRebooting])==0)
	{
		FirmwareStatusNotificationStatus = FirmwareStatusEnumType_InstallRebooting;
		DB_updateBootType(BootReasonEnumType_FirmwareUpdate);
		DB_updateSecurityEventType(SecurityEventEnumType_FirmwareUpdated);
	}
	else if(strcmp(status,FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_InstallScheduled])==0)
	{
		FirmwareStatusNotificationStatus = FirmwareStatusEnumType_InstallScheduled;
	}
	else if(strcmp(status,FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_InstallVerificationFailed])==0)
	{
		FirmwareStatusNotificationStatus = FirmwareStatusEnumType_InstallVerificationFailed;
	}
	else if(strcmp(status,FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_InvalidSignature])==0)
	{
		FirmwareStatusNotificationStatus = FirmwareStatusEnumType_InvalidSignature;
	}
	else if(strcmp(status,FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_SignatureVerified])==0)
	{
		FirmwareStatusNotificationStatus = FirmwareStatusEnumType_SignatureVerified;
	}

	return result;
}

int sendGet15118EVCertificateRequest()
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	char guid[37]={0};
	char tempdata[128]={0};
	json_object *Get15118EVCertificate = json_object_new_object();

	DEBUG_INFO("sendGet15118EVCertificateRequest...\n");

	json_object_object_add(Get15118EVCertificate, "iso15118SchemaVersion", json_object_new_string((char*)ShmOCPP20Data->Get15118EVCertificate.iso15118SchemaVersion));
	json_object_object_add(Get15118EVCertificate, "action", json_object_new_string((char*)ShmOCPP20Data->Get15118EVCertificate.action));
	json_object_object_add(Get15118EVCertificate, "exiRequest", json_object_new_string((char*)ShmOCPP20Data->Get15118EVCertificate.exiRequest));

	random_uuid(guid);
	sprintf(message,"[%d,\"%s\",\"%s\",%s]",MESSAGE_TYPE_CALL, guid, "Get15118EVCertificate", json_object_to_json_string_ext(Get15118EVCertificate, JSON_C_TO_STRING_PLAIN));
	json_object_put(Get15118EVCertificate);
	LWS_Send(message);

	sprintf(tempdata, "Get15118EVCertificate,0");
	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;
	}

	return result;
}

int sendGetCertificateStatusRequest()
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	char guid[37]={0};
	char tempdata[128]={0};
	json_object *GetCertificateStatus = json_object_new_object();
	json_object *ocspRequestData = json_object_new_object();
	DEBUG_INFO("sendGetCertificateStatusRequest...\n");

	json_object_object_add(ocspRequestData, "hashAlgorithm", json_object_new_string((char*)ShmOCPP20Data->GetCertificateStatus.ocspRequestData.hashAlgorithm));
	json_object_object_add(ocspRequestData, "issuerNameHash", json_object_new_string((char*)ShmOCPP20Data->GetCertificateStatus.ocspRequestData.issuerNameHash));
	json_object_object_add(ocspRequestData, "issuerKeyHash", json_object_new_string((char*)ShmOCPP20Data->GetCertificateStatus.ocspRequestData.issuerKeyHash));
	json_object_object_add(ocspRequestData, "serialNumber", json_object_new_string((char*)ShmOCPP20Data->GetCertificateStatus.ocspRequestData.serialNumber));
	json_object_object_add(ocspRequestData, "responderURL", json_object_new_string((char*)ShmOCPP20Data->GetCertificateStatus.ocspRequestData.responderURL));
	json_object_object_add(GetCertificateStatus, "ocspRequestData", ocspRequestData);

	random_uuid(guid);
	sprintf(message,"[%d,\"%s\",\"%s\",%s]",MESSAGE_TYPE_CALL, guid, "GetCertificateStatus", json_object_to_json_string_ext(GetCertificateStatus, JSON_C_TO_STRING_PLAIN));
	json_object_put(GetCertificateStatus);
	LWS_Send(message);

	sprintf(tempdata, "GetCertificateStatus,0");
	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;
	}
	return result;
}

int sendHeartbeatRequest()
{
	mtrace();
	int result = FAIL;

	char message[40096]={0};
	char guid[37]={0};
	char tempdata[128]={0};
	DEBUG_INFO("sendHeartbeatRequest...\n");

	random_uuid(guid);

	sprintf(message, "[%d,\"%s\",\"Heartbeat\",{ }]"
					, MESSAGE_TYPE_CALL
					, guid );

	LWS_Send(message);

	sprintf(tempdata, "Heartbeat,%d", 0);

	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;
	}

	return result;
}

int sendLogStatusNotificationRequest(char *status)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	char guid[37]={0};
	char tempdata[128]={0};
	json_object *LogStatusNotification = json_object_new_object();

	DEBUG_INFO("sendLogStatusNotificationRequest...\n");
	ShmOCPP20Data->LogStatusNotification.requestId = ShmOCPP20Data->GetLog.requestId;
	sprintf((char *)ShmOCPP20Data->LogStatusNotification.status,"%s",(const char *)status);

	json_object_object_add(LogStatusNotification, "status", json_object_new_string((char*)ShmOCPP20Data->LogStatusNotification.status));
	json_object_object_add(LogStatusNotification, "requestId", json_object_new_int(ShmOCPP20Data->LogStatusNotification.requestId));

	random_uuid(guid);
	sprintf(message,"[%d,\"%s\",\"LogStatusNotification\",%s]",MESSAGE_TYPE_CALL, guid, json_object_to_json_string_ext(LogStatusNotification, JSON_C_TO_STRING_PLAIN));
	json_object_put(LogStatusNotification);
	LWS_SendNow(message);

	sprintf(tempdata, "LogStatusNotification,%d", 0);

	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;
	}

	ShmOCPP20Data->SpMsg.bits.LogStatusNotificationReq = OFF;
	ShmOCPP20Data->SpMsg.bits.LogStatusNotificationConf = OFF;

	//record status
	if(strcmp(status,"BadMessage")==0)
	{
		LogStatusNotificationStatus = UploadLogStatusEnumType_BadMessage;
	}
	else if(strcmp(status,"Idle")==0)
	{
		LogStatusNotificationStatus = UploadLogStatusEnumType_Idle;
	}
	else if(strcmp(status,"NotSupportedOperation")==0)
	{
		LogStatusNotificationStatus = UploadLogStatusEnumType_NotSupportedOperation;
	}
	else if(strcmp(status,"PermissionDenied")==0)
	{
		LogStatusNotificationStatus = UploadLogStatusEnumType_PermissionDenied;
	}
	else if(strcmp(status,"Uploaded")==0)
	{
		LogStatusNotificationStatus = UploadLogStatusEnumType_Uploaded;
	}
	else if(strcmp(status,"UploadFailure")==0)
	{
		LogStatusNotificationStatus = UploadLogStatusEnumType_UploadFailure;
	}
	else if(strcmp(status,"Uploading")==0)
	{
		LogStatusNotificationStatus = UploadLogStatusEnumType_Uploading;
	}

	return result;
}

int sendMeterValuesRequest(int gun_index, ReadingContextEnumType dataType)
{
	mtrace();
	int result = FAIL;
	char guid[37]={0};
	char tempdata[65]={0};
	int tempIndex = 0;
	json_object *MeterValueReq = json_object_new_object();
	json_object *meterValues = json_object_new_array();
	json_object *sampledValues = json_object_new_array();
	DEBUG_INFO("sendMeterValuesRequest...\n");

	memset(queuedata, 0, ARRAY_SIZE(queuedata));
	memset(&ShmOCPP20Data->MeterValues[gun_index], 0, sizeof(struct MeterValues_20));
	//set value
	ShmOCPP20Data->MeterValues[gun_index].evseId = gun_index + 1; // gun start from 1~

	//UTC Date time
	struct timeval tmnow;
	struct tm *tm;
	char buf[28];//, usec_buf[6];
	gettimeofday(&tmnow, NULL);

	time_t t;
	t = time(NULL);
	/*UTC time and date*/
	tm = gmtime(&t);

	if(dataType == ReadingContextEnumType_Sample_Clock)
	{
		struct tm *tmTarget;
		struct timeb tbTarget;
		tbTarget.time = mktime(tm);
		tbTarget.time -= (atoi((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Interval].variableAttribute[0].value));
		tmTarget = gmtime(&tbTarget.time);
		strftime(buf,28,"%Y-%m-%dT%H:%M:%SZ", tmTarget);
	}
	else
	{
		strftime(buf,28,"%Y-%m-%dT%H:%M:%SZ", tm);
	}
	strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].timestamp, buf);

	//DEBUG_INFO("ShmSysConfigAndInfo->SysConfig.ModelName[0]=%c\n", ShmSysConfigAndInfo->SysConfig.ModelName[0]);

	//idx_sample=0;
	//********************************(1)Current.Import L1************************************************/
	if(((dataType == ReadingContextEnumType_Sample_Clock) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_Current_Import]) != NULL)) ||
	   ((dataType == ReadingContextEnumType_Sample_Periodic) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_Current_Import]) != NULL)) ||
	   (dataType == ReadingContextEnumType_Trigger))
	{
		//J: CHAdeMO  U: CCS1 combo  E: CCS2 combo  G: GBT DC
		if(gunType[gun_index] == GUN_TYPE_CHAdeMO)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = ((gun_index==2) ? 1: 0);
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < CHAdeMO_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex)
				{
					ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[0].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PresentChargingCurrent*100))/100.0;
				}
			}

			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[0].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
		}
		else if(gunType[gun_index] == GUN_TYPE_CCS)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = ((gun_index==2) ? 1: 0);
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < CCS_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
				{
					ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[0].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PresentChargingCurrent*100))/100.0;
				}
			}

			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[0].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
		}
		else if(gunType[gun_index] == GUN_TYPE_GBT)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = ((gun_index==2) ? 1: 0);
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < GB_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex)
				{
					ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[0].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PresentChargingCurrent*100))/100.0;
				}
			}

			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[0].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
		}
		else if(gunType[gun_index] == GUN_TYPE_DO)
		{
			tempIndex = gun_index;

			for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
				{
					ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[0].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PresentChargingCurrent*100))/100.0;
				}
			}

			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[0].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
		}
		else
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
			{
				tempIndex = 2;
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < AC_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
				{
					ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[0].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PresentChargingCurrent*100))/100.0;
				}
			}

			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[0].phase, PhaseEnumTypeStr[PhaseEnumType_L1_N]);
		}

		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[0].context, ReadingContextEnumTypeStr[dataType]);
		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[0].measurand, MeasurandEnumTypeStr[MeasurandEnumType_Current_Import]);
		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[0].location, LocationEnumTypeStr[LocationEnumType_Outlet]);
		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[0].unitOfMeasure.uint , "A");
		ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[0].unitOfMeasure.multiplier = 0;
	}

	//idx_sample=1;
	//********************************(2)Energy.Active.Import.Register ************************************************/
	if(((dataType == ReadingContextEnumType_Sample_Clock) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_Energy_Active_Import_Register]) != NULL)) ||
	   ((dataType == ReadingContextEnumType_Sample_Periodic) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_Energy_Active_Import_Register]) != NULL)) ||
	   (dataType == ReadingContextEnumType_Trigger))
	{
		//J: CHAdeMO  U: CCS1 combo  E: CCS2 combo  G: GBT DC
		if(gunType[gun_index] == GUN_TYPE_CHAdeMO)
		{
				if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
				{
					tempIndex = ((gun_index==2) ? 1: 0);
				}
				else
				{
					tempIndex = gun_index;
				}

				for (int index = 0; index < CHAdeMO_QUANTITY; index++)
				{
					if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex)
					{
						ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[1].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PowerConsumption*100))/100.0;
					}
				}

				strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[1].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
		}
		else if(gunType[gun_index] == GUN_TYPE_CCS)
		{
				if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
				{
					tempIndex = ((gun_index==2) ? 1: 0);
				}
				else
				{
					tempIndex = gun_index;
				}

				for (int index = 0; index < CCS_QUANTITY; index++)
				{
					if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
					{
						ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[1].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PowerConsumption*100))/100.0;
					}
				}

				strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[1].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
		}
		else if(gunType[gun_index] == GUN_TYPE_GBT)
		{
				if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
				{
					tempIndex = ((gun_index==2) ? 1: 0);
				}
				else
				{
					tempIndex = gun_index;
				}

				for (int index = 0; index < GB_QUANTITY; index++)
				{
					if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex)
					{
						ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[1].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PowerConsumption*100))/100.0;
					}
				}

				strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[1].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
		}
		else if(gunType[gun_index] == GUN_TYPE_DO)
		{

				tempIndex = gun_index;

				for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
				{
					if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
					{
						ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[1].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PowerConsumption*100))/100.0;
					}
				}

				strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[1].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
		}
		else
		{
				if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
				{
					tempIndex = 2;
				}
				else
				{
					tempIndex = gun_index;
				}

				for (int index = 0; index < AC_QUANTITY; index++)
				{
					if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
					{
						ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[1].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PowerConsumption*100))/100.0;
					}
				}

				strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[1].phase, PhaseEnumTypeStr[PhaseEnumType_L1_N]);
		}

		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[1].context, ReadingContextEnumTypeStr[dataType]);
		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[1].measurand, MeasurandEnumTypeStr[MeasurandEnumType_Energy_Active_Import_Register]);
		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[1].location, LocationEnumTypeStr[LocationEnumType_Outlet]);
		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[1].unitOfMeasure.uint , "kWh");
		ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[2].unitOfMeasure.multiplier = 0;
	}

	//idx_sample=2;
	//****************************************************(3)Energy.Active.Import.Interval*********************************************/
	if(((dataType == ReadingContextEnumType_Sample_Clock) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_Energy_Active_Import_Interval]) != NULL)) ||
	   ((dataType == ReadingContextEnumType_Sample_Periodic) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_Energy_Active_Import_Interval]) != NULL)) ||
	   (dataType == ReadingContextEnumType_Trigger))
	{
		//J: CHAdeMO  U: CCS1 combo  E: CCS2 combo  G: GBT DC
		if(gunType[gun_index] == GUN_TYPE_CHAdeMO)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = ((gun_index==2) ? 1: 0);
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < CHAdeMO_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex)
				{
					ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[2].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PresentChargedEnergy*100))/100.0;
				}
			} // END OF FOR CHAdeMO_QUANTITY

			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[2].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
		}
		else if(gunType[gun_index] == GUN_TYPE_CCS)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = ((gun_index==2) ? 1: 0);
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < CCS_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
				{
					ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[2].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PresentChargedEnergy*100))/100.0;
				}
			} // END OF CCS_QUANTITY

			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[2].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
		}
		else if(gunType[gun_index] == GUN_TYPE_GBT)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = ((gun_index==2) ? 1: 0);
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < GB_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex)
				{
					ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[2].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PresentChargedEnergy*100))/100.0;
				}
			} // END OF GB_QUANTITY

			 strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[2].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
		}
		else if(gunType[gun_index] == GUN_TYPE_DO)
		{
			tempIndex = gun_index;

			for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
				{
					ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[2].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PresentChargedEnergy*100))/100.0;
				}
			}

			 strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[2].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
		}
		else
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
			{
				tempIndex = 2;
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < AC_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
				{
					ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[2].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PresentChargedEnergy*100))/100.0;
				}
			 }

			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[2].phase, PhaseEnumTypeStr[PhaseEnumType_L1_N]);
		}

		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[2].context, ReadingContextEnumTypeStr[dataType]);
		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[2].measurand, MeasurandEnumTypeStr[MeasurandEnumType_Energy_Active_Import_Interval]);
		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[2].location, LocationEnumTypeStr[LocationEnumType_Outlet]);
		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[2].unitOfMeasure.uint , "kWh");
		ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[2].unitOfMeasure.multiplier = 0;
	}

	//idx_sample=3;
	//********************************(4)Power.Active.Import************************************************/
	if(((dataType == ReadingContextEnumType_Sample_Clock) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_Power_Active_Import]) != NULL)) ||
	   ((dataType == ReadingContextEnumType_Sample_Periodic) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_Power_Active_Import]) != NULL)) ||
	   (dataType == ReadingContextEnumType_Trigger))
	{
		//J : CHAdeMO   U: CCS1 combo   E: CCS2 combo   G: GBT DC
		if(gunType[gun_index] == GUN_TYPE_CHAdeMO)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = ((gun_index==2) ? 1: 0);
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < CHAdeMO_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex)
				{
					ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[3].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PresentChargingPower*100))/100.0;
				}
			} // END OF FOR

			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[3].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
		}
		else if(gunType[gun_index] == GUN_TYPE_CCS)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = ((gun_index==2) ? 1: 0);
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < CCS_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
				{
					ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[3].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PresentChargingPower*100))/100.0;
				}
			}

			 strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[3].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
		}
		else if(gunType[gun_index] == GUN_TYPE_GBT)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = ((gun_index==2) ? 1: 0);
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < GB_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex)
				{
				     //ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PresentChargingPower = 100.0;
				    ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[3].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PresentChargingPower*100))/100.0;
				}
			}

			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[3].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
		}
		else if(gunType[gun_index] == GUN_TYPE_DO)
		{
			tempIndex = gun_index;

			for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
				{
				     //ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PresentChargingPower = 100.0;
				    ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[3].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PresentChargingPower*100))/100.0;
				}
			}

			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[3].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
		}
		else
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
			{
				tempIndex = 2;
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < AC_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
				{
				    ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[3].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PresentChargingPower*100))/100.0;
				}
			}

			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[3].phase, PhaseEnumTypeStr[PhaseEnumType_L1_N]);
		}

		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[3].context, ReadingContextEnumTypeStr[dataType]);
		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[3].measurand, MeasurandEnumTypeStr[MeasurandEnumType_Power_Active_Import]);
		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[3].location, LocationEnumTypeStr[LocationEnumType_Outlet]);
		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[3].unitOfMeasure.uint , "kW");
		ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[3].unitOfMeasure.multiplier = 0;
	}

	//idx_sample=4;
	//***********************************************(5)VOLTAGE L1******************************************************/
	if(((dataType == ReadingContextEnumType_Sample_Clock) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_Voltage]) != NULL)) ||
	   ((dataType == ReadingContextEnumType_Sample_Periodic) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_Voltage]) != NULL)) ||
	   (dataType == ReadingContextEnumType_Trigger))
	{
		//J : CHAdeMO   U: CCS1 combo   E: CCS2 combo   G: GBT DC
		if(gunType[gun_index] == GUN_TYPE_CHAdeMO)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = ((gun_index==2) ? 1: 0);
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < CHAdeMO_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex)
				{
				 	ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[4].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PresentChargingVoltage*100))/100.0;
				}
			}

			 strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[4].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
		}
		else if(gunType[gun_index] == GUN_TYPE_CCS)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = ((gun_index==2) ? 1: 0);
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < CCS_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
				{
				 	ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[4].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PresentChargingVoltage*100))/100.0;
				}
			}

			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[4].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
		}
		else if(gunType[gun_index] == GUN_TYPE_GBT)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = ((gun_index==2) ? 1: 0);
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < GB_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex)
				{
				 	ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[4].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PresentChargingVoltage*100))/100.0;
				}
			}

			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[4].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
		}
		else if(gunType[gun_index] == GUN_TYPE_DO)
		{
			tempIndex = gun_index;

			for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
				{
				 	ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[4].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PresentChargingVoltage*100))/100.0;
				}
			}

			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[4].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
		}
		else
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
			{
				tempIndex = 2;
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < AC_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
				{
					ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[4].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PresentChargingVoltage*100))/100.0;
				}
			}

			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[4].phase, PhaseEnumTypeStr[PhaseEnumType_L1_N]);
		}

		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[4].context, ReadingContextEnumTypeStr[dataType]);
		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[4].measurand, MeasurandEnumTypeStr[MeasurandEnumType_Voltage]);
		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[4].location, LocationEnumTypeStr[LocationEnumType_Outlet]);
		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[4].unitOfMeasure.uint , "V");
		ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[4].unitOfMeasure.multiplier = 0;
	}

	//***********************************************(6)SOC******************************************************/
	if(((dataType == ReadingContextEnumType_Sample_Clock) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_SoC]) != NULL)) ||
	   ((dataType == ReadingContextEnumType_Sample_Periodic) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_SoC]) != NULL)) ||
	   (dataType == ReadingContextEnumType_Trigger))
	{
		if((gunType[gun_index] == GUN_TYPE_CHAdeMO)||(gunType[gun_index] == GUN_TYPE_CCS)||(gunType[gun_index] == GUN_TYPE_GBT)||(gunType[gun_index] == GUN_TYPE_DO))
		{
			if((ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0') && (gunType[gun_index] != GUN_TYPE_DO))
			{
				tempIndex = ((gun_index==2) ? 1: 0);
			}
			else
			{
				tempIndex = gun_index;
			}

			if(gunType[gun_index] == GUN_TYPE_CHAdeMO)
			{
				//tempIndex = ((gun_index==2) ? 1: 0);

				for (int index = 0; index < CHAdeMO_QUANTITY; index++)
				{
					if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex)
					{
						ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[5].value = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].EvBatterySoc;
					}
				}
			}
			else if(gunType[gun_index] == GUN_TYPE_CCS)
			{
				//tempIndex = ((gun_index==2) ? 1: 0);

				for (int index = 0; index < CCS_QUANTITY; index++)
				{
					if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
					{
						ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[5].value = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].EvBatterySoc;
					}
				}

			}
			else if(gunType[gun_index] == GUN_TYPE_GBT)
			{
				//tempIndex = ((gun_index==2) ? 1: 0);

				for (int index = 0; index < GB_QUANTITY; index++)
				{
					if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex)
					{
						 ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[5].value = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].EvBatterySoc;
					}
				}

			}
			else if(gunType[gun_index] == GUN_TYPE_DO)
			{
				//tempIndex = ((gun_index==2) ? 1: 0);

				for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
				{
					if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
					{
						 ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[5].value = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.EvBatterySoc;
					}
				}

			}

			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[5].context, ReadingContextEnumTypeStr[dataType]);
			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[5].measurand, MeasurandEnumTypeStr[MeasurandEnumType_SoC]);
			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[5].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[5].location, LocationEnumTypeStr[LocationEnumType_EV]);
			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[5].unitOfMeasure.uint , "Percent");
			ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[5].unitOfMeasure.multiplier = 0;
		}
	}

	//********************************(7)Current.Import L2************************************************/
	if(((dataType == ReadingContextEnumType_Sample_Clock) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_Current_Import]) != NULL)) ||
	   ((dataType == ReadingContextEnumType_Sample_Periodic) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_Current_Import]) != NULL)) ||
	   (dataType == ReadingContextEnumType_Trigger))
	{
		// Only for AC 3 phase
		if((gunType[gun_index] == GUN_TYPE_AC) && ((ShmSysConfigAndInfo->SysConfig.ModelName[2] == 'Y') || (ShmSysConfigAndInfo->SysConfig.ModelName[2] == 'W') || (ShmSysConfigAndInfo->SysConfig.ModelName[2] == 'D')))
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
			{
				tempIndex = 2;
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < AC_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
				{
					ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[6].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PresentChargingCurrentL2*100))/100.0;
				}
			}
			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[6].phase, PhaseEnumTypeStr[PhaseEnumType_L2_N]);
			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[6].context, ReadingContextEnumTypeStr[dataType]);
			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[6].measurand, MeasurandEnumTypeStr[MeasurandEnumType_Current_Import]);
			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[6].location, LocationEnumTypeStr[LocationEnumType_Outlet]);
			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[6].unitOfMeasure.uint , "A");
			ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[6].unitOfMeasure.multiplier = 0;
		}
	}

	//********************************(8)Current.Import L3************************************************/
	if(((dataType == ReadingContextEnumType_Sample_Clock) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_Current_Import]) != NULL)) ||
	   ((dataType == ReadingContextEnumType_Sample_Periodic) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_Current_Import]) != NULL)) ||
	   (dataType == ReadingContextEnumType_Trigger))
	{
		// Only for AC 3 phase
		if( (gunType[gun_index] == GUN_TYPE_AC) && ((ShmSysConfigAndInfo->SysConfig.ModelName[2] == 'Y') || (ShmSysConfigAndInfo->SysConfig.ModelName[2] == 'W') || (ShmSysConfigAndInfo->SysConfig.ModelName[2] == 'D')))
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
			{
				tempIndex = 2;
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < AC_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
				{
					ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[7].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PresentChargingCurrentL3*100))/100.0;
				}
			}
			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[7].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[7].context, ReadingContextEnumTypeStr[dataType]);
			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[7].measurand, MeasurandEnumTypeStr[MeasurandEnumType_Current_Import]);
			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[7].location, LocationEnumTypeStr[LocationEnumType_Outlet]);
			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[7].unitOfMeasure.uint , "A");
			ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[7].unitOfMeasure.multiplier = 0;
		}
	}


	//***********************************************(9)VOLTAGE L2******************************************************/
	if(((dataType == ReadingContextEnumType_Sample_Clock) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_Voltage]) != NULL)) ||
	   ((dataType == ReadingContextEnumType_Sample_Periodic) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_Voltage]) != NULL)) ||
	   (dataType == ReadingContextEnumType_Trigger))
	{
		if( (gunType[gun_index] == GUN_TYPE_AC) && ((ShmSysConfigAndInfo->SysConfig.ModelName[2] == 'Y') || (ShmSysConfigAndInfo->SysConfig.ModelName[2] == 'W') || (ShmSysConfigAndInfo->SysConfig.ModelName[2] == 'D')))
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
			{
				tempIndex = 2;
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < AC_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
				{
					ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[8].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PresentChargingVoltageL2*100))/100.0;
				}
			}

			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[8].phase, PhaseEnumTypeStr[PhaseEnumType_L2_N]);
			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[8].context, ReadingContextEnumTypeStr[dataType]);
			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[8].measurand, MeasurandEnumTypeStr[MeasurandEnumType_Voltage]);
			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[8].location, LocationEnumTypeStr[LocationEnumType_Outlet]);
			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[8].unitOfMeasure.uint , "V");
			ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[8].unitOfMeasure.multiplier = 0;
		}
	}

	//***********************************************(10)VOLTAGE L3******************************************************/
	if(((dataType == ReadingContextEnumType_Sample_Clock) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_Voltage]) != NULL)) ||
	   ((dataType == ReadingContextEnumType_Sample_Periodic) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_Voltage]) != NULL)) ||
	   (dataType == ReadingContextEnumType_Trigger))
	{
		if((gunType[gun_index] == GUN_TYPE_AC) && ((ShmSysConfigAndInfo->SysConfig.ModelName[2] == 'Y') || (ShmSysConfigAndInfo->SysConfig.ModelName[2] == 'W') || (ShmSysConfigAndInfo->SysConfig.ModelName[2] == 'D')))
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
			{
				tempIndex = 2;
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < AC_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
				{
					ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[9].value = ((uint32_t)(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PresentChargingVoltageL3*100))/100.0;
				}
			}

			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[9].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[9].context, ReadingContextEnumTypeStr[dataType]);
			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[9].measurand, MeasurandEnumTypeStr[MeasurandEnumType_Voltage]);
			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[9].location, LocationEnumTypeStr[LocationEnumType_Outlet]);
			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[9].unitOfMeasure.uint , "V");
			ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[9].unitOfMeasure.multiplier = 0;
		}
	}

	//***********************************************(11)Current.Offered******************************************************/
	if(((dataType == ReadingContextEnumType_Sample_Clock) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_Current_Offered]) != NULL)) ||
	   ((dataType == ReadingContextEnumType_Sample_Periodic) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_Current_Offered]) != NULL)) ||
	   (dataType == ReadingContextEnumType_Trigger))
	{
		//J : CHAdeMO   U: CCS1 combo   E: CCS2 combo   G: GBT DC
		if(gunType[gun_index] == GUN_TYPE_CHAdeMO)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = ((gun_index==2) ? 1: 0);
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < CHAdeMO_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex)
				{
					ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[10].value = (uint16_t) (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].AvailableChargingCurrent/10);
				}
			} // END OF FOR
		}
		else if(gunType[gun_index] == GUN_TYPE_CCS)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = ((gun_index==2) ? 1: 0);
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < CCS_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
				{
					ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[10].value = (uint16_t) (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].AvailableChargingCurrent/10);
				}
			}
		}
		else if(gunType[gun_index] == GUN_TYPE_GBT)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = ((gun_index==2) ? 1: 0);
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < GB_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex)
				{
				     //ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PresentChargingPower = 100.0;
				    ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[10].value = (uint16_t) (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].AvailableChargingCurrent/10);;
				}
			}
		}
		else if(gunType[gun_index] == GUN_TYPE_DO)
		{
			tempIndex = gun_index;

			for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
				{
				     //ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PresentChargingPower = 100.0;
				    ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[10].value = (uint16_t) (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.AvailableChargingCurrent/10);;
				}
			}
		}
		else
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
			{
				tempIndex = 2;
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < AC_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
				{
				    uint16_t currentOffer;
					if(ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent == 0)
					{
						currentOffer = ShmSysConfigAndInfo->SysConfig.RatingCurrent;
					}
					else
					{
						currentOffer = ((ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent>ShmSysConfigAndInfo->SysConfig.RatingCurrent)?ShmSysConfigAndInfo->SysConfig.RatingCurrent:ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent);
					}
					ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[10].value = currentOffer;
				}
			}
		}

		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[10].context, ReadingContextEnumTypeStr[dataType]);
		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[10].measurand, MeasurandEnumTypeStr[MeasurandEnumType_Current_Offered]);
		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[10].location, LocationEnumTypeStr[LocationEnumType_Outlet]);
		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[10].unitOfMeasure.uint , "A");
		ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[10].unitOfMeasure.multiplier = 0;
	}

	//***********************************************(12)Power.Offered******************************************************/
	if(((dataType == ReadingContextEnumType_Sample_Clock) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_Power_Offered]) != NULL)) ||
	   ((dataType == ReadingContextEnumType_Sample_Periodic) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].value, MeasurandEnumTypeStr[MeasurandEnumType_Power_Offered]) != NULL)) ||
	   (dataType == ReadingContextEnumType_Trigger))
	{
		//J : CHAdeMO   U: CCS1 combo   E: CCS2 combo   G: GBT DC
		if(gunType[gun_index] == GUN_TYPE_CHAdeMO)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = ((gun_index==2) ? 1: 0);
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < CHAdeMO_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex)
				{
					ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[11].value = (uint16_t) (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].AvailableChargingPower*100);
				}
			} // END OF FOR
		}
		else if(gunType[gun_index] == GUN_TYPE_CCS)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = ((gun_index==2) ? 1: 0);
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < CCS_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
				{
					ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[11].value = (uint16_t) (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].AvailableChargingPower*100);
				}
			}
		}
		else if(gunType[gun_index] == GUN_TYPE_GBT)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = ((gun_index==2) ? 1: 0);
			}
			else
			{
				tempIndex = gun_index;
			}

			for (int index = 0; index < GB_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex)
				{
				     //ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PresentChargingPower = 100.0;
				    ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[11].value = (uint16_t) (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].AvailableChargingPower*100);
				}
			}
		}
		else if(gunType[gun_index] == GUN_TYPE_DO)
		{
			tempIndex = gun_index;

			for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
				{
				     //ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PresentChargingPower = 100.0;
				    ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[11].value = (uint16_t) (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.AvailableChargingPower*100);
				}
			}
		}

		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[11].context, ReadingContextEnumTypeStr[dataType]);
		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[11].measurand, MeasurandEnumTypeStr[MeasurandEnumType_Power_Offered]);
		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[11].location, LocationEnumTypeStr[LocationEnumType_Outlet]);
		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[11].unitOfMeasure.uint , "W");
		ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[11].unitOfMeasure.multiplier = 0;
	}

	// Message create ====================================================================================================
	random_uuid(guid);

	for(uint8_t idxMeter=0;idxMeter<ARRAY_SIZE(ShmOCPP20Data->MeterValues[gun_index].meterValue);idxMeter++)
	{
		json_object *meterValue = json_object_new_object();

		for(int idxSample=0;idxSample<ARRAY_SIZE(ShmOCPP20Data->MeterValues[gun_index].meterValue[idxMeter].sampledValue);idxSample++)
		{
			if(strlen((char*)ShmOCPP20Data->MeterValues[gun_index].meterValue[idxMeter].sampledValue[idxSample].context) > 0)
			{
				json_object *sampledValue = json_object_new_object();

				json_object_object_add(sampledValue, "value", json_object_new_double(ShmOCPP20Data->MeterValues[gun_index].meterValue[idxMeter].sampledValue[idxSample].value));

				if(strlen((char*)ShmOCPP20Data->MeterValues[gun_index].meterValue[idxMeter].sampledValue[idxSample].context) > 0)
					json_object_object_add(sampledValue, "context", json_object_new_string((char*)ShmOCPP20Data->MeterValues[gun_index].meterValue[idxMeter].sampledValue[idxSample].context));

				if(strlen((char*)ShmOCPP20Data->MeterValues[gun_index].meterValue[idxMeter].sampledValue[idxSample].measurand) > 0)
					json_object_object_add(sampledValue, "measurand", json_object_new_string((char*)ShmOCPP20Data->MeterValues[gun_index].meterValue[idxMeter].sampledValue[idxSample].measurand));

				if(strlen((char*)ShmOCPP20Data->MeterValues[gun_index].meterValue[idxMeter].sampledValue[idxSample].phase) > 0)
					json_object_object_add(sampledValue, "phase", json_object_new_string((char*)ShmOCPP20Data->MeterValues[gun_index].meterValue[idxMeter].sampledValue[idxSample].phase));

				if(strlen((char*)ShmOCPP20Data->MeterValues[gun_index].meterValue[idxMeter].sampledValue[idxSample].location) > 0)
					json_object_object_add(sampledValue, "location", json_object_new_string((char*)ShmOCPP20Data->MeterValues[gun_index].meterValue[idxMeter].sampledValue[idxSample].location));

				if(strlen((char*)ShmOCPP20Data->MeterValues[gun_index].meterValue[idxMeter].sampledValue[idxSample].unitOfMeasure.uint) > 0)
				{
					json_object *unitOfMeasure = json_object_new_object();
					json_object_object_add(unitOfMeasure, "unit", json_object_new_string((char*)ShmOCPP20Data->MeterValues[gun_index].meterValue[idxMeter].sampledValue[idxSample].unitOfMeasure.uint));
					json_object_object_add(unitOfMeasure, "multiplier", json_object_new_int(ShmOCPP20Data->MeterValues[gun_index].meterValue[idxMeter].sampledValue[idxSample].unitOfMeasure.multiplier));
					json_object_object_add(sampledValue, "unitOfMeasure", unitOfMeasure);
				}

				json_object_array_add(sampledValues, sampledValue);
			}
		}
		json_object_object_add(meterValue, "timestamp", json_object_new_string((char*)ShmOCPP20Data->MeterValues[gun_index].meterValue[idxMeter].timestamp));
		json_object_object_add(meterValue, "sampledValue", sampledValues);
		json_object_array_add(meterValues, meterValue);
		idxMeter++;
	}
	json_object_object_add(MeterValueReq, "meterValue", meterValues);
	json_object_object_add(MeterValueReq, "evseId", json_object_new_int(ShmOCPP20Data->MeterValues[gun_index].evseId));

	sprintf(queuedata,"[%d,\"%s\",\"MeterValues\",%s]"
					 ,MESSAGE_TYPE_CALL
					 ,guid
					 ,json_object_to_json_string_ext(MeterValueReq, JSON_C_TO_STRING_PLAIN));

	json_object_put(MeterValueReq);

	if((dataType != ReadingContextEnumType_Trigger) &&
	   (dataType != ReadingContextEnumType_Sample_Clock))
	{
		// Transaction meter value send by TransactionEvent message
		memcpy(&ShmOCPP20Data->TransactionEvent[gun_index].meterValue[0], &ShmOCPP20Data->MeterValues[gun_index].meterValue[0], sizeof(struct MeterValueType));
		ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = ON;

		result = PASS;
	}
	else
	{
		// Put request guid to hash map
		sprintf(tempdata, "MeterValues,%d", (gun_index));
		if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
		{
		 	result = PASS;
		}

		if((dataType != ReadingContextEnumType_Trigger) &&
		   (dataType != ReadingContextEnumType_Sample_Clock))
			queue_operation(QUEUE_OPERATION_ADD, guid, queuedata );//addq(guid, queuedata);  ---> remove temporally
		else
		{
			if(FirstHeartBeat)
				LWS_Send(queuedata +2);
		}
	}

	return result;
}

int sendNotifyChargingLimitRequest(int gun_index)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	char guid[37]={0};
	char tempdata[128]={0};
	json_object *NotifyChargingLimit = json_object_new_object();
	json_object *chargingLimit = json_object_new_object();
	DEBUG_INFO("sendNotifyChargingLimitRequest...\n");

	json_object_object_add(NotifyChargingLimit, "evseId", json_object_new_int(ShmOCPP20Data->NotifyChargingLimit[gun_index].evseId));
	json_object_object_add(chargingLimit, "chargingLimitSource", json_object_new_string((char*)ShmOCPP20Data->NotifyChargingLimit[gun_index].chargingLimit.chargingLimitSource));
	json_object_object_add(chargingLimit, "chargingLimitSource", json_object_new_boolean(ShmOCPP20Data->NotifyChargingLimit[gun_index].chargingLimit.isGridCritical));
	json_object_object_add(NotifyChargingLimit, "chargingLimit", NotifyChargingLimit);

	random_uuid(guid);
	sprintf(message,"[%d,\"%s\",\"%s\",%s]",MESSAGE_TYPE_CALL, guid, "NotifyChargingLimit", json_object_to_json_string_ext(NotifyChargingLimit, JSON_C_TO_STRING_PLAIN));
	json_object_put(NotifyChargingLimit);
	LWS_Send(message);

	sprintf(tempdata, "NotifyChargingLimit,%d", gun_index);
	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;
	}
	return result;
}

int sendNotifyCustomerInformationRequest()
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	char guid[37]={0};
	char tempdata[128]={0};
	json_object *NotifyCustomerInformation = json_object_new_object();
	DEBUG_INFO("sendNotifyCustomerInformationRequest...\n");

	json_object_object_add(NotifyCustomerInformation, "data", json_object_new_string((char*)ShmOCPP20Data->NotifyCustomerInformation.data));
	json_object_object_add(NotifyCustomerInformation, "tbc", json_object_new_boolean(ShmOCPP20Data->NotifyCustomerInformation.tbc));
	json_object_object_add(NotifyCustomerInformation, "seqNo", json_object_new_int(ShmOCPP20Data->NotifyCustomerInformation.seqNo));
	json_object_object_add(NotifyCustomerInformation, "generatedAt", json_object_new_string((char*)ShmOCPP20Data->NotifyCustomerInformation.generatedAt));
	json_object_object_add(NotifyCustomerInformation, "requestId", json_object_new_int(ShmOCPP20Data->NotifyCustomerInformation.requestId));

	random_uuid(guid);
	sprintf(message,"[%d,\"%s\",\"%s\",%s]",MESSAGE_TYPE_CALL, guid, "NotifyCustomerInformation", json_object_to_json_string_ext(NotifyCustomerInformation, JSON_C_TO_STRING_PLAIN));
	json_object_put(NotifyCustomerInformation);
	LWS_Send(message);

	sprintf(tempdata, "NotifyCustomerInformation,0");
	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;
	}
	return result;
}

int sendNotifyDisplayMessagesRequest()
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	char guid[37]={0};
	char tempdata[128]={0};
	json_object *NotifyDisplayMessages = json_object_new_object();
	json_object *messageInfos = json_object_new_array();
	DEBUG_INFO("sendNotifyDisplayMessagesRequest...\n");

	json_object_object_add(NotifyDisplayMessages, "requestId", json_object_new_int(ShmOCPP20Data->NotifyDisplayMessages.requestId));
	json_object_object_add(NotifyDisplayMessages, "tbc", json_object_new_boolean(ShmOCPP20Data->NotifyDisplayMessages.tbc));

	for(int idxMsg=0;idxMsg<ARRAY_SIZE(ShmOCPP20Data->NotifyDisplayMessages.messageInfo);idxMsg++)
	{
		if(strlen((char*)ShmOCPP20Data->NotifyDisplayMessages.messageInfo[idxMsg].message.content) > 0)
		{
			json_object *messageInfo = json_object_new_object();
			json_object *message = json_object_new_object();
			json_object *display = json_object_new_object();
			json_object *evse = json_object_new_object();

			json_object_object_add(messageInfo, "id", json_object_new_int(ShmOCPP20Data->NotifyDisplayMessages.messageInfo[idxMsg].id));
			json_object_object_add(messageInfo, "priority", json_object_new_string((char*)ShmOCPP20Data->NotifyDisplayMessages.messageInfo[idxMsg].priority));
			json_object_object_add(messageInfo, "state", json_object_new_string((char*)ShmOCPP20Data->NotifyDisplayMessages.messageInfo[idxMsg].state));
			json_object_object_add(messageInfo, "startDateTime", json_object_new_string((char*)ShmOCPP20Data->NotifyDisplayMessages.messageInfo[idxMsg].startDateTime));
			json_object_object_add(messageInfo, "endDateTime", json_object_new_string((char*)ShmOCPP20Data->NotifyDisplayMessages.messageInfo[idxMsg].endDateTime));
			json_object_object_add(messageInfo, "transactionId", json_object_new_string((char*)ShmOCPP20Data->NotifyDisplayMessages.messageInfo[idxMsg].transactionId));

			json_object_object_add(message, "format", json_object_new_string((char*)ShmOCPP20Data->NotifyDisplayMessages.messageInfo[idxMsg].message.format));
			json_object_object_add(message, "language", json_object_new_string((char*)ShmOCPP20Data->NotifyDisplayMessages.messageInfo[idxMsg].message.language));
			json_object_object_add(message, "content", json_object_new_string((char*)ShmOCPP20Data->NotifyDisplayMessages.messageInfo[idxMsg].message.content));
			json_object_object_add(messageInfo, "message", message);

			json_object_object_add(display, "name", json_object_new_string((char*)ShmOCPP20Data->NotifyDisplayMessages.messageInfo[idxMsg].display.name));
			json_object_object_add(display, "instance", json_object_new_string((char*)ShmOCPP20Data->NotifyDisplayMessages.messageInfo[idxMsg].display.instance));
			json_object_object_add(evse, "id", json_object_new_int(ShmOCPP20Data->NotifyDisplayMessages.messageInfo[idxMsg].display.evse.id));
			json_object_object_add(evse, "connectorId", json_object_new_int(ShmOCPP20Data->NotifyDisplayMessages.messageInfo[idxMsg].display.evse.connectorId));
			json_object_object_add(display, "evse",evse);
			json_object_object_add(messageInfo, "evse", display);

			json_object_array_add(messageInfos, messageInfo);
		}
	}
	json_object_object_add(NotifyDisplayMessages, "messageInfo", messageInfos);

	random_uuid(guid);
	sprintf(message,"[%d,\"%s\",\"%s\",%s]",MESSAGE_TYPE_CALL, guid, "NotifyDisplayMessages", json_object_to_json_string_ext(NotifyDisplayMessages, JSON_C_TO_STRING_PLAIN));
	json_object_put(NotifyDisplayMessages);
	LWS_Send(message);

	sprintf(tempdata, "NotifyDisplayMessages,0");
	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;
	}
	return result;
}

int sendNotifyEVChargingNeedsRequest(int gun_index)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	char guid[37]={0};
	char tempdata[128]={0};
	json_object *NotifyEVChargingNeeds = json_object_new_object();
	json_object *chargingNeeds = json_object_new_object();
	json_object *acChargingParameters = json_object_new_object();
	json_object *dcChargingParameters = json_object_new_object();
	DEBUG_INFO("sendNotifyEVChargingNeedsRequest...\n");

	json_object_object_add(NotifyEVChargingNeeds, "maxScheduleTuples", json_object_new_int(ShmOCPP20Data->NotifyEVChargingNeeds[gun_index].maxScheduleTuples));
	json_object_object_add(NotifyEVChargingNeeds, "evseId", json_object_new_int(ShmOCPP20Data->NotifyEVChargingNeeds[gun_index].evseId));

	json_object_object_add(chargingNeeds, "requestedEnergyTransfer", json_object_new_string((char*)ShmOCPP20Data->NotifyEVChargingNeeds[gun_index].chargingNeeds.requestedEnergyTransfer));
	json_object_object_add(chargingNeeds, "departureTime", json_object_new_string((char*)ShmOCPP20Data->NotifyEVChargingNeeds[gun_index].chargingNeeds.departureTime));

	json_object_object_add(acChargingParameters, "energyAmount", json_object_new_int(ShmOCPP20Data->NotifyEVChargingNeeds[gun_index].chargingNeeds.acChargingParameters.energyAmount));
	json_object_object_add(acChargingParameters, "evMinCurrent", json_object_new_int(ShmOCPP20Data->NotifyEVChargingNeeds[gun_index].chargingNeeds.acChargingParameters.evMinCurrent));
	json_object_object_add(acChargingParameters, "evMaxCurrent", json_object_new_int(ShmOCPP20Data->NotifyEVChargingNeeds[gun_index].chargingNeeds.acChargingParameters.evMaxCurrent));
	json_object_object_add(acChargingParameters, "evMaxVoltage", json_object_new_int(ShmOCPP20Data->NotifyEVChargingNeeds[gun_index].chargingNeeds.acChargingParameters.evMaxVoltage));
	json_object_object_add(chargingNeeds, "acChargingParameters", acChargingParameters);

	json_object_object_add(dcChargingParameters, "evMaxCurrent", json_object_new_int(ShmOCPP20Data->NotifyEVChargingNeeds[gun_index].chargingNeeds.dcChargingParameters.evMaxCurrent));
	json_object_object_add(dcChargingParameters, "evMaxVoltage", json_object_new_int(ShmOCPP20Data->NotifyEVChargingNeeds[gun_index].chargingNeeds.dcChargingParameters.evMaxVoltage));
	json_object_object_add(dcChargingParameters, "energyAmount", json_object_new_int(ShmOCPP20Data->NotifyEVChargingNeeds[gun_index].chargingNeeds.dcChargingParameters.energyAmount));
	json_object_object_add(dcChargingParameters, "evMaxPower", json_object_new_int(ShmOCPP20Data->NotifyEVChargingNeeds[gun_index].chargingNeeds.dcChargingParameters.evMaxPower));
	json_object_object_add(dcChargingParameters, "stateOfCharge", json_object_new_int(ShmOCPP20Data->NotifyEVChargingNeeds[gun_index].chargingNeeds.dcChargingParameters.stateOfCharge));
	json_object_object_add(dcChargingParameters, "evEnergyCapacity", json_object_new_int(ShmOCPP20Data->NotifyEVChargingNeeds[gun_index].chargingNeeds.dcChargingParameters.evEnergyCapacity));
	json_object_object_add(dcChargingParameters, "fullSoC", json_object_new_int(ShmOCPP20Data->NotifyEVChargingNeeds[gun_index].chargingNeeds.dcChargingParameters.fullSoC));
	json_object_object_add(dcChargingParameters, "bulkSoC", json_object_new_int(ShmOCPP20Data->NotifyEVChargingNeeds[gun_index].chargingNeeds.dcChargingParameters.bulkSoC));
	json_object_object_add(chargingNeeds, "dcChargingParameters", dcChargingParameters);

	json_object_object_add(NotifyEVChargingNeeds, "chargingNeeds", chargingNeeds);

	random_uuid(guid);
	sprintf(message,"[%d,\"%s\",\"%s\",%s]",MESSAGE_TYPE_CALL, guid, "NotifyEVChargingNeeds", json_object_to_json_string_ext(NotifyEVChargingNeeds, JSON_C_TO_STRING_PLAIN));
	json_object_put(NotifyEVChargingNeeds);
	LWS_Send(message);

	sprintf(tempdata, "NotifyEVChargingNeeds,%d", gun_index);
	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;
	}
	return result;
}

int sendNotifyEVChargingScheduleRequest(int gun_index)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	char guid[37]={0};
	char tempdata[128]={0};
	json_object *NotifyEVChargingSchedule = json_object_new_object();
	json_object *chargingSchedule = json_object_new_object();
	json_object *periods = json_object_new_array();
	DEBUG_INFO("sendNotifyEVChargingScheduleRequest...\n");

	json_object_object_add(NotifyEVChargingSchedule, "timeBase", json_object_new_string((char*)ShmOCPP20Data->NotifyEVChargingSchedule[gun_index].timeBase));
	json_object_object_add(NotifyEVChargingSchedule, "evseId", json_object_new_int(ShmOCPP20Data->NotifyEVChargingSchedule[gun_index].evseId));

	json_object_object_add(chargingSchedule, "startSchedule", json_object_new_string((char*)ShmOCPP20Data->NotifyEVChargingSchedule[gun_index].chargingSchedule.startSchedule));
	json_object_object_add(chargingSchedule, "duration", json_object_new_int(ShmOCPP20Data->NotifyEVChargingSchedule[gun_index].chargingSchedule.duration));
	json_object_object_add(chargingSchedule, "chargingRateUnit", json_object_new_string((char*)ShmOCPP20Data->NotifyEVChargingSchedule[gun_index].chargingSchedule.chargingRateUnit));
	json_object_object_add(chargingSchedule, "minChargingRate", json_object_new_double(ShmOCPP20Data->NotifyEVChargingSchedule[gun_index].chargingSchedule.minChargingRate));
	json_object_object_add(chargingSchedule, "id", json_object_new_int(ShmOCPP20Data->NotifyEVChargingSchedule[gun_index].chargingSchedule.id));

	for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(ShmOCPP20Data->NotifyEVChargingSchedule[gun_index].chargingSchedule.chargingSchedulePeriod);idxPeriod++)
	{
		if(((ShmOCPP20Data->NotifyEVChargingSchedule[gun_index].chargingSchedule.chargingSchedulePeriod[idxPeriod].startPeriod == 0) && (ShmOCPP20Data->NotifyEVChargingSchedule[gun_index].chargingSchedule.chargingSchedulePeriod[idxPeriod].limit>0)) ||
		   (ShmOCPP20Data->NotifyEVChargingSchedule[gun_index].chargingSchedule.chargingSchedulePeriod[idxPeriod].startPeriod > 0))
		{
			json_object *Period = json_object_new_object();
			json_object_object_add(Period, "startPeriod", json_object_new_int(ShmOCPP20Data->NotifyEVChargingSchedule[gun_index].chargingSchedule.chargingSchedulePeriod[idxPeriod].startPeriod));
			json_object_object_add(Period, "limit", json_object_new_double(ShmOCPP20Data->NotifyEVChargingSchedule[gun_index].chargingSchedule.chargingSchedulePeriod[idxPeriod].limit));

			if(ShmOCPP20Data->NotifyEVChargingSchedule[gun_index].chargingSchedule.chargingSchedulePeriod[idxPeriod].numberPhases > 0)
				json_object_object_add(Period, "numberPhases", json_object_new_int(ShmOCPP20Data->NotifyEVChargingSchedule[gun_index].chargingSchedule.chargingSchedulePeriod[idxPeriod].numberPhases));
			if(ShmOCPP20Data->NotifyEVChargingSchedule[gun_index].chargingSchedule.chargingSchedulePeriod[idxPeriod].phaseToUse > 0)
				json_object_object_add(Period, "phaseToUse", json_object_new_int(ShmOCPP20Data->NotifyEVChargingSchedule[gun_index].chargingSchedule.chargingSchedulePeriod[idxPeriod].phaseToUse));

			json_object_array_add(periods, Period);
		}
	}
	json_object_object_add(chargingSchedule, "chargingSchedulePeriod", periods);

	json_object_object_add(NotifyEVChargingSchedule, "chargingSchedule", chargingSchedule);

	random_uuid(guid);
	sprintf(message,"[%d,\"%s\",\"%s\",%s]",MESSAGE_TYPE_CALL, guid, "NotifyEVChargingSchedule", json_object_to_json_string_ext(NotifyEVChargingSchedule, JSON_C_TO_STRING_PLAIN));
	json_object_put(NotifyEVChargingSchedule);
	LWS_Send(message);

	sprintf(tempdata, "NotifyEVChargingSchedule,%d", gun_index);
	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;
	}
	return result;
}

int sendNotifyEventRequest()
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	char guid[37]={0};
	char tempdata[128]={0};
	json_object *NotifyEvent = json_object_new_object();
	json_object *eventDatas = json_object_new_array();
	DEBUG_INFO("sendNotifyEventRequest...\n");

	json_object_object_add(NotifyEvent, "generatedAt", json_object_new_string((char*)ShmOCPP20Data->NotifyEvent.generatedAt));
	json_object_object_add(NotifyEvent, "tbc", json_object_new_boolean(ShmOCPP20Data->NotifyEvent.tbc));
	json_object_object_add(NotifyEvent, "seqNo", json_object_new_int(ShmOCPP20Data->NotifyEvent.seqNo));

	for(int idxEvent=0;idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData);idxEvent++)
	{
		if(strlen((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp) > 0)
		{
			json_object *eventData = json_object_new_object();
			json_object *component = json_object_new_object();
			json_object *evse = json_object_new_object();
			json_object *variable = json_object_new_object();

			json_object_object_add(eventData, "eventId", json_object_new_int(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId));
			json_object_object_add(eventData, "timestamp", json_object_new_string((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp));
			json_object_object_add(eventData, "trigger", json_object_new_string((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger));
			json_object_object_add(eventData, "cause", json_object_new_int(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cause));
			json_object_object_add(eventData, "actualValue", json_object_new_string((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue));
			json_object_object_add(eventData, "techCode", json_object_new_string((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode));
			json_object_object_add(eventData, "techInfo", json_object_new_string((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo));
			json_object_object_add(eventData, "cleared", json_object_new_boolean(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared));
			json_object_object_add(eventData, "transactionId", json_object_new_string((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].transactionId));
			json_object_object_add(eventData, "variableMonitoringId", json_object_new_int(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variableMonitoringId));
			json_object_object_add(eventData, "eventNotificationType", json_object_new_string((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType));

			json_object_object_add(component, "name", json_object_new_string((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name));
			json_object_object_add(component, "instance", json_object_new_string((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.instance));
			json_object_object_add(evse, "id", json_object_new_int(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.id));
			json_object_object_add(evse, "connectorId", json_object_new_int(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId));
			json_object_object_add(component, "evse",evse);
			json_object_object_add(eventData, "component", component);

			json_object_object_add(variable, "name", json_object_new_string((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name));
			json_object_object_add(variable, "instance", json_object_new_string((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.instance));
			json_object_object_add(eventData, "variable", variable);

			json_object_array_add(eventDatas, eventData);
		}
	}
	json_object_object_add(NotifyEvent, "eventData", eventDatas);

	random_uuid(guid);
	sprintf(message,"[%d,\"%s\",\"%s\",%s]",MESSAGE_TYPE_CALL, guid, "NotifyEvent", json_object_to_json_string_ext(NotifyEvent, JSON_C_TO_STRING_PLAIN));
	json_object_put(NotifyEvent);
	LWS_Send(message);

	sprintf(tempdata, "NotifyEvent,0");
	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;
	}
	return result;
}

int sendNotifyMonitoringReportRequest()
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	char guid[37]={0};
	char tempdata[128]={0};
	json_object *NotifyMonitoringReport = json_object_new_object();
	json_object *monitors = json_object_new_array();
	DEBUG_INFO("sendNotifyMonitoringReportRequest...\n");

	json_object_object_add(NotifyMonitoringReport, "requestId", json_object_new_int(ShmOCPP20Data->NotifyMonitoringReport.requestId));
	json_object_object_add(NotifyMonitoringReport, "tbc", json_object_new_int(ShmOCPP20Data->NotifyMonitoringReport.tbc));
	json_object_object_add(NotifyMonitoringReport, "seqNo", json_object_new_int(ShmOCPP20Data->NotifyMonitoringReport.seqNo));
	json_object_object_add(NotifyMonitoringReport, "generatedAt", json_object_new_string((char*)ShmOCPP20Data->NotifyMonitoringReport.generatedAt));

	for(int idxMonitor=0;idxMonitor<ARRAY_SIZE(ShmOCPP20Data->NotifyMonitoringReport.monitor);idxMonitor++)
	{
		if(strlen((char*)ShmOCPP20Data->NotifyMonitoringReport.monitor[idxMonitor].component.name) > 0)
		{
			json_object *monitor = json_object_new_object();
			json_object *component = json_object_new_object();
			json_object *evse = json_object_new_object();
			json_object *variable = json_object_new_object();
			json_object *variableMonitorings = json_object_new_array();

			json_object_object_add(component, "name", json_object_new_string((char*)ShmOCPP20Data->NotifyMonitoringReport.monitor[idxMonitor].component.name));
			json_object_object_add(component, "instance", json_object_new_string((char*)ShmOCPP20Data->NotifyMonitoringReport.monitor[idxMonitor].component.instance));
			json_object_object_add(evse, "id", json_object_new_int(ShmOCPP20Data->NotifyMonitoringReport.monitor[idxMonitor].component.evse.id));
			json_object_object_add(evse, "connectorId", json_object_new_int(ShmOCPP20Data->NotifyMonitoringReport.monitor[idxMonitor].component.evse.connectorId));
			json_object_object_add(component, "evse",evse);
			json_object_object_add(monitor, "component", component);

			json_object_object_add(variable, "name", json_object_new_string((char*)ShmOCPP20Data->NotifyMonitoringReport.monitor[idxMonitor].variable.name));
			json_object_object_add(variable, "instance", json_object_new_string((char*)ShmOCPP20Data->NotifyMonitoringReport.monitor[idxMonitor].variable.instance));
			json_object_object_add(monitor, "variable", variable);

			for(int idxVar=0;idxVar<ARRAY_SIZE(ShmOCPP20Data->NotifyMonitoringReport.monitor[idxMonitor].variableMonitoring);idxVar++)
			{
				if(strlen((char*)ShmOCPP20Data->NotifyMonitoringReport.monitor[idxMonitor].variableMonitoring[idxVar].type) > 0)
				{
					json_object *variableMonitoring = json_object_new_object();

					json_object_object_add(variableMonitoring, "id", json_object_new_int(ShmOCPP20Data->NotifyMonitoringReport.monitor[idxMonitor].variableMonitoring[idxVar].id));
					json_object_object_add(variableMonitoring, "value", json_object_new_double(ShmOCPP20Data->NotifyMonitoringReport.monitor[idxMonitor].variableMonitoring[idxVar].value));
					json_object_object_add(variableMonitoring, "type", json_object_new_string((char*)ShmOCPP20Data->NotifyMonitoringReport.monitor[idxMonitor].variableMonitoring[idxVar].type));
					json_object_object_add(variableMonitoring, "severity", json_object_new_int(ShmOCPP20Data->NotifyMonitoringReport.monitor[idxMonitor].variableMonitoring[idxVar].severity));
					json_object_object_add(variableMonitoring, "transaction", json_object_new_boolean(ShmOCPP20Data->NotifyMonitoringReport.monitor[idxMonitor].variableMonitoring[idxVar].transaction));

					json_object_array_add(variableMonitorings, variableMonitoring);
				}
			}
			json_object_object_add(monitor, "variableMonitoring", variableMonitorings);

			json_object_array_add(monitors, monitor);
		}
	}
	json_object_object_add(NotifyMonitoringReport, "monitor", monitors);

	random_uuid(guid);
	sprintf(message,"[%d,\"%s\",\"%s\",%s]",MESSAGE_TYPE_CALL, guid, "NotifyMonitoringReport", json_object_to_json_string_ext(NotifyMonitoringReport, JSON_C_TO_STRING_PLAIN));
	json_object_put(NotifyMonitoringReport);
	LWS_Send(message);

	sprintf(tempdata, "NotifyMonitoringReport,0");
	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;
	}
	return result;
}

int sendNotifyReportRequest()
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	char guid[37]={0};
	char tempdata[128]={0};
	json_object *NotifyReport = json_object_new_object();
	json_object *reportDatas = json_object_new_array();
	DEBUG_INFO("sendNotifyReportRequest...\n");

	json_object_object_add(NotifyReport, "requestId", json_object_new_int(ShmOCPP20Data->NotifyReport.requestId));
	json_object_object_add(NotifyReport, "generatedAt", json_object_new_string((char*)ShmOCPP20Data->NotifyReport.generatedAt));
	json_object_object_add(NotifyReport, "tbc", json_object_new_boolean(ShmOCPP20Data->NotifyReport.tbc));
	json_object_object_add(NotifyReport, "seqNo", json_object_new_int(ShmOCPP20Data->NotifyReport.seqNo));

	for(int idxReport=0;idxReport<ARRAY_SIZE(ShmOCPP20Data->NotifyReport.reportData);idxReport++)
	{
		if(strlen((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].component.name) > 0)
		{
			json_object *reportData = json_object_new_object();
			json_object *component = json_object_new_object();
			json_object *evse = json_object_new_object();
			json_object *variable = json_object_new_object();
			json_object *variableAttributes = json_object_new_array();
			json_object *variableCharacteristics = json_object_new_object();

			json_object_object_add(component, "name", json_object_new_string((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].component.name));
			json_object_object_add(component, "instance", json_object_new_string((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].component.instance));
			json_object_object_add(evse, "id", json_object_new_int(ShmOCPP20Data->NotifyReport.reportData[idxReport].component.evse.id));
			json_object_object_add(evse, "connectorId", json_object_new_int(ShmOCPP20Data->NotifyReport.reportData[idxReport].component.evse.connectorId));
			json_object_object_add(component, "evse",evse);
			json_object_object_add(reportData, "component", component);

			json_object_object_add(variable, "name", json_object_new_string((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variable.name));
			json_object_object_add(variable, "instance", json_object_new_string((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variable.instance));
			json_object_object_add(reportData, "variable",variable);

			json_object_object_add(variableCharacteristics, "unit", json_object_new_string((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variableCharacteristics.unit));
			json_object_object_add(variableCharacteristics, "dataType", json_object_new_string((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variableCharacteristics.dataType));
			json_object_object_add(variableCharacteristics, "minLimit", json_object_new_double(ShmOCPP20Data->NotifyReport.reportData[idxReport].variableCharacteristics.minLimit));
			json_object_object_add(variableCharacteristics, "maxLimit", json_object_new_double(ShmOCPP20Data->NotifyReport.reportData[idxReport].variableCharacteristics.maxLimit));
			json_object_object_add(variableCharacteristics, "supportsMonitoring", json_object_new_boolean(ShmOCPP20Data->NotifyReport.reportData[idxReport].variableCharacteristics.supportsMonitoring));
			json_object_object_add(reportData, "variableCharacteristics",variableCharacteristics);
			DEBUG_INFO("+++++++++++++++++++-->VariableName: %s\n", ShmOCPP20Data->NotifyReport.reportData[idxReport].variable.name);
			for(int idxAttr=0;idxAttr<ARRAY_SIZE(ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute);idxAttr++)
			{
				if(strlen((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].value) > 0)
				{
					json_object *variableAttribute = json_object_new_object();
					json_object_object_add(variableAttribute, "type", json_object_new_string((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].type));
					json_object_object_add(variableAttribute, "value", json_object_new_string((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].value));
					json_object_object_add(variableAttribute, "mutability", json_object_new_string((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].mutability));
					json_object_object_add(variableAttribute, "persistent", json_object_new_boolean(ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].persistent));
					json_object_object_add(variableAttribute, "constant", json_object_new_boolean(ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].constant));

					json_object_array_add(variableAttributes, variableAttribute);
				}
				/*else
				{
					sprintf((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
					sprintf((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_WriteOnly]);
					sprintf((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].value, "%s", "0");
					json_object *variableAttribute = json_object_new_object();q1314qgrh
					//if(strlen((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].type)==0)
					DEBUG_INFO("AAAAAAAAAAAAAAAAA\n");
					json_object_object_add(variableAttribute, "type", json_object_new_string((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].type));
					DEBUG_INFO("BBBBBBBBBBBBBBBBBBB\n");
					json_object_object_add(variableAttribute, "value", json_object_new_string((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].value));
					DEBUG_INFO("CCCCCCCCCCCCCCCCCCCCC\n");
					json_object_object_add(variableAttribute, "mutability", json_object_new_string((char*)ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].mutability));
					DEBUG_INFO("DDDDDDDDDDDDDDDDDDDDDD\n");
					json_object_object_add(variableAttribute, "persistent", json_object_new_boolean(ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].persistent));
					DEBUG_INFO("EEEEEEEEEEEEEEEEEEE\n");
					json_object_object_add(variableAttribute, "constant", json_object_new_boolean(ShmOCPP20Data->NotifyReport.reportData[idxReport].variableAttribute[idxAttr].constant));
					DEBUG_INFO("FFFFFFFFFFFFFFFFFFF\n");
					json_object_array_add(variableAttributes, variableAttribute);
					DEBUG_INFO("GGGGGGGGGGGGGGGGGGGGG\n");
				}*/
			}
			json_object_object_add(reportData, "variableAttribute", variableAttributes);

			json_object_array_add(reportDatas, reportData);
		}
	}
	json_object_object_add(NotifyReport, "reportData", reportDatas);

	random_uuid(guid);
	sprintf(message,"[%d,\"%s\",\"%s\",%s]",MESSAGE_TYPE_CALL, guid, "NotifyReport", json_object_to_json_string_ext(NotifyReport, JSON_C_TO_STRING_PLAIN));
	json_object_put(NotifyReport);
	LWS_SendNow(message);

	sprintf(tempdata, "NotifyReport,0");
	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;
	}
	return result;
}

int sendPublishFirmwareStatusNotificationRequest()
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	char guid[37]={0};
	char tempdata[128]={0};
	json_object *PublishFirmwareStatusNotification = json_object_new_object();
	json_object *locations = json_object_new_array();
	DEBUG_INFO("sendPublishFirmwareStatusNotificationRequest...\n");

	json_object_object_add(PublishFirmwareStatusNotification, "status", json_object_new_string((char*)ShmOCPP20Data->PublishFirmwareStatusNotificatio.status));
	json_object_object_add(PublishFirmwareStatusNotification, "requestId", json_object_new_int(ShmOCPP20Data->PublishFirmwareStatusNotificatio.requestId));

	for(int idx=0;idx<ARRAY_SIZE(ShmOCPP20Data->PublishFirmwareStatusNotificatio.location);idx++)
	{
		json_object_array_add(locations, json_object_new_string((char*)ShmOCPP20Data->PublishFirmwareStatusNotificatio.location[idx]));
	}
	json_object_object_add(PublishFirmwareStatusNotification, "location", locations);

	random_uuid(guid);
	sprintf(message,"[%d,\"%s\",\"%s\",%s]",MESSAGE_TYPE_CALL, guid, "PublishFirmwareStatusNotification", json_object_to_json_string_ext(PublishFirmwareStatusNotification, JSON_C_TO_STRING_PLAIN));
	json_object_put(PublishFirmwareStatusNotification);
	LWS_Send(message);

	sprintf(tempdata, "PublishFirmwareStatusNotification,0");
	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;
	}
	return result;
}

int sendReportChargingProfilesRequest(int gun_index)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	char guid[37]={0};
	char tempdata[128]={0};
	json_object *ReportChargingProfiles = json_object_new_object();
	json_object *chargingProfiles = json_object_new_array();
	DEBUG_INFO("sendReportChargingProfilesRequest...\n");

	json_object_object_add(ReportChargingProfiles, "requestId", json_object_new_int(ShmOCPP20Data->ReportChargingProfiles[gun_index].requestId));
	json_object_object_add(ReportChargingProfiles, "chargingLimitSource", json_object_new_string((char*)ShmOCPP20Data->ReportChargingProfiles[gun_index].chargingLimitSource));
	json_object_object_add(ReportChargingProfiles, "tbc", json_object_new_int(ShmOCPP20Data->ReportChargingProfiles[gun_index].tbc));
	json_object_object_add(ReportChargingProfiles, "evseId", json_object_new_int(ShmOCPP20Data->ReportChargingProfiles[gun_index].evseId));

	for(int idxProfile=0;idxProfile<ARRAY_SIZE(ShmOCPP20Data->ReportChargingProfiles[gun_index].chargingProfile);idxProfile++)
	{
		json_object *chargingProfile = json_object_new_object();
		json_object *chargingSchedules = json_object_new_array();

		json_object_object_add(chargingProfile, "id", json_object_new_int(ShmOCPP20Data->ReportChargingProfiles[gun_index].chargingProfile[idxProfile].id));
		json_object_object_add(chargingProfile, "stackLevel", json_object_new_int(ShmOCPP20Data->ReportChargingProfiles[gun_index].chargingProfile[idxProfile].stackLevel));
		json_object_object_add(chargingProfile, "chargingProfilePurpose", json_object_new_string((char*)ShmOCPP20Data->ReportChargingProfiles[gun_index].chargingProfile[idxProfile].chargingProfilePurpose));
		json_object_object_add(chargingProfile, "chargingProfileKind", json_object_new_string((char*)ShmOCPP20Data->ReportChargingProfiles[gun_index].chargingProfile[idxProfile].chargingProfileKind));
		json_object_object_add(chargingProfile, "recurrencyKind", json_object_new_string((char*)ShmOCPP20Data->ReportChargingProfiles[gun_index].chargingProfile[idxProfile].recurrencyKind));
		json_object_object_add(chargingProfile, "validFrom", json_object_new_string((char*)ShmOCPP20Data->ReportChargingProfiles[gun_index].chargingProfile[idxProfile].validFrom));
		json_object_object_add(chargingProfile, "validTo", json_object_new_string((char*)ShmOCPP20Data->ReportChargingProfiles[gun_index].chargingProfile[idxProfile].validTo));
		json_object_object_add(chargingProfile, "transactionId", json_object_new_string((char*)ShmOCPP20Data->ReportChargingProfiles[gun_index].chargingProfile[idxProfile].transactionId));

		for(int idxSchedule=0;idxSchedule<ARRAY_SIZE(ShmOCPP20Data->ReportChargingProfiles[gun_index].chargingProfile[idxProfile].chargingSchedule);idxSchedule++)
		{
			json_object *chargingSchedule = json_object_new_object();
			json_object *chargingSchedulePeriods = json_object_new_array();

			json_object_object_add(chargingSchedule, "startSchedule", json_object_new_string((char*)ShmOCPP20Data->ReportChargingProfiles[gun_index].chargingProfile[idxProfile].chargingSchedule[idxSchedule].startSchedule));
			json_object_object_add(chargingSchedule, "duration", json_object_new_int(ShmOCPP20Data->ReportChargingProfiles[gun_index].chargingProfile[idxProfile].chargingSchedule[idxSchedule].duration));
			json_object_object_add(chargingSchedule, "chargingRateUnit", json_object_new_string((char*)ShmOCPP20Data->ReportChargingProfiles[gun_index].chargingProfile[idxProfile].chargingSchedule[idxSchedule].chargingRateUnit));
			json_object_object_add(chargingSchedule, "minChargingRate", json_object_new_double(ShmOCPP20Data->ReportChargingProfiles[gun_index].chargingProfile[idxProfile].chargingSchedule[idxSchedule].minChargingRate));
			json_object_object_add(chargingSchedule, "id", json_object_new_int(ShmOCPP20Data->ReportChargingProfiles[gun_index].chargingProfile[idxProfile].chargingSchedule[idxSchedule].id));

			for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(ShmOCPP20Data->ReportChargingProfiles[gun_index].chargingProfile[idxProfile].chargingSchedule[idxSchedule].chargingSchedulePeriod);idxPeriod++)
			{
				json_object *chargingSchedulePeriod = json_object_new_object();
				json_object_object_add(chargingSchedulePeriod, "startPeriod", json_object_new_int(ShmOCPP20Data->ReportChargingProfiles[gun_index].chargingProfile[idxProfile].chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod));
				json_object_object_add(chargingSchedulePeriod, "limit", json_object_new_double(ShmOCPP20Data->ReportChargingProfiles[gun_index].chargingProfile[idxProfile].chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit));
				json_object_object_add(chargingSchedulePeriod, "numberPhases", json_object_new_int(ShmOCPP20Data->ReportChargingProfiles[gun_index].chargingProfile[idxProfile].chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases));
				json_object_object_add(chargingSchedulePeriod, "phaseToUse", json_object_new_int(ShmOCPP20Data->ReportChargingProfiles[gun_index].chargingProfile[idxProfile].chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].phaseToUse));

				json_object_array_add(chargingSchedulePeriods, chargingSchedulePeriod);
			}
			json_object_object_add(chargingSchedule, "chargingSchedulePeriod", chargingSchedulePeriods);


			json_object_array_add(chargingSchedules, chargingSchedule);
		}
		json_object_object_add(chargingProfile, "chargingSchedule", chargingSchedules);

		json_object_array_add(chargingProfiles, chargingProfile);
	}
	json_object_object_add(ReportChargingProfiles, "chargingProfile", chargingProfiles);

	random_uuid(guid);
	sprintf(message,"[%d,\"%s\",\"%s\",%s]",MESSAGE_TYPE_CALL, guid, "ReportChargingProfiles", json_object_to_json_string_ext(ReportChargingProfiles, JSON_C_TO_STRING_PLAIN));
	json_object_put(ReportChargingProfiles);
	LWS_Send(message);

	sprintf(tempdata, "ReportChargingProfiles,%d", gun_index);
	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;
	}
	return result;
}

int sendReservationStatusUpdateRequest(int gun_index)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	char guid[37]={0};
	char tempdata[128]={0};
	json_object *ReservationStatusUpdate = json_object_new_object();
	DEBUG_INFO("sendReservationStatusUpdateRequest...\n");

	json_object_object_add(ReservationStatusUpdate, "reservationId", json_object_new_int(ShmOCPP20Data->ReservationStatusUpdate[gun_index].reservationId));
	json_object_object_add(ReservationStatusUpdate, "reservationUpdateStatus", json_object_new_string((char*)ShmOCPP20Data->ReservationStatusUpdate[gun_index].reservationUpdateStatus));

	random_uuid(guid);
	sprintf(message,"[%d,\"%s\",\"%s\",%s]",MESSAGE_TYPE_CALL, guid, "ReservationStatusUpdate", json_object_to_json_string_ext(ReservationStatusUpdate, JSON_C_TO_STRING_PLAIN));
	json_object_put(ReservationStatusUpdate);
	LWS_Send(message);

	sprintf(tempdata, "ReservationStatusUpdate,%d", gun_index);
	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;

		ShmOCPP20Data->CpMsg.bits[gun_index].ReservationStatusUpdateReq = OFF;
	}
	return result;
}

int sendSecurityEventNotificationRequest()
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	char guid[37]={0};
	char tempdata[128]={0};
	struct timeval tmnow;
	struct tm *tm;
	char buf[28];//, usec_buf[6];
	json_object *SecurityEventNotification = json_object_new_object();
	DEBUG_INFO("sendSecurityEventNotificationRequest...\n");

	DB_getSecurityEventType();

	gettimeofday(&tmnow, NULL);

	time_t t;
	t = time(NULL);
	/*UTC time and date*/
	tm = gmtime(&t);
	strftime(buf,28,"%Y-%m-%dT%H:%M:%SZ", tm);
#if 0 // remove temporally
	strftime(buf,30,"%Y-%m-%dT%H:%M:%S", tm);
	strcat(buf,".");
	sprintf(usec_buf,"%dZ",(int)tmnow.tv_usec);
	strcat(buf,usec_buf);
#endif
	printf("%s",buf);

	strcpy((char *)ShmOCPP20Data->SecurityEventNotification.timestamp, buf);
	if(strlen((char *)ShmOCPP20Data->SecurityEventNotification.techInfo)==0)
		sprintf((char*)ShmOCPP20Data->SecurityEventNotification.type,"%s", SecurityEventEnumTypeStr[SecurityEventEnumType_ResetOrReboot]);

	json_object_object_add(SecurityEventNotification, "type", json_object_new_string((char*)ShmOCPP20Data->SecurityEventNotification.type));
	json_object_object_add(SecurityEventNotification, "timestamp", json_object_new_string((char*)ShmOCPP20Data->SecurityEventNotification.timestamp));
	if(strlen((char *)ShmOCPP20Data->SecurityEventNotification.techInfo)>0)
		json_object_object_add(SecurityEventNotification, "techInfo", json_object_new_string((char*)ShmOCPP20Data->SecurityEventNotification.techInfo));

	random_uuid(guid);
	sprintf(message,"[%d,\"%s\",\"%s\",%s]",MESSAGE_TYPE_CALL, guid, "SecurityEventNotification", json_object_to_json_string_ext(SecurityEventNotification, JSON_C_TO_STRING_PLAIN));
	json_object_put(SecurityEventNotification);
	LWS_Send(message);

	sprintf(tempdata, "SecurityEventNotification,0");
	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;
	}
	return result;
}

int sendSignCertificateRequest(CertificateSigningUseEnumType certType)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	char guid[37]={0};
	char tempdata[128]={0};
	json_object *SignCertificate = json_object_new_object();
	DEBUG_INFO("sendSignCertificateRequest...\n");

	// Read csr file content
	memset(ShmOCPP20Data->SignCertificate.csr, 0x00, ARRAY_SIZE(ShmOCPP20Data->SignCertificate.csr));
	FILE *fp=fopen(((certType == CertificateSignedStatusEnumType_V2GCertificate)?"/Storage/OCPP/certV2G.csr":"/Storage/OCPP/certCP.csr"),"r");
	char *line = NULL;
	size_t len = 0;
	while(getline(&line, &len, fp) != -1)
	{
		if((strstr(line, "BEGIN CERTIFICATE REQUEST") == NULL) && (strstr(line, "END CERTIFICATE REQUEST") == NULL))
		{
			memcpy(&ShmOCPP20Data->SignCertificate.csr[strlen((char*)ShmOCPP20Data->SignCertificate.csr)], line, (strlen(line)-1));
		}
	}
	fclose(fp);

	json_object_object_add(SignCertificate, "csr", json_object_new_string((char*)ShmOCPP20Data->SignCertificate.csr));

	sprintf((char*)ShmOCPP20Data->SignCertificate.certificateType, CertificateSigningUseEnumTypeStr[certType]);
	json_object_object_add(SignCertificate, "certificateType", json_object_new_string((char*)ShmOCPP20Data->SignCertificate.certificateType));

	random_uuid(guid);
	sprintf(message,"[%d,\"%s\",\"%s\",%s]",MESSAGE_TYPE_CALL, guid, "SignCertificate", json_object_to_json_string_ext(SignCertificate, JSON_C_TO_STRING_PLAIN));
	json_object_put(SignCertificate);
	LWS_Send(message);

	sprintf(tempdata, "SignCertificate,0");
	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;
	}
	return result;
}

int sendStatusNotificationRequest(int gun_index)
{
	mtrace();
	int result = FAIL;

	char message[600]={0};
	char guid[37];
	int currentStatus = 0;
	struct timeval tmnow;
	struct tm *tm;
	char buf[28];//, usec_buf[6];
	char tempdata[65]={0};
	int tempIndex = 0;
	uint8_t isStateChanged = TRUE;

	DEBUG_INFO("sendStatusNotificationRequest...\n");

	gettimeofday(&tmnow, NULL);

	time_t t;
	t = time(NULL);
	/*UTC time and date*/
	tm = gmtime(&t);
	strftime(buf,28,"%Y-%m-%dT%H:%M:%SZ", tm);
#if 0 // remove temporally
	strftime(buf,30,"%Y-%m-%dT%H:%M:%S", tm);
	strcat(buf,".");
	sprintf(usec_buf,"%dZ",(int)tmnow.tv_usec);
	strcat(buf,usec_buf);
#endif
	printf("%s",buf);

	ShmOCPP20Data->StatusNotification[gun_index].evseId = (gun_index + 1);
	ShmOCPP20Data->StatusNotification[gun_index].connectorId = (gun_index + 1);
	strcpy((char *)ShmOCPP20Data->StatusNotification[gun_index].timestamp, buf);
	//strcpy(ShmOCPP20Data->StatusNotification[gun_index].ErrorCode, "NoError"); --- CSU Setting

/*
	 enum _SYSTEM_STATUS
{
S_BOOTING               = 0,
S_IDLE,                 = 1
S_AUTHORIZING,          =2
S_REASSIGN_CHECK,       =3
S_REASSIGN,             =4
S_PRECHARGE,            =5
S_PREPARING_FOR_EV,     =6
S_PREPARING_FOR_EVSE,   =7
S_CHARGING,             =8
S_TERMINATING,          =9
S_COMPLETE,             =10
S_ALARM,                =11
S_FAULT                 =12
}

*/

	//check Transaction active
	//J: CHAdeMO  U: CCS1 combo  E: CCS2 combo  G: GBT DCcc
	if(gunType[gun_index] == GUN_TYPE_CHAdeMO)
	{
		if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
		{
			tempIndex = ((gun_index==2) ? 1: 0);
		}
		else
		{
			tempIndex = gun_index;
		}

		for (int index = 0; index < CHAdeMO_QUANTITY; index++)
		{
			if ((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex))
			{
				if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_IDLE)//S_IDLE
				{
					if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ConnectorPlugIn == ON) // //0: unplug, 1: Plug-in
					{
						currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: Preparing
					}
					else
					{
						currentStatus = ConnectorStatusEnumType_Available; //OCPP Status: Available
					}

					memset(&ShmOCPP20Data->TransactionEvent[gun_index].eventType[0], 0x00, ARRAY_SIZE(ShmOCPP20Data->TransactionEvent[gun_index].eventType));
					memset(&ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo, 0x00, sizeof(struct TransactionType));
					memset(&ShmOCPP20Data->TransactionEvent[gun_index].idToken, 0x00, sizeof(struct IdTokenType));
					memset(&ShmOCPP20Data->TransactionEvent[gun_index].meterValue, 0x00, sizeof(struct MeterValueType));
				}
				else if ( ((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus >= SYS_MODE_AUTHORIZING)&&( ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus <= SYS_MODE_PREPARE_FOR_EVSE)) ||
				          ((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0) && ( ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1) )
						) //S_PRECHARGE
				{
					currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: Preparing
				}
				else if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_CHARGING) //S_CHARGING
				{
					currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: Charging
				}
				else if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_COMPLETE) //S_COMPLETE
				{
					currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: Finishing
				}
				else if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_TERMINATING) // S_TERMINATING   ---> SuspendedEV
				{
					currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: SuspendedEV
				}
				else if ((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_BOOTING) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //  ---> Unavailable
				{
					currentStatus = ConnectorStatusEnumType_Unavailable; //OCPP Status: Unavailable
				}
				else if ((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_FAULT) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_ALARM)) //S_ALARM,S_FAULT   ---> Faulted
				{
					currentStatus = ConnectorStatusEnumType_Faulted; //OCPP Status: Faulted
				}
				else if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_RESERVATION) //    ---> Reserved
				{
					currentStatus = ConnectorStatusEnumType_Reserved; //OCPP Status: Reserved
				}

			} //end of the same index

		}//end of for CHAdeMO_QUANTITY

	}
	else if(gunType[gun_index] == GUN_TYPE_CCS)
	{
		if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
		{
			tempIndex = ((gun_index==2) ? 1: 0);
		}
		else
		{
			tempIndex = gun_index;
		}

		for (int index = 0; index < CCS_QUANTITY; index++)
		{
			if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
			{
				if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_IDLE) //S_IDLE
				{
					if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ConnectorPlugIn == ON) //0: unplug, 1: Plug-in
					{
						currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: Preparing
					}
					else
					{
						currentStatus = ConnectorStatusEnumType_Available; //OCPP Status: Available
					}

					memset(&ShmOCPP20Data->TransactionEvent[gun_index].eventType[0], 0x00, ARRAY_SIZE(ShmOCPP20Data->TransactionEvent[gun_index].eventType));
					memset(&ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo, 0x00, sizeof(struct TransactionType));
					memset(&ShmOCPP20Data->TransactionEvent[gun_index].idToken, 0x00, sizeof(struct IdTokenType));
					memset(&ShmOCPP20Data->TransactionEvent[gun_index].meterValue, 0x00, sizeof(struct MeterValueType));
				}
				else if ( ((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus >= SYS_MODE_AUTHORIZING)&&( ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus <= SYS_MODE_PREPARE_FOR_EVSE)) ||
				          ((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0) && ( ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1) )
						) //S_PRECHARGE
				{
					currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: Preparing
				}
				else if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_CHARGING) //S_CHARGING
				{
					currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: Charging
				}
				else if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_COMPLETE) //S_COMPLETE
				{
					currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: Finishing
				}
				else if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_TERMINATING) //S_TERMINATING  ---> SuspendedEV
				{
					currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: SuspendedEV
				}
				else if ((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_BOOTING) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //   ---> Unavailable
				{
					currentStatus = ConnectorStatusEnumType_Unavailable; //OCPP Status : Unavailable
				}
				else if ((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_FAULT) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_ALARM)) //S_ALARM ,S_FAULT   ---> Faulted
				{
					currentStatus = ConnectorStatusEnumType_Faulted; //OCPP Status: Faulted
				}
				else if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_RESERVATION) //   ---> Reserved
				{
					currentStatus = ConnectorStatusEnumType_Reserved; //OCPP Status: Reserved
				}

			} //end of the same index

		} // end of for CCS_QUANTITY
	}
	else if(gunType[gun_index] == GUN_TYPE_GBT)
	{
		if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
		{
			tempIndex = ((gun_index==2) ? 1: 0);
		}
		else
		{
			tempIndex = gun_index;
		}

		for (int index = 0; index < GB_QUANTITY; index++)
		{
			if(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex)
			{
				if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_IDLE) //S_IDLE
				{
					if(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ConnectorPlugIn == ON) // //0: unplug, 1: Plug-in
					{
						currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: Preparing
					}
					else
					{
						currentStatus = ConnectorStatusEnumType_Available; //OCPP Status: Available
					}

					memset(&ShmOCPP20Data->TransactionEvent[gun_index].eventType[0], 0x00, ARRAY_SIZE(ShmOCPP20Data->TransactionEvent[gun_index].eventType));
					memset(&ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo, 0x00, sizeof(struct TransactionType));
					memset(&ShmOCPP20Data->TransactionEvent[gun_index].idToken, 0x00, sizeof(struct IdTokenType));
					memset(&ShmOCPP20Data->TransactionEvent[gun_index].meterValue, 0x00, sizeof(struct MeterValueType));
				}
				else if ( ((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus >= SYS_MODE_AUTHORIZING)&&( ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus <= SYS_MODE_PREPARE_FOR_EVSE)) ||
				          ((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0) && ( ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1) )
						) //S_PRECHARGE
				{
					currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: Preparing
				}
				else if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_CHARGING) //S_CHARGING
				{
					currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: Charging
				}
				else if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_COMPLETE) //S_COMPLETE
				{
					currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: Finishing
				}
				else if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_TERMINATING) // S_TERMINATING  ---> SuspendedEV
				{
					currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: SuspendedEV
				}
				else if ((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_BOOTING) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //  ---> Unavailable
				{
					currentStatus = ConnectorStatusEnumType_Unavailable; //OCPP Status: Unavailable
				}
				else if ((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_FAULT) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_ALARM)) //S_ALARM ,S_FAULT   ---> Faulted
				{
					currentStatus = ConnectorStatusEnumType_Faulted; //OCPP Status: Faulted
				}
				else if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_RESERVATION) //   ---> Reserved
				{
					currentStatus = ConnectorStatusEnumType_Reserved; //OCPP Status: Reserved
				}
			} //end of the same index

		} // end of for GB_QUANTITY
	}
	else if(gunType[gun_index] == GUN_TYPE_DO)
	{
		tempIndex = gun_index;

		for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
		{
			if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
			{
				if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_IDLE) //S_IDLE
				{
					if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ConnectorPlugIn == ON) // //0: unplug, 1: Plug-in
					{
						currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: Preparing
					}
					else
					{
						currentStatus = ConnectorStatusEnumType_Available; //OCPP Status: Available
					}

					memset(&ShmOCPP20Data->TransactionEvent[gun_index].eventType[0], 0x00, ARRAY_SIZE(ShmOCPP20Data->TransactionEvent[gun_index].eventType));
					memset(&ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo, 0x00, sizeof(struct TransactionType));
					memset(&ShmOCPP20Data->TransactionEvent[gun_index].idToken, 0x00, sizeof(struct IdTokenType));
					memset(&ShmOCPP20Data->TransactionEvent[gun_index].meterValue, 0x00, sizeof(struct MeterValueType));
				}
				else if ( ((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus >= SYS_MODE_AUTHORIZING) && (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus <= SYS_MODE_PREPARE_FOR_EVSE)) ||
						  ((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0) && (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1) )
						) //S_PRECHARGE
				{
					currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: Preparing
				}
				else if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_CHARGING) //S_CHARGING
				{
					currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: Charging
				}
				else if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_COMPLETE) //S_COMPLETE
				{
					currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: Finishing
				}
				else if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_TERMINATING) // S_TERMINATING  ---> SuspendedEV
				{
					currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: SuspendedEV
				}
				else if ((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_BOOTING) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_UPDATE)) //  ---> Unavailable
				{
					currentStatus = ConnectorStatusEnumType_Unavailable; //OCPP Status: Unavailable
				}
				else if ((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_FAULT) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_ALARM)) //S_ALARM ,S_FAULT   ---> Faulted
				{
					currentStatus = ConnectorStatusEnumType_Faulted; //OCPP Status: Faulted
				}
				else if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_RESERVATION) //   ---> Reserved
				{
					currentStatus = ConnectorStatusEnumType_Reserved; //OCPP Status: Reserved
				}
			} //end of the same index
		}
	}
	else
	{
		if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
		{
			tempIndex = 2;
		}
		else
		{
			tempIndex = gun_index;
		}

		for (int index = 0; index < AC_QUANTITY; index++)
		{
			if(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
			{
				if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_IDLE) //SYS_MODE_IDLE
				{
					if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState == CP_STATE_B) ||(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState == CP_STATE_C) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState == CP_STATE_D))
					{
						currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: Preparing
					}
					else
					{
						currentStatus = ConnectorStatusEnumType_Available; //OCPP Status: Available
					}

					memset(&ShmOCPP20Data->TransactionEvent[gun_index].eventType[0], 0x00, ARRAY_SIZE(ShmOCPP20Data->TransactionEvent[gun_index].eventType));
					memset(&ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo, 0x00, sizeof(struct TransactionType));
					memset(&ShmOCPP20Data->TransactionEvent[gun_index].idToken, 0x00, sizeof(struct IdTokenType));
					memset(&ShmOCPP20Data->TransactionEvent[gun_index].meterValue, 0x00, sizeof(struct MeterValueType));
				}
				else if (/*(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_AUTHORIZING) || */(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_PREPARING)) //SYS_MODE_PREPARING
				{
					currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: Preparing
				}
				else if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_CHARGING) //SYS_MODE_CHARGING
				{
					currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: Charging
				}
				else if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_COMPLETE) //SYS_MODE_COMPLETE
				{
					currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: Finishing
				}
				else if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_TERMINATING) // S_TERMINATING   ---> SuspendedEV
				{
					currentStatus = ConnectorStatusEnumType_Occupied; //OCPP Status: SuspendedEV
				}
				else if ((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_BOOTING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //   ---> Unavailable
				{
					currentStatus = ConnectorStatusEnumType_Unavailable; //OCPP Status: Unavailable
				}
				else if ((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_FAULT) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_ALARM)) //S_ALARM,S_FAULT   ---> Faulted
				{
					currentStatus = ConnectorStatusEnumType_Faulted; //OCPP Status: Faulted
				}
				else if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_RESERVATION) //    ---> Reserved
				{
					currentStatus = ConnectorStatusEnumType_Reserved; //OCPP Status: Reserved
				}

			}//end of the same index

		}//end of for AC_QUANTITY
	}
	//it's option
	if((strstr((char *)ShmOCPP20Data->StatusNotification[gun_index].connectorStatus, ConnectorStatusEnumTypeStr[currentStatus]) != NULL) &&
		!cpinitateMsg.bits[gun_index].TriggerStatusNotificationReq &&
		(strcmp((const char *)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_StatusNotificationPeriodically].variableAttribute[0].value, "TRUE") != 0))
	{
		isStateChanged = FALSE;
	}
	cpinitateMsg.bits[gun_index].TriggerStatusNotificationReq = OFF;

	strcpy((char *)ShmOCPP20Data->StatusNotification[gun_index].connectorStatus, ConnectorStatusEnumTypeStr[currentStatus]);
	random_uuid(guid);
	sprintf(message, "[%d,\"%s\",\"StatusNotification\",{\"connectorId\":%d,\"evseId\":%d,\"connectorStatus\":\"%s\",\"timestamp\":\"%s\"}]"
					, MESSAGE_TYPE_CALL
					, guid
					, ShmOCPP20Data->StatusNotification[gun_index].connectorId
					, ShmOCPP20Data->StatusNotification[gun_index].evseId
					, ShmOCPP20Data->StatusNotification[gun_index].connectorStatus
					, ShmOCPP20Data->StatusNotification[gun_index].timestamp);

	if((server_sign == TRUE) && isStateChanged)
	{
		cpinitateMsg.bits[gun_index].StatusNotificationReq = OFF;
		cpinitateMsg.bits[gun_index].TriggerStatusNotificationReq = OFF;
		LWS_Send(message);

		sprintf(tempdata, "StatusNotification,%d", (gun_index));

		if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
		{
			result = PASS;
		}
	}
	else
	{
		cpinitateMsg.bits[gun_index].StatusNotificationReq = OFF;
		cpinitateMsg.bits[gun_index].TriggerStatusNotificationReq = OFF;
		result = PASS;
	}

	return result;
}

int sendTransactionEventRequest(int gun_index)
{
	mtrace();
	int result = FAIL;
	char message[1024*20]={0};
	char guid[37]={0};
	char tempdata[128]={0};
	uint8_t tempIndex;
	json_object *TransactionEvent = json_object_new_object();
	json_object *transactionInfo = json_object_new_object();
	json_object *idToken = json_object_new_object();
	json_object *evse = json_object_new_object();
	json_object *meterValues = json_object_new_array();
	char TempStopTransaction[256];
	sprintf(TempStopTransaction, "/Storage/OCPP/TempStopTransaction20_%d", (gun_index+1));

	DEBUG_INFO("sendTransactionEventRequest...\n");

	if(gunType[gun_index] == GUN_TYPE_CHAdeMO)
	{
		if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
		{
			tempIndex = ((gun_index==2) ? 1: 0);
		}
		else
		{
			tempIndex = gun_index;
		}

		for (int index = 0; index < CHAdeMO_QUANTITY; index++)
		{
			if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex))
			{
				getNowDatetime(ShmOCPP20Data->TransactionEvent[gun_index].timestamp);

				if((ShmOCPP20Data->TransactionEvent[gun_index].seqNo + 1) < INT_MAX)
					ShmOCPP20Data->TransactionEvent[gun_index].seqNo++;
				else
					ShmOCPP20Data->TransactionEvent[gun_index].seqNo = 0;

				ShmOCPP20Data->TransactionEvent[gun_index].offline = (!ShmOCPP20Data->OcppConnStatus?TRUE:FALSE);

				ShmOCPP20Data->TransactionEvent[gun_index].evse.id = (gun_index + 1);
				ShmOCPP20Data->TransactionEvent[gun_index].evse.connectorId = (gun_index + 1);

				if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_IDLE)//S_IDLE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Idle]);

					if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ConnectorPlugIn == ON) // //0: unplug, 1: Plug-in
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_CablePluggedIn]);
					}
					else
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_EVCommunicationLost]);
					}
				}
				else if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_AUTHORIZING)//S_IDLE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Idle]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_Authorized]);
				}
				else if ( ((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus >= SYS_MODE_PREPARING)&&( ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus <= SYS_MODE_PREPARE_FOR_EVSE)) ||
				          ((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0) && ( ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1) )
						) //S_PRECHARGE
				{
					if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId) == 0)
					{
						random_uuid((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, "%s", ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].StartUserId);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.type, "%s", IdTokenEnumTypeStr[ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].StartIdType]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					}
					else
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					}

					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_EVConnected]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_CHARGING) //S_CHARGING
				{
					if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId) == 0)
					{
						if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].StartMethod == 2)
						{
							ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.remoteStartId = ShmOCPP20Data->RequestStartTransaction[index].remoteStartId;
							sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId, (char*)ShmOCPP20Data->RequestStartTransaction[index].Response_transactionId);
						}
						else
							random_uuid((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId);

						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, "%s", ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].StartUserId);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.type, "%s", IdTokenEnumTypeStr[ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].StartIdType]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
					}
					else
					{
						storeTempStopTransaction(gun_index);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_MeterValuePeriodic]);
					}
				}
				else if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_COMPLETE) //S_COMPLETE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Ended]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
					if((access(TempStopTransaction,F_OK))!=-1)
					{
						remove(TempStopTransaction);  		// remove file "TempStopTransaction"
					}
				}
				else if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_TERMINATING) // S_TERMINATING   ---> SuspendedEV
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEV]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if ((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_MAINTAIN)|| (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //  ---> Unavailable
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);
				}
				else if ((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_FAULT)|| (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_ALARM)) //S_ALARM,S_FAULT   ---> Faulted
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_RESERVATION) //    ---> Reserved
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);
				}
			} //end of the same index

		}//end of for CHAdeMO_QUANTITY

	}
	else if(gunType[gun_index] == GUN_TYPE_CCS)
	{
		if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
		{
			tempIndex = ((gun_index==2) ? 1: 0);
		}
		else
		{
			tempIndex = gun_index;
		}

		for (int index = 0; index < CCS_QUANTITY; index++)
		{
			if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
			{
				getNowDatetime(ShmOCPP20Data->TransactionEvent[gun_index].timestamp);

				if((ShmOCPP20Data->TransactionEvent[gun_index].seqNo + 1) < INT_MAX)
					ShmOCPP20Data->TransactionEvent[gun_index].seqNo++;
				else
					ShmOCPP20Data->TransactionEvent[gun_index].seqNo = 0;

				ShmOCPP20Data->TransactionEvent[gun_index].offline = (!ShmOCPP20Data->OcppConnStatus?TRUE:FALSE);

				ShmOCPP20Data->TransactionEvent[gun_index].evse.id = (gun_index + 1);
				ShmOCPP20Data->TransactionEvent[gun_index].evse.connectorId = (gun_index + 1);

				if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_IDLE) //S_IDLE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Idle]);

					if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ConnectorPlugIn == ON) //0: unplug, 1: Plug-in
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_CablePluggedIn]);
					}
					else
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_EVCommunicationLost]);
					}
				}
				else if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_AUTHORIZING)//S_IDLE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Idle]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_Authorized]);
				}
				else if ( ((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus >= SYS_MODE_PREPARING)&&( ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus <= SYS_MODE_PREPARE_FOR_EVSE)) ||
				          ((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0) && ( ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1) )
						) //S_PRECHARGE
				{
					if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId) == 0)
					{
						random_uuid((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, "%s", ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].StartUserId);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.type, "%s", IdTokenEnumTypeStr[ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].StartIdType]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					}
					else
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					}

					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_EVConnected]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_CHARGING) //S_CHARGING
				{
					if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId) == 0)
					{
						if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].StartMethod == 2)
						{
							ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.remoteStartId = ShmOCPP20Data->RequestStartTransaction[index].remoteStartId;
							sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId, (char*)ShmOCPP20Data->RequestStartTransaction[index].Response_transactionId);
						}
						else
							random_uuid((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId);

						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, "%s", ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].StartUserId);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.type, "%s", IdTokenEnumTypeStr[ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].StartIdType]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
					}
					else
					{
						storeTempStopTransaction(gun_index);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_MeterValuePeriodic]);
					}
				}
				else if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_COMPLETE) //S_COMPLETE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Ended]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
					if((access(TempStopTransaction,F_OK))!=-1)
					{
						remove(TempStopTransaction);  		// remove file "TempStopTransaction"
					}
				}
				else if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_TERMINATING) // S_TERMINATING   ---> SuspendedEV
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEV]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if ((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_MAINTAIN)|| (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //  ---> Unavailable
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);
				}
				else if ((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_FAULT)|| (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_ALARM)) //S_ALARM,S_FAULT   ---> Faulted
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_RESERVATION) //    ---> Reserved
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);
				}
			} //end of the same index

		} // end of for CCS_QUANTITY
	}
	else if(gunType[gun_index] == GUN_TYPE_GBT)
	{
		if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
		{
			tempIndex = ((gun_index==2) ? 1: 0);
		}
		else
		{
			tempIndex = gun_index;
		}

		for (int index = 0; index < GB_QUANTITY; index++)
		{
			if(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex)
			{
				getNowDatetime(ShmOCPP20Data->TransactionEvent[gun_index].timestamp);

				if((ShmOCPP20Data->TransactionEvent[gun_index].seqNo + 1) < INT_MAX)
					ShmOCPP20Data->TransactionEvent[gun_index].seqNo++;
				else
					ShmOCPP20Data->TransactionEvent[gun_index].seqNo = 0;

				ShmOCPP20Data->TransactionEvent[gun_index].offline = (!ShmOCPP20Data->OcppConnStatus?TRUE:FALSE);

				ShmOCPP20Data->TransactionEvent[gun_index].evse.id = (gun_index + 1);
				ShmOCPP20Data->TransactionEvent[gun_index].evse.connectorId = (gun_index + 1);

				if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_IDLE) //S_IDLE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Idle]);

					if(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ConnectorPlugIn == ON) //0: unplug, 1: Plug-in
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_CablePluggedIn]);
					}
					else
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_EVCommunicationLost]);
					}
				}
				else if(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_AUTHORIZING)//S_IDLE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Idle]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_Authorized]);
				}
				else if ( ((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus >= SYS_MODE_PREPARING)&&( ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus <= SYS_MODE_PREPARE_FOR_EVSE)) ||
				          ((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0) && ( ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1) )
						) //S_PRECHARGE
				{
					if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId) == 0)
					{
						random_uuid((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, "%s", ShmSysConfigAndInfo->SysInfo.GbChargingData[index].StartUserId);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.type, "%s", IdTokenEnumTypeStr[ShmSysConfigAndInfo->SysInfo.GbChargingData[index].StartIdType]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					}
					else
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					}

					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_EVConnected]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_CHARGING) //S_CHARGING
				{
					if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId) == 0)
					{
						if(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].StartMethod == 2)
						{
							ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.remoteStartId = ShmOCPP20Data->RequestStartTransaction[index].remoteStartId;
							sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId, (char*)ShmOCPP20Data->RequestStartTransaction[index].Response_transactionId);
						}
						else
							random_uuid((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId);

						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, "%s", ShmSysConfigAndInfo->SysInfo.GbChargingData[index].StartUserId);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.type, "%s", IdTokenEnumTypeStr[ShmSysConfigAndInfo->SysInfo.GbChargingData[index].StartIdType]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
					}
					else
					{
						storeTempStopTransaction(gun_index);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_MeterValuePeriodic]);
					}
				}
				else if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_COMPLETE) //S_COMPLETE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Ended]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
					if((access(TempStopTransaction,F_OK))!=-1)
					{
						remove(TempStopTransaction);  		// remove file "TempStopTransaction"
					}
				}
				else if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_TERMINATING) // S_TERMINATING   ---> SuspendedEV
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEV]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if ((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_MAINTAIN)|| (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //  ---> Unavailable
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);
				}
				else if ((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_FAULT)|| (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_ALARM)) //S_ALARM,S_FAULT   ---> Faulted
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_RESERVATION) //    ---> Reserved
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);
				}
			} //end of the same index

		} // end of for GB_QUANTITY
	}
	else if(gunType[gun_index] == GUN_TYPE_DO)
	{
		tempIndex = gun_index;

		for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
		{
			if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
			{
				getNowDatetime(ShmOCPP20Data->TransactionEvent[gun_index].timestamp);

				if((ShmOCPP20Data->TransactionEvent[gun_index].seqNo + 1) < INT_MAX)
					ShmOCPP20Data->TransactionEvent[gun_index].seqNo++;
				else
					ShmOCPP20Data->TransactionEvent[gun_index].seqNo = 0;

				ShmOCPP20Data->TransactionEvent[gun_index].offline = (!ShmOCPP20Data->OcppConnStatus?TRUE:FALSE);

				ShmOCPP20Data->TransactionEvent[gun_index].evse.id = (gun_index + 1);
				ShmOCPP20Data->TransactionEvent[gun_index].evse.connectorId = (gun_index + 1);

				if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_IDLE) //S_IDLE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Idle]);

					if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ConnectorPlugIn == ON) // //0: unplug, 1: Plug-in
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_CablePluggedIn]);
					}
					else
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_EVCommunicationLost]);
					}
				}
				else if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_AUTHORIZING)//S_IDLE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Idle]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_Authorized]);
				}
				else if ( ((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus >= SYS_MODE_PREPARING)&&( ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus <= SYS_MODE_PREPARE_FOR_EVSE)) ||
				          ((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0) && ( ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1) )
						) //S_PRECHARGE
				{
					if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId) == 0)
					{
						random_uuid((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, "%s", ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.StartUserId);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.type, "%s", IdTokenEnumTypeStr[ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.StartIdType]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					}
					else
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					}

					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_EVConnected]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_CHARGING) //S_CHARGING
				{
					if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId) == 0)
					{
						if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.StartMethod == 2)
						{
							ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.remoteStartId = ShmOCPP20Data->RequestStartTransaction[index].remoteStartId;
							sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId, (char*)ShmOCPP20Data->RequestStartTransaction[index].Response_transactionId);
						}
						else
							random_uuid((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId);

						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, "%s", ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.StartUserId);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.type, "%s", IdTokenEnumTypeStr[ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.StartIdType]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
					}
					else
					{
						storeTempStopTransaction(gun_index);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_MeterValuePeriodic]);
					}
				}
				else if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_COMPLETE) //S_COMPLETE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Ended]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
					if((access(TempStopTransaction,F_OK))!=-1)
					{
						remove(TempStopTransaction);  		// remove file "TempStopTransaction"
					}
				}
				else if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_TERMINATING) // S_TERMINATING   ---> SuspendedEV
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEV]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if ((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_MAINTAIN)|| (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_UPDATE)) //  ---> Unavailable
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);
				}
				else if ((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_FAULT)|| (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_ALARM)) //S_ALARM,S_FAULT   ---> Faulted
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_RESERVATION) //    ---> Reserved
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);
				}
			} //end of the same index
		}
	}
	else
	{
		if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
		{
			tempIndex = 2;
		}
		else
		{
			tempIndex = gun_index;
		}

		for (int index = 0; index < AC_QUANTITY; index++)
		{
			if(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
			{
				getNowDatetime(ShmOCPP20Data->TransactionEvent[gun_index].timestamp);

				if((ShmOCPP20Data->TransactionEvent[gun_index].seqNo + 1) < INT_MAX)
					ShmOCPP20Data->TransactionEvent[gun_index].seqNo++;
				else
					ShmOCPP20Data->TransactionEvent[gun_index].seqNo = 0;

				ShmOCPP20Data->TransactionEvent[gun_index].offline = (!ShmOCPP20Data->OcppConnStatus?TRUE:FALSE);

				ShmOCPP20Data->TransactionEvent[gun_index].evse.id = (gun_index + 1);
				ShmOCPP20Data->TransactionEvent[gun_index].evse.connectorId = (gun_index + 1);

				if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_IDLE) //SYS_MODE_IDLE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Idle]);

					if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState == CP_STATE_B) ||(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState == CP_STATE_C) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState == CP_STATE_D))
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_CablePluggedIn]);
					}
					else
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_EVCommunicationLost]);
					}
				}
				else if(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_AUTHORIZING)//S_IDLE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Idle]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_Authorized]);
				}
				else if ( ((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus >= SYS_MODE_PREPARING)&&( ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus <= SYS_MODE_PREPARE_FOR_EVSE)) ||
				          ((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0) && ( ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1) )
						) //S_PRECHARGE
				{
					if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId) == 0)
					{
						random_uuid((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, "%s", ShmSysConfigAndInfo->SysInfo.AcChargingData[index].StartUserId);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.type, "%s", IdTokenEnumTypeStr[ShmSysConfigAndInfo->SysInfo.AcChargingData[index].StartIdType]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					}
					else
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					}

					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_EVConnected]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_CHARGING) //S_CHARGING
				{
					if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId) == 0)
					{
						if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod == 2)
						{
							ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.remoteStartId = ShmOCPP20Data->RequestStartTransaction[index].remoteStartId;
							sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId, (char*)ShmOCPP20Data->RequestStartTransaction[index].Response_transactionId);
						}
						else
							random_uuid((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId);

						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken, "%s", ShmSysConfigAndInfo->SysInfo.AcChargingData[index].StartUserId);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.type, "%s", IdTokenEnumTypeStr[ShmSysConfigAndInfo->SysInfo.AcChargingData[index].StartIdType]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
					}
					else
					{
						storeTempStopTransaction(gun_index);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
						sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_MeterValuePeriodic]);
					}
				}
				else if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_COMPLETE) //S_COMPLETE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Ended]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
					if((access(TempStopTransaction,F_OK))!=-1)
					{
						remove(TempStopTransaction);  		// remove file "TempStopTransaction"
					}
				}
				else if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_TERMINATING) // S_TERMINATING   ---> SuspendedEV
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEV]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if ((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_MAINTAIN)|| (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //  ---> Unavailable
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);
				}
				else if ((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_FAULT)|| (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_ALARM)) //S_ALARM,S_FAULT   ---> Faulted
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_RESERVATION) //    ---> Reserved
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);
				}
			}//end of the same index
		}//end of for AC_QUANTITY
	}

	// Message
	json_object_object_add(TransactionEvent, "eventType", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType));
	json_object_object_add(TransactionEvent, "timestamp", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].timestamp));
	json_object_object_add(TransactionEvent, "triggerReason", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason));
	json_object_object_add(TransactionEvent, "seqNo", json_object_new_int(ShmOCPP20Data->TransactionEvent[gun_index].seqNo));
	json_object_object_add(TransactionEvent, "offline", json_object_new_boolean(ShmOCPP20Data->TransactionEvent[gun_index].offline));

	if(ShmOCPP20Data->TransactionEvent[gun_index].numberOfPhasesUsed > 0)
		json_object_object_add(TransactionEvent, "numberOfPhasesUsed", json_object_new_int(ShmOCPP20Data->TransactionEvent[gun_index].numberOfPhasesUsed));

	if(ShmOCPP20Data->TransactionEvent[gun_index].cableMaxCurrent > 0)
		json_object_object_add(TransactionEvent, "cableMaxCurrent", json_object_new_double(ShmOCPP20Data->TransactionEvent[gun_index].cableMaxCurrent));

	if(ShmOCPP20Data->TransactionEvent[gun_index].reservationId > 0)
		json_object_object_add(TransactionEvent, "reservationId", json_object_new_int(ShmOCPP20Data->TransactionEvent[gun_index].reservationId));


	json_object_object_add(transactionInfo, "transactionId", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId));
	json_object_object_add(transactionInfo, "chargingState", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState));

	if(ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.timeSpentCharging > 0)
		json_object_object_add(transactionInfo, "timeSpentCharging", json_object_new_int(ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.timeSpentCharging));

	if((strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason) > 0) && (strstr((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, TransactionEventEnumTypeStr[TransactionEventEnumType_Ended]) != NULL))
		json_object_object_add(transactionInfo, "stoppedReason", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason));

	//if(ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.remoteStartId > 0)
	if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod == 2)
		json_object_object_add(transactionInfo, "remoteStartId", json_object_new_int(ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.remoteStartId));

	json_object_object_add(TransactionEvent, "transactionInfo", transactionInfo);


	if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken) > 0)
	{
		json_object_object_add(idToken, "idToken", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken));
		json_object_object_add(idToken, "type", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.type));
		json_object_object_add(TransactionEvent, "idToken", idToken);
	}

	json_object_object_add(evse, "id", json_object_new_int(ShmOCPP20Data->TransactionEvent[gun_index].evse.id));
	json_object_object_add(evse, "connectorId", json_object_new_int(ShmOCPP20Data->TransactionEvent[gun_index].evse.connectorId));
	json_object_object_add(TransactionEvent, "evse", evse);


	if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[0].timestamp) > 0)
	{
		for(int idxMeter=0;idxMeter<ARRAY_SIZE(ShmOCPP20Data->TransactionEvent[gun_index].meterValue);idxMeter++)
		{
			json_object *meterValue = json_object_new_object();
			json_object *sampledValues = json_object_new_array();

			json_object_object_add(meterValue, "timestamp", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].timestamp));

			for(int idxSample=0;idxSample<ARRAY_SIZE(ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue);idxSample++)
			{
				if((strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].context) > 0) &&
				   ((strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].phase) > 0) || (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].measurand, MeasurandEnumTypeStr[MeasurandEnumType_SoC]) == 0) || (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].measurand, MeasurandEnumTypeStr[MeasurandEnumType_Current_Offered]) == 0) || (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].measurand, MeasurandEnumTypeStr[MeasurandEnumType_Power_Offered]) == 0)))
				{
					if(((strstr((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, TransactionEventEnumTypeStr[TransactionEventEnumType_Ended]) != NULL) && (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].variableAttribute[0].value, (char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].measurand) != NULL)) ||
						(strstr((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, TransactionEventEnumTypeStr[TransactionEventEnumType_Ended]) == NULL))
					{
						json_object *sampledValue = json_object_new_object();

						json_object_object_add(sampledValue, "value", json_object_new_double(ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].value));

						if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].context) > 0)
							json_object_object_add(sampledValue, "context", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].context));

						if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].measurand) > 0)
							json_object_object_add(sampledValue, "measurand", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].measurand));

						if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].phase) > 0)
							json_object_object_add(sampledValue, "phase", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].phase));

						if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].location) > 0)
							json_object_object_add(sampledValue, "location", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].location));

						if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].unitOfMeasure.uint) > 0)
						{
							json_object *unitOfMeasure = json_object_new_object();

							json_object_object_add(unitOfMeasure, "unit", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].unitOfMeasure.uint));
							json_object_object_add(unitOfMeasure, "multiplier", json_object_new_int(ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].unitOfMeasure.multiplier));
							json_object_object_add(sampledValue, "unitOfMeasure", unitOfMeasure);
						}

						json_object_array_add(sampledValues, sampledValue);
					}
				}
			}
			json_object_object_add(meterValue, "sampledValue", sampledValues);

			json_object_array_add(meterValues, meterValue);
		}
		json_object_object_add(TransactionEvent, "meterValue", meterValues);
	}

	random_uuid(guid);
	sprintf(message,"[%d,\"%s\",\"%s\",%s]",MESSAGE_TYPE_CALL, guid, "TransactionEvent", json_object_to_json_string_ext(TransactionEvent, JSON_C_TO_STRING_PLAIN));
	json_object_put(TransactionEvent);

	sprintf(tempdata, "TransactionEvent,%d", gun_index);
	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;
	}

	queue_operation(QUEUE_OPERATION_ADD, guid, message);
	if(strstr((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, TransactionEventEnumTypeStr[TransactionEventEnumType_Started]) != NULL)
		OCPP_insert_transaction_msg(YES, message);
	else if(strstr((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, TransactionEventEnumTypeStr[TransactionEventEnumType_Ended]) != NULL)
	{
		OCPP_insert_transaction_msg(NO, message);
		memset(&ShmOCPP20Data->SessionTarget[gun_index], 0x00, sizeof(struct StructSessionTarget));
		memset(&ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo, 0x00, sizeof(struct TransactionType));
		memset(&ShmOCPP20Data->TransactionEvent[gun_index].idToken, 0x00, sizeof(struct IdTokenType));
		memset(&ShmOCPP20Data->TransactionEvent[gun_index].meterValue, 0x00, sizeof(struct MeterValueType));
	}

	return result;
}

//==========================================
// send confirm routine
//==========================================
int sendCancelReservationConfirmation(char *uuid, unsigned char gun_index)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *CancelReservation = json_object_new_object();

	DEBUG_INFO("sendCancelReservationConfirmation...\n");

	json_object_object_add(CancelReservation, "status", json_object_new_string((char*)ShmOCPP20Data->CancelReservation[gun_index].Response_status));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(CancelReservation, JSON_C_TO_STRING_PLAIN));
	json_object_put(CancelReservation);
	ShmOCPP20Data->CsMsg.bits[gun_index].CancelReservationConf = OFF;
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendCertificateSignedConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *CertificateSigned = json_object_new_object();
	json_object *statusInfo = json_object_new_object();

	DEBUG_INFO("sendCertificateSignedConfirmation...\n");

	json_object_object_add(CertificateSigned, "status", json_object_new_string((char*)ShmOCPP20Data->CertificateSigned.Response_status));

	if(strlen((char*)ShmOCPP20Data->CertificateSigned.Response_statusInfo.reasonCode) > 0)
	{
		json_object_object_add(statusInfo, "reasonCode", json_object_new_string((char*)ShmOCPP20Data->CertificateSigned.Response_statusInfo.reasonCode));

		if(strlen((char*)ShmOCPP20Data->CertificateSigned.Response_statusInfo.additionalInfo) > 0)
			json_object_object_add(statusInfo, "statadditionalInfous", json_object_new_string((char*)ShmOCPP20Data->CertificateSigned.Response_statusInfo.additionalInfo));
	}
	json_object_object_add(CertificateSigned, "statusInfo", statusInfo);

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(CertificateSigned, JSON_C_TO_STRING_PLAIN));
	json_object_put(CertificateSigned);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendChangeAvailabilityConfirmation(char *uuid, unsigned char gun_index)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *ChangeAvailability = json_object_new_object();

	DEBUG_INFO("sendChangeAvailabilityConfirmation...\n");

	json_object_object_add(ChangeAvailability, "status", json_object_new_string((char*)ShmOCPP20Data->ChangeAvailability[gun_index].Response_status));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(ChangeAvailability, JSON_C_TO_STRING_PLAIN));
	json_object_put(ChangeAvailability);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendClearCacheConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
    char message[4096]={0};
    json_object *ClearCache = json_object_new_object();

    DEBUG_INFO("sendClearCacheConfirmation...\n");

	json_object_object_add(ClearCache, "status", json_object_new_string((char*)ShmOCPP20Data->ClearCache.Response_status));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(ClearCache, JSON_C_TO_STRING_PLAIN));
	json_object_put(ClearCache);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendClearChargingProfileConfirmation(char *uuid,char *payload)
{
	mtrace();
	int result = FAIL;
	char message[500]={0};

	DEBUG_INFO("sendClearChargingProfileConfirmation...\n");
	sprintf(message,"[%d,\"%s\",{\"%s\":\"%s\"}]",MESSAGE_TYPE_CALLRESULT, uuid, "status", payload);
	LWS_Send(message);

	return result;
}

int sendClearDisplayMessageConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *ClearDisplayMessage = json_object_new_object();

	DEBUG_INFO("sendClearDisplayMessageConfirmation...\n");

	json_object_object_add(ClearDisplayMessage, "status", json_object_new_string((char*)ShmOCPP20Data->ClearDisplayMessage.Response_status));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(ClearDisplayMessage, JSON_C_TO_STRING_PLAIN));
	json_object_put(ClearDisplayMessage);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendClearVariableMonitoringConfirmation(char *uuid, unsigned char variableQuantity)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *ClearVariableMonitoring = json_object_new_object();
	json_object *clearMonitoringResults = json_object_new_array();

	DEBUG_INFO("sendClearVariableMonitoringConfirmation...\n");

	for(int idx=0;idx<variableQuantity;idx++)
	{
		json_object *clearMonitoringResult = json_object_new_object();

		json_object_object_add(clearMonitoringResult, "id", json_object_new_int(ShmOCPP20Data->ClearVariableMonitoring.Response_clearMonitoringResult[idx].id));
		json_object_object_add(clearMonitoringResult, "status", json_object_new_string((char*)ShmOCPP20Data->ClearVariableMonitoring.Response_clearMonitoringResult[idx].status));

		json_object_array_add(clearMonitoringResults, clearMonitoringResult);
	}
	json_object_object_add(ClearVariableMonitoring, "clearMonitoringResult", clearMonitoringResults);

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(ClearVariableMonitoring, JSON_C_TO_STRING_PLAIN));
	json_object_put(ClearVariableMonitoring);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendCostUpdatedConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};

	DEBUG_INFO("sendCostUpdatedConfirmation...\n");


	sprintf(message,"[%d,\"%s\",{}]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid);

	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendCustomerInformationConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *CustomerInformation = json_object_new_object();

	DEBUG_INFO("sendCustomerInformationConfirmation...\n");

	json_object_object_add(CustomerInformation, "status", json_object_new_string((char*)ShmOCPP20Data->CustomerInformation.Response_status));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(CustomerInformation, JSON_C_TO_STRING_PLAIN));
	json_object_put(CustomerInformation);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendDataTransferConfirmation(char *uuid, unsigned char gun_index)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *DataTransfer = json_object_new_object();

	DEBUG_INFO("sendDataTransferConfirmation...\n");

	json_object_object_add(DataTransfer, "status", json_object_new_string((char*)ShmOCPP20Data->DataTransfer[gun_index].Response_status));
	json_object_object_add(DataTransfer, "data", json_object_new_string((char*)ShmOCPP20Data->DataTransfer[gun_index].Response_data));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(DataTransfer, JSON_C_TO_STRING_PLAIN));
	json_object_put(DataTransfer);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendDeleteCertificateConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *DeleteCertificate = json_object_new_object();

	DEBUG_INFO("sendDeleteCertificateConfirmation...\n");

	json_object_object_add(DeleteCertificate, "status", json_object_new_string((char*)ShmOCPP20Data->DeleteCertificate.Response_status));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(DeleteCertificate, JSON_C_TO_STRING_PLAIN));
	json_object_put(DeleteCertificate);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendGetBaseReportConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *GetBaseReport = json_object_new_object();


	DEBUG_INFO("sendGetBaseReportConfirmation...\n");

	json_object_object_add(GetBaseReport, "status", json_object_new_string((char*)ShmOCPP20Data->GetBaseReport.Response_status));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(GetBaseReport, JSON_C_TO_STRING_PLAIN));
	json_object_put(GetBaseReport);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendGetChargingProfilesConfirmation(char *uuid, unsigned char gun_index)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *GetChargingProfiles = json_object_new_object();


	DEBUG_INFO("sendGetChargingProfilesConfirmation...\n");

	json_object_object_add(GetChargingProfiles, "status", json_object_new_string((char*)ShmOCPP20Data->GetChargingProfiles[gun_index].Response_status));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(GetChargingProfiles, JSON_C_TO_STRING_PLAIN));
	json_object_put(GetChargingProfiles);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendGetCompositeScheduleConfirmation(char *uuid, char *payload, int connectorIdInt, int nPeriod)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	int CompositeScheduleIndex = 0;
	json_object *GetCompositeSchedule = json_object_new_object();
	json_object *schedule = json_object_new_object();
	json_object *chargingSchedule = json_object_new_object();
	json_object *chargingSchedulePeriod = json_object_new_array();

	DEBUG_INFO("sendGetCompositeScheduleConfirmation...\n");

	json_object_object_add(GetCompositeSchedule, "status", json_object_new_string(payload));

  	CompositeScheduleIndex = (connectorIdInt > 0) ?(connectorIdInt -1) : 0;
  	json_object_object_add(chargingSchedule, "evseId", json_object_new_int(CompositeScheduleIndex));
	if(nPeriod == 0)
	{
		if(strcmp((const char *)ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.startDateTime,"")!=0)
		{
			if(strlen((char*)ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.startSchedule))
				json_object_object_add(schedule, "scheduleStart", json_object_new_string((char*)ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.startSchedule));

			if(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.duration > 0)
				json_object_object_add(schedule, "duration", json_object_new_int(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.duration));

			json_object_object_add(schedule, "chargingRateUnit", json_object_new_string((char*)ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingRateUnit));

			//if(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.minChargingRate > 0)
				//json_object_object_add(chargingSchedule, "minChargingRate", json_object_new_double(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.minChargingRate));

			//json_object_object_add(chargingSchedule, "id", json_object_new_int(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.id));

			for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingSchedulePeriod);idxPeriod++)
			{
				if(((ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingSchedulePeriod[idxPeriod].startPeriod == 0) && (ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingSchedulePeriod[idxPeriod].limit>0)) ||
				   (ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingSchedulePeriod[idxPeriod].startPeriod > 0))
				{
					json_object *Period = json_object_new_object();
					json_object_object_add(Period, "startPeriod", json_object_new_int(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingSchedulePeriod[idxPeriod].startPeriod));
					json_object_object_add(Period, "limit", json_object_new_double(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingSchedulePeriod[idxPeriod].limit));

					if(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingSchedulePeriod[idxPeriod].numberPhases > 0)
						json_object_object_add(Period, "numberPhases", json_object_new_int(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingSchedulePeriod[idxPeriod].numberPhases));
					if(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingSchedulePeriod[idxPeriod].phaseToUse > 0)
						json_object_object_add(Period, "phaseToUse", json_object_new_int(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingSchedulePeriod[idxPeriod].phaseToUse));

					json_object_array_add(chargingSchedulePeriod, Period);
				}
			}
			json_object_object_add(schedule, "chargingSchedulePeriod", chargingSchedulePeriod);

			//json_object_object_add(schedule, "startDateTime", json_object_new_string((char*)ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.startDateTime));
			//json_object_object_add(schedule, "chargingSchedule", chargingSchedule);
			json_object_object_add(GetCompositeSchedule, "schedule", schedule);
		}
	}
	else
	{
		if(strlen((char*)ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.startSchedule))
			json_object_object_add(chargingSchedule, "scheduleStart", json_object_new_string((char*)ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.startSchedule));

		if(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.duration > 0)
			json_object_object_add(chargingSchedule, "duration", json_object_new_int(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.duration));

		json_object_object_add(chargingSchedule, "chargingRateUnit", json_object_new_string((char*)ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingRateUnit));

		if(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.minChargingRate > 0)
			json_object_object_add(chargingSchedule, "minChargingRate", json_object_new_double(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.minChargingRate));

		json_object_object_add(chargingSchedule, "id", json_object_new_int(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.id));

		for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingSchedulePeriod);idxPeriod++)
		{
			if(((ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingSchedulePeriod[idxPeriod].startPeriod == 0) && (ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingSchedulePeriod[idxPeriod].limit>0)) ||
			   (ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingSchedulePeriod[idxPeriod].startPeriod > 0))
			{
				json_object *Period = json_object_new_object();
				json_object_object_add(Period, "startPeriod", json_object_new_int(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingSchedulePeriod[idxPeriod].startPeriod));
				json_object_object_add(Period, "limit", json_object_new_double(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingSchedulePeriod[idxPeriod].limit));

				if(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingSchedulePeriod[idxPeriod].numberPhases > 0)
					json_object_object_add(Period, "numberPhases", json_object_new_int(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingSchedulePeriod[idxPeriod].numberPhases));
				if(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingSchedulePeriod[idxPeriod].phaseToUse > 0)
					json_object_object_add(Period, "phaseToUse", json_object_new_int(ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.chargingSchedulePeriod[idxPeriod].phaseToUse));

				json_object_array_add(chargingSchedulePeriod, Period);
			}
		}
		json_object_object_add(chargingSchedule, "chargingSchedulePeriod", chargingSchedulePeriod);

		json_object_object_add(schedule, "startDateTime", json_object_new_string((char*)ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.startDateTime));
		json_object_object_add(schedule, "chargingSchedule", chargingSchedule);
		json_object_object_add(GetCompositeSchedule, "schedule", schedule);
	}

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(GetCompositeSchedule, JSON_C_TO_STRING_PLAIN));
	json_object_put(GetCompositeSchedule);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendGetGetDisplayMessagesConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *GetGetDisplayMessages = json_object_new_object();

	DEBUG_INFO("sendGetGetDisplayMessagesConfirmation...\n");

	json_object_object_add(GetGetDisplayMessages, "status", json_object_new_string((char*)ShmOCPP20Data->GetDisplayMessages.Response_status));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(GetGetDisplayMessages, JSON_C_TO_STRING_PLAIN));
	json_object_put(GetGetDisplayMessages);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendGetInstalledCertificateIdsConfirmation(char *uuid, unsigned char certQuantity)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *GetInstalledCertificateIds = json_object_new_object();
	json_object *certificateHashDataChains = json_object_new_array();

	DEBUG_INFO("sendGetInstalledCertificateIdsConfirmation...\n");

	json_object_object_add(GetInstalledCertificateIds, "status", json_object_new_string((char*)ShmOCPP20Data->GetInstalledCertificateIds.Response_status));

	for(int idx=0;idx<certQuantity;idx++)
	{
		json_object *cert = json_object_new_object();
		json_object *certificateHashData = json_object_new_object();

		json_object_object_add(certificateHashData, "hashAlgorithm", json_object_new_string((char*)ShmOCPP20Data->GetInstalledCertificateIds.Response_certificateHashDataChain[idx].certificateHashData.hashAlgorithm));
		json_object_object_add(certificateHashData, "issuerNameHash", json_object_new_string((char*)ShmOCPP20Data->GetInstalledCertificateIds.Response_certificateHashDataChain[idx].certificateHashData.issuerNameHash));
		json_object_object_add(certificateHashData, "issuerKeyHash", json_object_new_string((char*)ShmOCPP20Data->GetInstalledCertificateIds.Response_certificateHashDataChain[idx].certificateHashData.issuerKeyHash));
		json_object_object_add(certificateHashData, "serialNumber", json_object_new_string((char*)ShmOCPP20Data->GetInstalledCertificateIds.Response_certificateHashDataChain[idx].certificateHashData.serialNumber));

		json_object_object_add(cert, "certificateHashData", certificateHashData);
		json_object_object_add(cert, "certificateType", json_object_new_string((char*)ShmOCPP20Data->GetInstalledCertificateIds.Response_certificateHashDataChain[idx].certificateType));

		json_object_array_add(certificateHashDataChains, cert);
	}
	json_object_object_add(GetInstalledCertificateIds , "certificateHashDataChain", certificateHashDataChains);

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(GetInstalledCertificateIds, JSON_C_TO_STRING_PLAIN));
	json_object_put(GetInstalledCertificateIds);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendGetLocalListVersionConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *GetLocalListVersion = json_object_new_object();

	DEBUG_INFO("sendGetLocalListVersionConfirmation...\n");

	json_object_object_add(GetLocalListVersion, "versionNumber", json_object_new_int(ShmOCPP20Data->GetLocalListVersion.Response_versionNumber));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(GetLocalListVersion, JSON_C_TO_STRING_PLAIN));
	json_object_put(GetLocalListVersion);
	LWS_Send(message);
	result = TRUE;

	return result;
}

int sendGetLogConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *GetLog = json_object_new_object();

	DEBUG_INFO("sendGetLogConfirmation...\n");

	json_object_object_add(GetLog, "status", json_object_new_string((char*)ShmOCPP20Data->GetLog.Response_status));
	json_object_object_add(GetLog, "filename", json_object_new_string((char*)ShmOCPP20Data->GetLog.Response_filename));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(GetLog, JSON_C_TO_STRING_PLAIN));
	json_object_put(GetLog);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendGetMonitoringReportConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *GetMonitoringReport = json_object_new_object();

	DEBUG_INFO("sendGetMonitoringReportConfirmation...\n");

	json_object_object_add(GetMonitoringReport, "status", json_object_new_string((char*)ShmOCPP20Data->GetMonitoringReport.Response_status));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(GetMonitoringReport, JSON_C_TO_STRING_PLAIN));
	json_object_put(GetMonitoringReport);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendGetReportConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *GetReport = json_object_new_object();

	DEBUG_INFO("sendGetReportConfirmation...\n");

	json_object_object_add(GetReport, "status", json_object_new_string((char*)ShmOCPP20Data->GetReport.Response_status));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(GetReport, JSON_C_TO_STRING_PLAIN));
	json_object_put(GetReport);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendGetTransactionStatusConfirmation(char *uuid, unsigned char gun_index)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *GetTransactionStatus = json_object_new_object();

	DEBUG_INFO("sendGetTransactionStatusConfirmation...\n");

	json_object_object_add(GetTransactionStatus, "ongoingIndicator", json_object_new_boolean(ShmOCPP20Data->GetTransactionStatus[gun_index].Response_ongoingIndicator));
	json_object_object_add(GetTransactionStatus, "messagesInQueue", json_object_new_boolean(ShmOCPP20Data->GetTransactionStatus[gun_index].Response_messagesInQueue));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(GetTransactionStatus, JSON_C_TO_STRING_PLAIN));
	json_object_put(GetTransactionStatus);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendGetVariablesConfirmation(char *uuid, unsigned char variableQuantity)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *GetVariables = json_object_new_object();
	json_object *getVariableResults = json_object_new_array();

	DEBUG_INFO("sendGetVariablesConfirmation...\n");

	for(int idx=0;idx<variableQuantity;idx++)
	{
		json_object *variableResult = json_object_new_object();
		json_object *component = json_object_new_object();
		json_object *variable = json_object_new_object();
		json_object *evse = json_object_new_object();

		if(strlen((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeType) > 0)
			json_object_object_add(variableResult, "attributeType", json_object_new_string((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeType));
		json_object_object_add(variableResult, "attributeStatus", json_object_new_string((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeStatus));
		if(strlen((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeValue) > 0)
			json_object_object_add(variableResult, "attributeValue", json_object_new_string((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeValue));

		json_object_object_add(evse, "id", json_object_new_int(ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].component.evse.id));
		json_object_object_add(evse, "connectorId", json_object_new_int(ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].component.evse.connectorId));
		json_object_object_add(component, "evse", evse);
		json_object_object_add(component, "name", json_object_new_string((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].component.name));
		if(strlen((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].component.instance) > 0)
			json_object_object_add(component, "instance", json_object_new_string((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].component.instance));
		json_object_object_add(variableResult, "component", component);

		json_object_object_add(variable, "name", json_object_new_string((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].variable.name));
		if(strlen((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].variable.instance) > 0)
			json_object_object_add(variable, "instance", json_object_new_string((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].variable.instance));
		json_object_object_add(variableResult, "variable", variable);

		json_object_array_add(getVariableResults, variableResult);
	}
	json_object_object_add(GetVariables , "getVariableResult", getVariableResults);

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(GetVariables, JSON_C_TO_STRING_PLAIN));
	json_object_put(GetVariables);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendInstallCertificateConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *InstallCertificate = json_object_new_object();


	DEBUG_INFO("sendInstallCertificateConfirmation...\n");

	json_object_object_add(InstallCertificate, "status", json_object_new_string((char*)ShmOCPP20Data->InstallCertificate.Response_status));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(InstallCertificate, JSON_C_TO_STRING_PLAIN));
	json_object_put(InstallCertificate);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendPublishFirmwareConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *PublishFirmware = json_object_new_object();

	json_object_object_add(PublishFirmware, "status", json_object_new_string((char*)ShmOCPP20Data->PublishFirmware.Response_status));

	DEBUG_INFO("sendPublishFirmwareConfirmation...\n");

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(PublishFirmware, JSON_C_TO_STRING_PLAIN));
	json_object_put(PublishFirmware);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendRemoteStartTransactionConfirmation(char *uuid, unsigned char gun_index)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *RemoteStartTransaction = json_object_new_object();

	json_object_object_add(RemoteStartTransaction, "status", json_object_new_string((char*)ShmOCPP20Data->RequestStartTransaction[gun_index].Response_status));

	if((strstr((char*)ShmOCPP20Data->RequestStartTransaction[gun_index].Response_status, RequestStartStopStatusEnumTypeStr[RequestStartStopStatusEnumType_Accepted]) != NULL) &&
	   (strlen((char*)ShmOCPP20Data->RequestStartTransaction[gun_index].Response_transactionId) > 0))
		json_object_object_add(RemoteStartTransaction, "transactionId", json_object_new_string((char*)ShmOCPP20Data->RequestStartTransaction[gun_index].Response_transactionId));

	DEBUG_INFO("sendRemoteStartConfirmation...\n");

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(RemoteStartTransaction, JSON_C_TO_STRING_PLAIN));
	json_object_put(RemoteStartTransaction);
	LWS_Send(message);
	result = TRUE;

	return result;
}

int sendRemoteStopTransactionConfirmation(char *uuid, unsigned char gun_index)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *RemoteStopTransaction = json_object_new_object();

	json_object_object_add(RemoteStopTransaction, "status", json_object_new_string((char*)ShmOCPP20Data->RequestStopTransaction[gun_index].Response_status));

	DEBUG_INFO("sendRemoteStopTransactionConfirmation...\n");

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(RemoteStopTransaction, JSON_C_TO_STRING_PLAIN));
	json_object_put(RemoteStopTransaction);
	LWS_Send(message);
	result = TRUE;

	return result;
}

int sendReserveNowConfirmation(char *uuid, unsigned char gun_index)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *ReserveNow = json_object_new_object();

	json_object_object_add(ReserveNow, "status", json_object_new_string((char*)ShmOCPP20Data->ReserveNow[gun_index].Response_status));

	DEBUG_INFO("sendReserveNowTransactionConfirmation...\n");
	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(ReserveNow, JSON_C_TO_STRING_PLAIN));
	json_object_put(ReserveNow);
	LWS_Send(message);
	result = TRUE;

	ShmOCPP20Data->CsMsg.bits[gun_index].ReserveNowConf = OFF;

	return result;
}

int sendResetConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *Reset = json_object_new_object();
	DEBUG_INFO("sendResetConfirmation...\n");

	ShmOCPP20Data->MsMsg.bits.ResetConf = OFF;

	json_object_object_add(Reset, "status", json_object_new_string((char*)ShmOCPP20Data->Reset.Response_status));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(Reset, JSON_C_TO_STRING_PLAIN));
	json_object_put(Reset);
	LWS_Send(message);

	if(strcmp((char*)ShmOCPP20Data->Reset.Response_status, ResetStatusEnumTypeStr[ResetStatusEnumType_Accepted]) == 0)
	{
		DB_updateBootType(BootReasonEnumType_RemoteReset);
		DB_updateSecurityEventType(SecurityEventEnumType_ResetOrReboot);
	}
	else if(strcmp((char*)ShmOCPP20Data->Reset.Response_status, ResetStatusEnumTypeStr[ResetStatusEnumType_Scheduled]) == 0)
	{
		DB_updateBootType(BootReasonEnumType_ScheduledReset);
		DB_updateSecurityEventType(SecurityEventEnumType_ResetOrReboot);
	}

	result = TRUE;

	return result;
}

int sendSendLocalListConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *SendLocalList = json_object_new_object();
	DEBUG_INFO("sendSendLocalListConfirmation...\n");

	json_object_object_add(SendLocalList, "status", json_object_new_string((char*)ShmOCPP20Data->SendLocalList.Response_status));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(SendLocalList, JSON_C_TO_STRING_PLAIN));
	json_object_put(SendLocalList);
	LWS_Send(message);
	result = TRUE;

	return result;
}

int sendSetChargingProfileConfirmation(char *uuid, unsigned char gun_index)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *SetChargingProfile = json_object_new_object();

	DEBUG_INFO("sendSetChargingProfileConfirmation...\n");

	json_object_object_add(SetChargingProfile, "status", json_object_new_string((char*)ShmOCPP20Data->SetChargingProfile[gun_index].Response_status));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(SetChargingProfile, JSON_C_TO_STRING_PLAIN));
	json_object_put(SetChargingProfile);
	LWS_Send(message);
	result = TRUE;

	return result;
}

int sendSetDisplayMessagesConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *SetDisplayMessage = json_object_new_object();

	DEBUG_INFO("sendSetDisplayMessageConfirmation...\n");

	json_object_object_add(SetDisplayMessage, "status", json_object_new_string((char*)ShmOCPP20Data->SetDisplayMessage.Response_status));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(SetDisplayMessage, JSON_C_TO_STRING_PLAIN));
	json_object_put(SetDisplayMessage);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendSetMonitoringBaseConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *SetMonitoringBase = json_object_new_object();

	DEBUG_INFO("sendSetMonitoringBaseConfirmation...\n");

	json_object_object_add(SetMonitoringBase, "status", json_object_new_string((char*)ShmOCPP20Data->SetMonitoringBase.Response_status));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(SetMonitoringBase, JSON_C_TO_STRING_PLAIN));
	json_object_put(SetMonitoringBase);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendSetMonitoringLevelConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *SetMonitoringLevel = json_object_new_object();

	DEBUG_INFO("sendSetMonitoringLevelConfirmation...\n");

	json_object_object_add(SetMonitoringLevel, "status", json_object_new_string((char*)ShmOCPP20Data->SetMonitoringLevel.Response_status));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(SetMonitoringLevel, JSON_C_TO_STRING_PLAIN));
	json_object_put(SetMonitoringLevel);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendSetNetworkProfileConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *SetNetworkProfile = json_object_new_object();

	DEBUG_INFO("sendSetNetworkProfileConfirmation...\n");

	json_object_object_add(SetNetworkProfile, "status", json_object_new_string((char*)ShmOCPP20Data->SetNetworkProfile.Response_status));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(SetNetworkProfile, JSON_C_TO_STRING_PLAIN));
	json_object_put(SetNetworkProfile);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendSetVariableMonitoringConfirmation(char *uuid, unsigned char variableQuantity)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *SetVariableMonitoring = json_object_new_object();
	json_object *setMonitoringResults = json_object_new_array();

	DEBUG_INFO("sendSetVariableMonitoringConfirmation...\n");

	for(int idx=0;idx<variableQuantity;idx++)
	{
		json_object *variableMonitorResult = json_object_new_object();
		json_object *component = json_object_new_object();
		json_object *variable = json_object_new_object();
		json_object *evse = json_object_new_object();

		json_object_object_add(variableMonitorResult, "id", json_object_new_int(ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].id));
		json_object_object_add(variableMonitorResult, "type", json_object_new_string((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].type));
		json_object_object_add(variableMonitorResult, "severity", json_object_new_int(ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].severity));
		json_object_object_add(variableMonitorResult, "status", json_object_new_string((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].status));

		json_object_object_add(evse, "id", json_object_new_int(ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].component.evse.id));
		json_object_object_add(evse, "connectorId", json_object_new_int(ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].component.evse.connectorId));
		json_object_object_add(component, "evse", evse);
		json_object_object_add(component, "name", json_object_new_string((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].component.name));
		json_object_object_add(component, "instance", json_object_new_string((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].component.instance));
		json_object_object_add(variableMonitorResult, "component", component);

		json_object_object_add(variable, "name", json_object_new_string((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].variable.name));
		json_object_object_add(variable, "instance", json_object_new_string((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].variable.instance));
		json_object_object_add(variableMonitorResult, "variable", variable);

		json_object_array_add(setMonitoringResults, variableMonitorResult);
	}
	json_object_object_add(SetVariableMonitoring , "setMonitoringResult", setMonitoringResults);

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(SetVariableMonitoring, JSON_C_TO_STRING_PLAIN));
	json_object_put(SetVariableMonitoring);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendSetVariableConfirmation(char *uuid, unsigned char variableQuantity)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *SetVariable = json_object_new_object();
	json_object *setVariableResults = json_object_new_array();

	DEBUG_INFO("sendSetVariableConfirmation...\n");

	for(int idx=0;idx<variableQuantity;idx++)
	{
		json_object *variableResult = json_object_new_object();
		json_object *component = json_object_new_object();
		json_object *variable = json_object_new_object();
		json_object *evse = json_object_new_object();

		json_object_object_add(variableResult, "attributeType", json_object_new_string((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeType));
		json_object_object_add(variableResult, "attributeStatus", json_object_new_string((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus));

		json_object_object_add(evse, "id", json_object_new_int(ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].component.evse.id));
		json_object_object_add(evse, "connectorId", json_object_new_int(ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].component.evse.connectorId));
		json_object_object_add(component, "evse", evse);
		json_object_object_add(component, "name", json_object_new_string((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].component.name));
		json_object_object_add(component, "instance", json_object_new_string((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].component.instance));
		json_object_object_add(variableResult, "component", component);

		json_object_object_add(variable, "name", json_object_new_string((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].variable.name));
		json_object_object_add(variable, "instance", json_object_new_string((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].variable.instance));
		json_object_object_add(variableResult, "variable", variable);

		json_object_array_add(setVariableResults, variableResult);
	}
	json_object_object_add(SetVariable , "setVariableResult", setVariableResults);

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(SetVariable, JSON_C_TO_STRING_PLAIN));
	json_object_put(SetVariable);
	LWS_Send(message);
	result = TRUE;
	return result;
}

int sendTriggerMessageConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *TriggerMessage = json_object_new_object();

	DEBUG_INFO("sendTriggerMessageConfirmation...\n");

	json_object_object_add(TriggerMessage, "status", json_object_new_string((char*)ShmOCPP20Data->TriggerMessage.Response_status));

	sprintf(message,"[%d,\"%s\",%s]",
									MESSAGE_TYPE_CALLRESULT,
									uuid,
									json_object_to_json_string_ext(TriggerMessage, JSON_C_TO_STRING_PLAIN));
	json_object_put(TriggerMessage);
	LWS_Send(message);
	result = TRUE;

	return result;
}

int sendUnlockConnectorConfirmation(char *uuid, unsigned char gun_index)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *UnlockConnector = json_object_new_object();

	DEBUG_INFO("sendUnlockConnectorConfirmation...\n");

	json_object_object_add(UnlockConnector, "status", json_object_new_string((char*)ShmOCPP20Data->UnlockConnector[gun_index].Response_status));

	sprintf(message,"[%d,\"%s\",%s]",
									MESSAGE_TYPE_CALLRESULT,
									uuid,
									json_object_to_json_string_ext(UnlockConnector, JSON_C_TO_STRING_PLAIN));
	json_object_put(UnlockConnector);
	LWS_Send(message);
	result = TRUE;

	ShmOCPP20Data->CsMsg.bits[gun_index].UnlockConnectorConf = OFF;

	return result;
}

int sendUnpublishFirmwareConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *UnpublishFirmware = json_object_new_object();

	DEBUG_INFO("sendUnpublishFirmwareConfirmation...\n");

	json_object_object_add(UnpublishFirmware, "status", json_object_new_string((char*)ShmOCPP20Data->UnpublishFirmware.Response_status));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(UnpublishFirmware, JSON_C_TO_STRING_PLAIN));
	json_object_put(UnpublishFirmware);
	LWS_Send(message);
	result = TRUE;

	return result;
}

int sendUpdateFirmwareConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *UpdateFirmware = json_object_new_object();

	DEBUG_INFO("sendUpdateFirmwareConfirmation...\n");
	sprintf((char*)ShmOCPP20Data->UpdateFirmware.Response_status, "%s", UpdateFirmwareStatusEnumTypeStr[UpdateFirmwareStatusEnumType_Accepted]);
	json_object_object_add(UpdateFirmware, "status", json_object_new_string((char*)ShmOCPP20Data->UpdateFirmware.Response_status));

	sprintf(message,"[%d,\"%s\",%s]"
								,MESSAGE_TYPE_CALLRESULT
								,uuid
								,json_object_to_json_string_ext(UpdateFirmware, JSON_C_TO_STRING_PLAIN));
	json_object_put(UpdateFirmware);
	LWS_Send(message);
	result = TRUE;

	return result;
}

int sendUnknownConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;

	char message[256]={0};

	//[ 3, "ba1cbd49-2a76-493a-8f76-fa23e7606532", { "status": "Unlocked" } ]
	DEBUG_INFO("sendUnknownConfirmation...\n");
	sprintf(message,"[%d,\"%s\",\"NotImplemented\",\"Requested Action is not known by receiver\",{}]", MESSAGE_TYPE_CALLERROR, uuid);
	LWS_Send(message);
	result = TRUE;

	return result;
}

//==========================================
// send CallError routine
//==========================================
void SendCallError(char *uniqueId, char *action, char *errorCode, char *errorDescription)
{
	mtrace();
	char message[220]={0};

	DEBUG_INFO("An error occurred. Sending this information: uniqueId {}: action: {}, errorCore: {}, errorDescription: {}\n", uniqueId, action, errorCode, errorDescription);

	sprintf(message,"[%d,\"%s\",\"%s\",\"%s\",{}]",MESSAGE_TYPE_CALLERROR, uniqueId, errorCode, errorDescription);
	LWS_Send(message);
}

//==========================================
// Handle server request routine  Start
//==========================================
int handleCancelReservationRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
    int gunNO = 0;
	int reservationIdInt = -1;
    DEBUG_INFO("handleCancelReservationRequest...\n");

	json_object *CancelReservation;
	CancelReservation = json_tokener_parse(payload);
	if(!is_error(CancelReservation))
	{
		// Required data
		if(json_object_object_get(CancelReservation, "reservationId") != NULL)
			reservationIdInt = json_object_get_int(json_object_object_get(CancelReservation, "reservationId"));
	}
	json_object_put(CancelReservation);
	DEBUG_INFO("reservationIdInt = %d\n", reservationIdInt);

	for(int idx=0;idx<ARRAY_SIZE(ShmOCPP20Data->CancelReservation);idx++)
		sprintf((char*)ShmOCPP20Data->CancelReservation[idx].Response_status, "%s", CancelReservationStatusEnumTypeStr[CancelReservationStatusEnumType_Rejected]);

	if(reservationIdInt != -1)
	{
		//0: Booting, 1: idle, 2: authorizing, 3: preparing, 4: charging, 5: terminating, 6: alarm, 7: fault, 8: Reserved, 9: maintain
		//check Transaction active
		//J: CHAdeMO   U: CCS1 combo   E: CCS2 combo  G: GBT DC
		for (int index = 0; index < CHAdeMO_QUANTITY; index++)
		{
			if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ReservationId == reservationIdInt)
			{
				sprintf((char*)ShmOCPP20Data->CancelReservation[ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index].Response_status, "%s", CancelReservationStatusEnumTypeStr[CancelReservationStatusEnumType_Accepted]);

				if(gunType[2] == GUN_TYPE_CHAdeMO)
				{
					gunNO = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index + 1;
				}
				else
				{
					gunNO = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index;
				}

				ShmOCPP20Data->CsMsg.bits[gunNO].CancelReservationReq = ON;
				ShmOCPP20Data->ReservationStatusUpdate[gunNO].reservationId = reservationIdInt;
				sprintf((char*)ShmOCPP20Data->ReservationStatusUpdate[gunNO].reservationUpdateStatus, ReservationUpdateStatusEnumTypeStr[ReservationUpdateStatusEnumType_Removed]);
				ShmOCPP20Data->CpMsg.bits[gunNO].ReservationStatusUpdateReq = ON;
				goto end;
			}
		}

		for (int index = 0; index < CCS_QUANTITY; index++)
		{
			if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ReservationId == reservationIdInt)
			{
				sprintf((char *)ShmOCPP20Data->CancelReservation[ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index].Response_status, "%s", CancelReservationStatusEnumTypeStr[CancelReservationStatusEnumType_Accepted]);
				if(gunType[2] == GUN_TYPE_CCS)
				{
					gunNO = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index + 1;
				}
				else
				{
					gunNO = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index;
				}

				ShmOCPP20Data->CsMsg.bits[gunNO].CancelReservationReq = ON;
				ShmOCPP20Data->ReservationStatusUpdate[gunNO].reservationId = reservationIdInt;
				sprintf((char*)ShmOCPP20Data->ReservationStatusUpdate[gunNO].reservationUpdateStatus, ReservationUpdateStatusEnumTypeStr[ReservationUpdateStatusEnumType_Removed]);
				ShmOCPP20Data->CpMsg.bits[gunNO].ReservationStatusUpdateReq = ON;
				goto end;
			}
		}


		for (int index = 0; index < GB_QUANTITY; index++)
		{
			if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ReservationId == reservationIdInt)
			{
				sprintf((char *)ShmOCPP20Data->CancelReservation[ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index].Response_status, "%s", CancelReservationStatusEnumTypeStr[CancelReservationStatusEnumType_Accepted]);
				if(gunType[2] == GUN_TYPE_GBT)
				{
					gunNO = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index + 1;
				}
				else
				{
					gunNO = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index;
				}

				ShmOCPP20Data->CsMsg.bits[gunNO].CancelReservationReq = ON;
				ShmOCPP20Data->ReservationStatusUpdate[gunNO].reservationId = reservationIdInt;
				sprintf((char*)ShmOCPP20Data->ReservationStatusUpdate[gunNO].reservationUpdateStatus, ReservationUpdateStatusEnumTypeStr[ReservationUpdateStatusEnumType_Removed]);
				ShmOCPP20Data->CpMsg.bits[gunNO].ReservationStatusUpdateReq = ON;
				goto end;
			}
		}


		for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
		{
			if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ReservationId == reservationIdInt)
			{
				sprintf((char *)ShmOCPP20Data->CancelReservation[ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index].Response_status, "%s", CancelReservationStatusEnumTypeStr[CancelReservationStatusEnumType_Accepted]);

				gunNO = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index;

				ShmOCPP20Data->CsMsg.bits[gunNO].CancelReservationReq = ON;
				ShmOCPP20Data->ReservationStatusUpdate[gunNO].reservationId = reservationIdInt;
				sprintf((char*)ShmOCPP20Data->ReservationStatusUpdate[gunNO].reservationUpdateStatus, ReservationUpdateStatusEnumTypeStr[ReservationUpdateStatusEnumType_Removed]);
				ShmOCPP20Data->CpMsg.bits[gunNO].ReservationStatusUpdateReq = ON;
				goto end;
			}
		}


		for (int index = 0; index < AC_QUANTITY; index++)
		{
			if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].ReservationId == reservationIdInt)
			{
				sprintf((char *)ShmOCPP20Data->CancelReservation[ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index].Response_status, "%s", CancelReservationStatusEnumTypeStr[CancelReservationStatusEnumType_Accepted]);

				if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
				{
					gunNO = 1; //ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index ;
				}
				else
				{
					gunNO = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index;
				}

				ShmOCPP20Data->CsMsg.bits[gunNO].CancelReservationReq = ON;
				ShmOCPP20Data->ReservationStatusUpdate[gunNO].reservationId = reservationIdInt;
				sprintf((char*)ShmOCPP20Data->ReservationStatusUpdate[gunNO].reservationUpdateStatus, ReservationUpdateStatusEnumTypeStr[ReservationUpdateStatusEnumType_Removed]);
				ShmOCPP20Data->CpMsg.bits[gunNO].ReservationStatusUpdateReq = ON;
				goto end;
			}
		}
	}

	//The reservationId does NOT match the reservationId
	sendCancelReservationConfirmation(uuid, gunNO);
end:
	// Fill in ocpp packet uuid
	strcpy((char *)ShmOCPP20Data->CancelReservation[gunNO].guid, uuid);

	return result;
}

int handleCertificateSignedRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	json_object *CertificateSigned;

	DEBUG_INFO("handleCertificateSignedRequest...\n");
	CertificateSigned = json_tokener_parse(payload);
	if(!is_error(CertificateSigned))
	{
		memset(&ShmOCPP20Data->CertificateSigned, 0, sizeof(struct CertificateSigned_20));
		memcpy(&ShmOCPP20Data->CertificateSigned.guid, uuid, ARRAY_SIZE(ShmOCPP20Data->CertificateSigned.guid));
		// Required data
		sprintf((char*)ShmOCPP20Data->CertificateSigned.certificateChain, "%s", json_object_get_string(json_object_object_get(CertificateSigned, "certificateChain")));

		// Optional data
		if(json_object_object_get(CertificateSigned, "certificateType") != NULL)
		{
			sprintf((char*)ShmOCPP20Data->CertificateSigned.certificateType, "%s", json_object_get_string(json_object_object_get(CertificateSigned, "certificateType")));

			if(strcmp((char*)ShmOCPP20Data->CertificateSigned.certificateType, CertificateSigningUseEnumTypeStr[CertificateSignedStatusEnumType_ChargingStationCertificate]) == 0)
			{
				FILE *fp = fopen("/Storage/OCPP/certCP.crt", "w");
				fprintf(fp, "%s", ShmOCPP20Data->CertificateSigned.certificateChain);
				fclose(fp);
			}
			else if(strcmp((char*)ShmOCPP20Data->CertificateSigned.certificateType, CertificateSigningUseEnumTypeStr[CertificateSignedStatusEnumType_V2GCertificate]) == 0)
			{
				FILE *fp = fopen("/Storage/OCPP/certV2G.crt", "w");
				fprintf(fp, "%s", ShmOCPP20Data->CertificateSigned.certificateChain);
				fclose(fp);
			}
		}
		else
		{
			FILE *fp = fopen("/Storage/OCPP/certCP.crt", "w");
			fprintf(fp, "%s", ShmOCPP20Data->CertificateSigned.certificateChain);
			fclose(fp);

			fp = fopen("/Storage/OCPP/certV2G.crt", "w");
			fprintf(fp, "%s", ShmOCPP20Data->CertificateSigned.certificateChain);
			fclose(fp);
		}
		system("/bin/fsync -d /dev/mtdblock13;/bin/sync &");

		strcpy((char*)ShmOCPP20Data->CertificateSigned.Response_status, CertificateSignedStatusEnumTypeStr[CertificateSignedStatusEnumType_Accepted]);
	}
	else
		strcpy((char*)ShmOCPP20Data->CertificateSigned.Response_status, CertificateSignedStatusEnumTypeStr[CertificateSignedStatusEnumType_Rejected]);

	json_object_put(CertificateSigned);

	sendCertificateSignedConfirmation(uuid);

	return result;
}

int handleChangeAvailabilityRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
    int evseId = 0, gunIndex = 0;
	char operationalStatus[16]={0};
	char comfirmstr[20];
	int specificId = FALSE;

	DEBUG_INFO("handleChangeAvailabilityRequest...\n");

	json_object *ChangeAvailability;
	ChangeAvailability = json_tokener_parse(payload);

	if(!is_error(ChangeAvailability))
	{
		// Required data
		if(json_object_object_get(ChangeAvailability, "operationalStatus") != NULL)
			sprintf((char*)operationalStatus, "%s", json_object_get_string(json_object_object_get(ChangeAvailability, "operationalStatus")));


		if(json_object_object_get(ChangeAvailability, "evse") != NULL)
		{
			evseId = json_object_get_int(json_object_object_get(json_object_object_get(ChangeAvailability, "evse"), "id"));

			if(json_object_object_get(json_object_object_get(ChangeAvailability, "evse"), "connectorId") != NULL)
				gunIndex = json_object_get_int(json_object_object_get(json_object_object_get(ChangeAvailability, "evse"), "connectorId"));
		}
	}
	json_object_put(ChangeAvailability);


	if((evseId != 0) && (evseId <= gunTotalNumber))
	{
		ShmOCPP20Data->ChangeAvailability[evseId - 1].evse.connectorId = evseId;
		sprintf((char *)ShmOCPP20Data->ChangeAvailability[evseId - 1].operationalStatus, "%s", operationalStatus);
	}
	else if(evseId == 0)
	{
		for(int i=0; i < gunTotalNumber; i++)
		{
			ShmOCPP20Data->ChangeAvailability[i].evse.connectorId = evseId;
			sprintf((char *)ShmOCPP20Data->ChangeAvailability[i].operationalStatus, "%s", operationalStatus);
		}
	}

	if((gunIndex != 0) && (gunIndex <= gunTotalNumber))
	{
		ShmOCPP20Data->ChangeAvailability[gunIndex - 1].evse.connectorId = gunIndex;
		sprintf((char *)ShmOCPP20Data->ChangeAvailability[gunIndex - 1].operationalStatus, "%s", operationalStatus);
	}
	else if(gunIndex == 0)
	{
		for(int i=0; i < gunTotalNumber; i++)
		{
			ShmOCPP20Data->ChangeAvailability[i].evse.connectorId = gunIndex;
			sprintf((char *)ShmOCPP20Data->ChangeAvailability[i].operationalStatus, "%s", operationalStatus);
		}
	}

	memset(comfirmstr, 0, ARRAY_SIZE(comfirmstr));
	sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Rejected] );

	if((gunIndex  == 0) || (gunIndex <= gunTotalNumber))
	{
		specificId = TRUE;
	}

	if(specificId == FALSE)
		goto end;

	if(strcmp((const char *)operationalStatus, OperationalStatusEnumTypeStr[OperationalStatusEnumType_Inoperative]) == 0)
	{

		//----------------------gunIndex is 0  ------------------------------------------------//
		if(gunIndex  == 0)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D') // 'D' means DC
			{
				for(int i=0; i < gunTotalNumber; i++)
				{
					for (int index = 0; index < CHAdeMO_QUANTITY; index++)
					{
						if ((gunType[i] == GUN_TYPE_CHAdeMO)&&(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == i))
						{
							if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_RESERVATION) // S_PRECHARGE
							{
								sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Rejected] );
								goto end;
							}
							else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_AUTHORIZING) ||
									(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_PREPARING) ||
									(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_CHARGING) ||
									(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_TERMINATING) ||
									(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_COMPLETE))  // S_CHARGING
							{
								sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Scheduled] );
								goto end;
							}
						}
					}//END FOR CHAdeMO_QUANTITY

					for (int index = 0; index < CCS_QUANTITY; index++)
					{
						if ((gunType[i] == GUN_TYPE_CCS)&&(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == i))
						{
							if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_RESERVATION)// S_PRECHARGE
							{
									sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Rejected] );
									goto end;
							}
								else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_AUTHORIZING) ||
										(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_PREPARING) ||
										(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_CHARGING) ||
										(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_TERMINATING) ||
										(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_COMPLETE)) // S_CHARGING
							{
									sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Scheduled] );
									goto end;
							}
						}
					}//END FOR CCS_QUANTITY

					for (int index = 0; index < GB_QUANTITY; index++)
					{
						if ((gunType[i] == GUN_TYPE_GBT)&&(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == i))
						{
							if(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_RESERVATION) // S_PRECHARGE
							{
									sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Rejected] );
									goto end;
							}
							else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_AUTHORIZING) ||
									(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_PREPARING) ||
									(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_CHARGING) ||
									(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_TERMINATING) ||
									(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_COMPLETE)) // S_CHARGING
							{
									sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Scheduled] );
									goto end;
							}
						}
					}// END FOR GB_QUANTITY

					for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
					{
						if ((gunType[i] == GUN_TYPE_DO)&&(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == i))
						{
							if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_RESERVATION) // S_PRECHARGE
							{
									sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Rejected] );
									goto end;
							}
							else if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_AUTHORIZING) ||
									(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_PREPARING) ||
									(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_CHARGING) ||
									(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_TERMINATING) ||
									(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_COMPLETE)) // S_CHARGING
							{
									sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Scheduled] );
									goto end;
							}
						}
					}// END FOR DO_QUANTITY

					for (int index = 0; index < AC_QUANTITY; index++)
					{
						if ((gunType[i] == GUN_TYPE_AC)&&(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == i))
						{
							if(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_RESERVATION) // S_PRECHARGE
							{
									sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Rejected] );
									goto end;
							}
							else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_AUTHORIZING) ||
									(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_PREPARING) ||
									(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_CHARGING) ||
									(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_TERMINATING) ||
									(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_COMPLETE)) // S_CHARGING
							{
									sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Scheduled] );
									goto end;
							}
						}
					}//END FOR AC_QUANTITY
				}// END FOR gunTotalNumber
			}
			else if (ShmSysConfigAndInfo->SysConfig.ModelName[0]=='A') //'A' means AC
			{
				for(int i=0; i < gunTotalNumber; i++)
				{
					if(ShmSysConfigAndInfo->SysInfo.AcChargingData[i].SystemStatus == SYS_MODE_RESERVATION) // S_PRECHARGE
					{
						sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Rejected] );
						goto end;
					}
					else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[i].SystemStatus == SYS_MODE_AUTHORIZING) ||
						(ShmSysConfigAndInfo->SysInfo.AcChargingData[i].SystemStatus == SYS_MODE_PREPARING) ||
						(ShmSysConfigAndInfo->SysInfo.AcChargingData[i].SystemStatus == SYS_MODE_CHARGING) ||
						(ShmSysConfigAndInfo->SysInfo.AcChargingData[i].SystemStatus == SYS_MODE_TERMINATING) ||
						(ShmSysConfigAndInfo->SysInfo.AcChargingData[i].SystemStatus == SYS_MODE_COMPLETE)) // S_CHARGING
					{
						sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Scheduled] );
						goto end;
					}
				}
			}

			sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Accepted] );
			goto end;
		}


		//----------------------gunIndex is not 0  ------------------------------------------------//

	    //check Transaction active
		for (int index = 0; index < CHAdeMO_QUANTITY; index++)
		{
			if ((gunIndex > 0)&&(gunType[gunIndex-1] == GUN_TYPE_CHAdeMO))
			{
				if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_RESERVATION) ) // S_PRECHARGE
				{
					sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Rejected] );
					goto end;
				}
				else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_AUTHORIZING) ||
						(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_PREPARING) ||
						(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_CHARGING) ||
						(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_TERMINATING) ||
						(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_COMPLETE))  // S_CHARGING
				{
					sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Scheduled] );
					goto end;
				}
				else
				{
					DEBUG_INFO("ShmSysConfigAndInfo->SysInfo.ChademoChargingData[%d].SystemStatus = %d\n",index, ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus);
					sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Accepted] );
					goto end;
				}
			}
		}//END FOR CHAdeMO_QUANTITY

		for (int index = 0; index < CCS_QUANTITY; index++)
		{
			if ((gunIndex > 0)&&(gunType[gunIndex - 1] == GUN_TYPE_CCS))
			{
				if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_RESERVATION) )// S_PRECHARGE
				{
					sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Rejected] );
					goto end;
				}
				else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_AUTHORIZING) ||
						(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_PREPARING) ||
						(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_CHARGING) ||
						(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_TERMINATING) ||
						(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_COMPLETE)) // S_CHARGING
				{
					sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Scheduled] );
					goto end;
				}
				else
				{
					DEBUG_INFO("ShmSysConfigAndInfo->SysInfo.CcsChargingData[%d].SystemStatus=%d\n",index, ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus);
					sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Accepted] );
					goto end;
				}
			}
		}//END FOR CCS_QUANTITY

		for (int index = 0; index < GB_QUANTITY; index++)
		{
			if ((gunIndex > 0)&&(gunType[gunIndex-1] == GUN_TYPE_GBT))
			{
				if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_RESERVATION)) // S_PRECHARGE
				{
					sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Rejected] );
					goto end;
				}
				else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_AUTHORIZING) ||
						(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_PREPARING) ||
						(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_CHARGING) ||
						(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_TERMINATING) ||
						(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_COMPLETE)) // S_CHARGING
				{
					sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Scheduled] );
					goto end;
				}
				else
				{
					DEBUG_INFO("ShmSysConfigAndInfo->SysInfo.GbChargingData[%d].SystemStatus=%d\n",index,ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus);
					sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Accepted] );
					goto end;
				}


			}
		}// END FOR GB_QUANTITY

		for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
		{
			if ((gunIndex > 0)&&(gunType[gunIndex-1] == GUN_TYPE_DO))
			{
				if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_RESERVATION)) // S_PRECHARGE
				{
					sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Rejected] );
					goto end;
				}
				else if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_AUTHORIZING) ||
						(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_PREPARING) ||
						(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_CHARGING) ||
						(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_TERMINATING) ||
						(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_COMPLETE)) // S_CHARGING
				{
					sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Scheduled] );
					goto end;
				}
				else
				{
					DEBUG_INFO("ShmSysConfigAndInfo->SysInfo.GbChargingData[%d].SystemStatus=%d\n",index,ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus);
					sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Accepted] );
					goto end;
				}


			}
		}// END FOR DO_QUANTITY

		for (int index = 0; index < AC_QUANTITY; index++)
		{
			if ((gunIndex > 0)&&(gunType[gunIndex-1] == GUN_TYPE_AC))
			{
				if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_RESERVATION)) // S_PRECHARGE
				{
					sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Rejected] );
					goto end;
				}
				else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_AUTHORIZING) ||
						(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_PREPARING) ||
						(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_CHARGING) ||
						(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_TERMINATING) ||
						(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_COMPLETE)) // S_CHARGING
				{
					sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Scheduled] );
					goto end;
				}
				else
				{
					DEBUG_INFO("ShmSysConfigAndInfo->SysInfo.AcChargingData[%d].SystemStatus=%d\n",index, ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus);
					sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Accepted] );
					goto end;
				}
			}
		}//END FOR AC_QUANTITY

	}//END FOR AvailabilityEnumTypeStr[Inoperative]


	if(strcmp((const char *)operationalStatus, OperationalStatusEnumTypeStr[OperationalStatusEnumType_Operative]) == 0)
	{
		//----------------------gunIndex is 0  ------------------------------------------------//
		if(gunIndex  == 0)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D') // 'D' means DC
			{
				for(int i=0; i < gunTotalNumber; i++)
				{
					for (int index = 0; index < CHAdeMO_QUANTITY; index++)
					{
						if ((gunType[i] == GUN_TYPE_CHAdeMO )&&(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == i)&&(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_FAULT))  //S_FAULT   //(((gunIndex  == 0)|| ((gunIndex > 0)&&(gunType[gunIndex-1] == GUN_TYPE_CHAdeMO)) ) &&(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus != SYS_MODE_FAULT))  //S_FAULT
						{
							sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Rejected] );
							goto end;
						}
					}//END FOR CHAdeMO_QUANTITY

					for (int index = 0; index < CCS_QUANTITY; index++)
					{
						if ((gunType[i] == GUN_TYPE_CCS)&&(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == i)&&(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_FAULT)) //S_FAULT//(((gunIndex  == 0)|| ((gunIndex > 0)&&((gunType[gunIndex - 1] == 'U')||(gunType[gunIndex - 1] == 'E'))) )&&(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != SYS_MODE_FAULT)) //S_FAULT
						{
							sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Rejected] );
							goto end;
						}
					}//END FOR CCS_QUANTITY

					for (int index = 0; index < GB_QUANTITY; index++)
					{
						if ((gunType[i] == GUN_TYPE_GBT)&&(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == i)&&(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_FAULT)) //S_FAULT  //(((gunIndex  == 0)|| ((gunIndex > 0)&&(gunType[gunIndex-1] == GUN_TYPE_GBT)))&&(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus != SYS_MODE_FAULT)) //S_FAULT
						{
							//ShmOCPP20Data->CsMsg.bits[gunIndex - 1].ChangeAvailabilityReq = ON;
							sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Rejected] );
							goto end;
						}
					}// END FOR GB_QUANTITY

					for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
					{
						if ((gunType[i] == GUN_TYPE_DO)&&(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == i)&&(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_FAULT)) //S_FAULT  //(((gunIndex  == 0)|| ((gunIndex > 0)&&(gunType[gunIndex-1] == GUN_TYPE_GBT)))&&(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus != SYS_MODE_FAULT)) //S_FAULT
						{
							//ShmOCPP20Data->CsMsg.bits[gunIndex - 1].ChangeAvailabilityReq = ON;
							sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Rejected] );
							goto end;
						}
					}// END FOR DO_QUANTITY

					for (int index = 0; index < AC_QUANTITY; index++)
					{
						if ((gunType[i] == GUN_TYPE_AC) &&(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_FAULT))  //S_FAULT // (((gunIndex  == 0)|| ((gunIndex > 0)&&((gunType[gunIndex-1] > '0')&&(gunType[gunIndex-1] <= '9')))) &&(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != SYS_MODE_FAULT))  //S_FAULT
						{
							sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Rejected] );
							goto end;
						}
					}//END FOR CHAdeMO_QUANTITY

				}// END FOR gunTotalNumber
			}
			else if (ShmSysConfigAndInfo->SysConfig.ModelName[0]=='A') //'A' means AC
			{
				for(int i=0; i < gunTotalNumber; i++)
				{
					for (int index = 0; index < AC_QUANTITY; index++)
					{
						if ((gunType[i] == GUN_TYPE_AC) &&(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_FAULT))  //S_FAULT // (((gunIndex  == 0)|| ((gunIndex > 0)&&((gunType[gunIndex-1] > '0')&&(gunType[gunIndex-1] <= '9')))) &&(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != SYS_MODE_FAULT))  //S_FAULT
						{
							sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Rejected] );
							goto end;
						}
					}//END FOR CHAdeMO_QUANTITY

				} // END FOR gunTotalNumber
			}

			sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Accepted] );
			goto end;
		}

		//----------------------gunIndex is not 0  ------------------------------------------------//
	    //check Transaction active
		for (int index = 0; index < CHAdeMO_QUANTITY; index++)
		{
			if (((gunIndex > 0)&&(gunType[gunIndex-1] == GUN_TYPE_CHAdeMO) ) &&(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus != SYS_MODE_FAULT))  //S_FAULT
			{
				sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Accepted] );
				goto end;
			}
		}//END FOR CHAdeMO_QUANTITY

		for (int index = 0; index < CCS_QUANTITY; index++)
		{
			if ((((gunIndex > 0)&&(gunType[gunIndex - 1] == GUN_TYPE_CCS)) )&&(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != SYS_MODE_FAULT))  //S_FAULT
			{
				sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Accepted] );
				goto end;
			}
		}//END FOR CCS_QUANTITY

		for (int index = 0; index < GB_QUANTITY; index++)
		{
			if (((gunIndex > 0)&&(gunType[gunIndex-1] == GUN_TYPE_GBT))&&(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus != SYS_MODE_FAULT)) //S_FAULT
			{
				sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Accepted] );
				goto end;
			}
		}// END FOR GB_QUANTITY

		for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
		{
			if (((gunIndex > 0)&&(gunType[gunIndex-1] == GUN_TYPE_DO))&&(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus != SYS_MODE_FAULT)) //S_FAULT
			{
				sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Accepted] );
				goto end;
			}
		}// END FOR DO_QUANTITY

		for (int index = 0; index < AC_QUANTITY; index++)
		{
			if (((gunIndex > 0)&&(gunType[gunIndex-1] == GUN_TYPE_AC)) &&(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != SYS_MODE_FAULT))  //S_FAULT
			{
				sprintf(comfirmstr, "%s", ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Accepted] );
				goto end;
			}
		}//END FOR AC_QUANTITY
	}//END FOR AvailabilityEnumTypeStr[Operative]

end:
	if((gunIndex != 0) && (gunIndex <= gunTotalNumber))
	{
		sprintf((char *)ShmOCPP20Data->ChangeAvailability[gunIndex - 1].Response_status, "%s", comfirmstr );
	}
	else
	{
		sprintf((char *)ShmOCPP20Data->ChangeAvailability[0].Response_status, "%s", comfirmstr );
	}

	if((gunIndex != 0) && (gunIndex <= gunTotalNumber))
	{
		if(strstr(comfirmstr, ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Rejected]) == NULL)
			ShmOCPP20Data->CsMsg.bits[gunIndex - 1].ChangeAvailabilityReq = ON;
	}
	else if(gunIndex == 0)
	{
		if(strstr(comfirmstr, ChangeAvailabilityStatusEnumTypeStr[ChangeAvailabilityStatusEnumType_Rejected]) == NULL)
		{
			for(int i=0; i < gunTotalNumber/*(CHAdeMO_QUANTITY+ CCS_QUANTITY + GB_QUANTITY)*/; i++)
				ShmOCPP20Data->CsMsg.bits[i].ChangeAvailabilityReq = ON;
		}
	}

	sendChangeAvailabilityConfirmation(uuid, (gunIndex==0?gunIndex:gunIndex-1));
	system("/bin/fsync -d /dev/mtdblock13;/bin/sync &");
	return result;
}

int handleClearCacheRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
    char rmFileCmd[100]={0};
    struct stat stats;
    DEBUG_INFO("handleClearCacheRequest...\n");
    stat("/Storage/OCPP", &stats);

    // Check for directory existence
    if (S_ISDIR(stats.st_mode) == 1)
    {}
    else
    {
    	DEBUG_INFO("\n OCPP directory not exist, create dir \n");
    	sprintf(rmFileCmd,"mkdir -p %s","/Storage/OCPP");
    	system(rmFileCmd);
    }

    if(DB_cleanLocalCache() != PASS)
    {
    	DEBUG_INFO("open AuthorizationCache file failed\n");
    	sprintf((char*)ShmOCPP20Data->ClearCache.Response_status, "%s", ClearCacheStatusEnumTypeStr[ClearCacheStatusEnumType_Rejected] );
    }
    else
    {
    	DEBUG_INFO("open AuthorizationCache file successful\n");
    	sprintf((char*)ShmOCPP20Data->ClearCache.Response_status, "%s", ClearCacheStatusEnumTypeStr[ClearCacheStatusEnumType_Accepted] );
    }

    sendClearCacheConfirmation(uuid);
    system("/bin/fsync -d /dev/mtdblock13;/bin/sync &");

	return result;
}

int handleClearChargingProfileRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	int resultRename;
	int connectorIdInt, chargingProfileIdInt, stackLevelInt;
	char chargingProfilePurposeStr[26]={0};
	int tempconnectorIdInt, tempchargingProfileIdInt, tempstackLevelInt;
	char tempchargingProfilePurposeStr[26]={0};
	char sstr[160]={0};
	char str[100]={0};
	int c = 0;
	char *loc;
	char fname[200]={0};
	char comfirmstr[20]={0};
	char word[1600]={0};
	int clearflag = FALSE;
	int chargingProfileIdIsNULL = FALSE;
	int connectorIsNULL = FALSE;
	int chargingProfilePurposeIsNULL = FALSE;
	int stackLevelIsNULL = FALSE;
	//int GotoEnd = FALSE;
	FILE *fptr1, *fptr2;
	char temp[] = "/Storage/OCPP/ClearChargingProfiletemp.json";  // Create temp file
    int n_chargingProfile=0;
    int isEmptyFile = FALSE;
    char sLineWord[1600]={0};
    char chargingProfiles[10][100]={0};
    int ChargeProfileCount = 0;
    int ch;
    connectorIdInt = chargingProfileIdInt = stackLevelInt = 0;
    DEBUG_INFO("handleClearChargingProfileRequest...\n");
    json_object *ClearChargingProfile;
	ClearChargingProfile = json_tokener_parse(payload);

	if(!is_error(ClearChargingProfile))
	{
		// Optional data
		if(json_object_object_get(ClearChargingProfile, "chargingProfileId") != NULL)
			chargingProfileIdInt = json_object_get_int(json_object_object_get(ClearChargingProfile, "chargingProfileId"));
		else
			chargingProfileIdIsNULL = TRUE;

		if(json_object_object_get(json_object_object_get(ClearChargingProfile, "chargingProfileCriteria"), "evseId") != NULL)
			connectorIdInt = json_object_get_int(json_object_object_get(json_object_object_get(ClearChargingProfile, "chargingProfileCriteria"), "evseId"));
		else
			connectorIsNULL = TRUE;

		if(json_object_object_get(json_object_object_get(ClearChargingProfile, "chargingProfileCriteria"), "chargingProfilePurpose") != NULL)
			sprintf((char*)chargingProfilePurposeStr, "%s", json_object_get_string(json_object_object_get(json_object_object_get(ClearChargingProfile, "chargingProfileCriteria"), "chargingProfilePurpose")));
		else
			chargingProfilePurposeIsNULL = TRUE;

		if(json_object_object_get(json_object_object_get(ClearChargingProfile, "chargingProfileCriteria"), "stackLevel") != NULL)
			stackLevelInt = json_object_get_int(json_object_object_get(json_object_object_get(ClearChargingProfile, "chargingProfileCriteria"), "stackLevel"));
		else
			stackLevelIsNULL = TRUE;
	}
	json_object_put(ClearChargingProfile);

	if(connectorIsNULL == FALSE)
	{
		switch(connectorIdInt)
		{
			case 0:

			    if(chargingProfilePurposeIsNULL == TRUE)
				{
			    	int l = 0;
			    	strcpy(fname, ChargingStationMaxProfile_JSON);
			    	if((access(fname,F_OK))!=-1)
			    	{
			    		strcpy(chargingProfiles[l], fname);
			    		l = l + 1;
			    	}

			    	strcpy(fname, TxDefaultProfile_0_JSON);
			    	if((access(fname,F_OK))!=-1)
			    	{
			    		strcpy(chargingProfiles[l], fname);
			    		l = l + 1;
			    	}
			    	ChargeProfileCount = l;

				}
				else if((chargingProfilePurposeIsNULL == FALSE)&&(strcmp(chargingProfilePurposeStr,"ChargePointMaxProfile")==0))
				{
					strcpy(fname, ChargingStationMaxProfile_JSON);
					if((access(fname,F_OK))!=-1)
					{
						strcpy(chargingProfiles[0], fname);
						ChargeProfileCount = 1;
					}
				}
				else if((chargingProfilePurposeIsNULL == FALSE)&&(strcmp(chargingProfilePurposeStr,"TxDefaultProfile")==0))
				{
					strcpy(fname, TxDefaultProfile_0_JSON);
					if((access(fname,F_OK))!=-1)
					{
						strcpy(chargingProfiles[0], fname);
						ChargeProfileCount = 1;
					}
				}

				break;

			default:
			    if(chargingProfilePurposeIsNULL == TRUE)
			    {
			    	int m = 0;
			    	memset(fname, 0, ARRAY_SIZE(fname));
			    	sprintf(fname, "/Storage/OCPP/TxDefaultProfile_%d_OCPP20.json", connectorIdInt);
			    	if((access(fname,F_OK))!=-1)
			    	{
			    		strcpy(chargingProfiles[m], fname);
			    		m = m + 1;
			    	}

			    	memset(fname, 0, ARRAY_SIZE(fname));
			    	sprintf(fname, "/Storage/OCPP/TxProfile_%d_OCPP20.json", connectorIdInt);
			    	if((access(fname,F_OK))!=-1)
			    	{
			    		strcpy(chargingProfiles[m], fname);
			    		m = m + 1;
			    	}

			    	ChargeProfileCount = m;
			    }
				else if((chargingProfilePurposeIsNULL == FALSE)&&(strcmp(chargingProfilePurposeStr,"TxDefaultProfile")==0))
				{
					//strcpy(fname, TxDefaultProfile_1_JSON);
					sprintf(fname, "/Storage/OCPP/TxDefaultProfile_%d_OCPP20.json", connectorIdInt);
					if((access(fname,F_OK))!=-1)
					{
						strcpy(chargingProfiles[0], fname);
						ChargeProfileCount = 1;
					}

				}
				else if((chargingProfilePurposeIsNULL == FALSE)&&(strcmp(chargingProfilePurposeStr,"TxProfile")==0))
				{
					sprintf(fname, "/Storage/OCPP/TxProfile_%d_OCPP20.json", connectorIdInt);
					if((access(fname,F_OK))!=-1)
					{
						strcpy(chargingProfiles[0], fname);
						ChargeProfileCount = 1;
					}
				}
				//strcpy(fname, ChargePointMaxProfile_JSON );
				break;
		}
	}
	else // Check all Charging Profiles
	{
		int i = 0;
		char fnametemp[200]={0};
		ChargeProfileCount = 0;
		//Check ChargePointMaxProfile.json exit
		if((access("/Storage/OCPP/ChargePointMaxProfile.json",F_OK))!=-1)
		{
			strcpy(chargingProfiles[i], "/Storage/OCPP/ChargePointMaxProfile.json");
			i = i + 1;
		}

        //Check TxDefaultProfile_%d.json
		for(int j=1; j <= gunTotalNumber; j++)
		{
			memset(fnametemp, 0, ARRAY_SIZE(fnametemp));
			sprintf(fnametemp, "/Storage/OCPP/TxDefaultProfile_%d_OCPP20.json", j);
			if((access(fnametemp,F_OK))!=-1)
			{
				strcpy(chargingProfiles[i], fnametemp);
				i = i + 1;
			}
		}

		//Check TxProfile_%d.json
		for(int j=1; j <= gunTotalNumber; j++)
		{
			memset(fnametemp, 0, ARRAY_SIZE(fnametemp));
			sprintf(fnametemp, "/Storage/OCPP/TxProfile_%d_OCPP20.json", j);
			if((access(fnametemp,F_OK))!=-1)
			{
				strcpy(chargingProfiles[i], fnametemp);
				i = i + 1;
			}
		}

		ChargeProfileCount = i;
	}// End connectorIsNULL is TRUE

	if(ChargeProfileCount == 0)
	{
		sprintf(comfirmstr, "%s", ClearChargingProfileStatusEnumTypeStr[ClearChargingProfileStatusEnumType_Unknown] );
		goto end;
	}

	if(connectorIsNULL == FALSE && (connectorIdInt != 0) && ( (connectorIdInt-1) > gunTotalNumber) )
	{
		sprintf(comfirmstr, "%s", ClearChargingProfileStatusEnumTypeStr[ClearChargingProfileStatusEnumType_Unknown] );
		goto end;
	}

	if((connectorIsNULL == FALSE) && (connectorIdInt == 0) )
	{
		memset(str, 0, ARRAY_SIZE(str));
		// clear temp file
		sprintf(str,"rm -f %s",temp);
		system(str);

		for(int k=0; k < ChargeProfileCount; k++)
		{
			memset(str, 0, ARRAY_SIZE(str));
			//clear file in C
			sprintf(str,"rm -f %s",chargingProfiles[k]);
			system(str);
		}

		sprintf(comfirmstr, "%s", ClearChargingProfileStatusEnumTypeStr[ClearChargingProfileStatusEnumType_Accepted] );
		goto end;
	}
	else if(connectorIsNULL == TRUE)
	{
		for(int k=0; k < ChargeProfileCount; k++)
		{
			fptr1 = fopen(chargingProfiles[k], "r");
			fptr2 = fopen("/Storage/OCPP/ClearChargingProfiletemp.json", "w+");

			//Check Charging Profile Count
			while(fscanf(fptr1, "%s", word) != EOF)
			{
				//DEBUG_INFO("word=%s\n",word);
				if(strstr(word, "id")!= NULL)
				{
					//DEBUG_INFO("test id \n");
					n_chargingProfile = n_chargingProfile + 1;
					//DEBUG_INFO("id Found\n");
				}
			}
			rewind(fptr1);

			//search Charging Profile Element
			//int i= 0;
			while ( fgets( sLineWord, sizeof sLineWord, fptr1 ) != NULL )
			{
				//------------------------tempconnectorIdInt------------------------//
				loc = strstr(sLineWord, "connectorId");
				c = 0;
				memset(sstr ,0, sizeof(sstr) );
				while (loc[strlen("connectorId")+2+c] != ',')
				{
					sstr[c] = loc[strlen("connectorId")+2+c];
					c++;
				}
				sstr[c] = '\0';
				tempconnectorIdInt = atoi(sstr);
				printf("file's gun number is %d\n", tempconnectorIdInt);

				//--------------------------id--------------------//
				c = 0;
				loc = strstr(sLineWord, "id");
				memset(sstr ,0, ARRAY_SIZE(sstr));
				while (loc[strlen("id")+2+c] != ',')
				{
					sstr[c] = loc[strlen("id")+2+c];
					//printf("i=%d sstr=%c\n",c, sstr[c]);
					c++;
				}
				sstr[c] = '\0';
				tempchargingProfileIdInt = atoi(sstr);

				//stackLevel
				c = 0;
				loc = strstr(sLineWord, "stackLevel");
				memset(sstr ,0, ARRAY_SIZE(sstr));
				while (loc[strlen("stackLevel")+2+c] != ',')
				{
					sstr[c] = loc[strlen("stackLevel")+2+c];
					//printf("i=%d sstr=%c\n",c, sstr[c]);
					c++;
				}
				sstr[c] = '\0';
				tempstackLevelInt = atoi(sstr);

				c = 0;
				loc = strstr(sLineWord, "chargingProfilePurpose");
				memset(sstr ,0, ARRAY_SIZE(sstr));
				while (loc[3+strlen("chargingProfilePurpose")+c] != '\"')
				{
					sstr[c] = loc[3+strlen("chargingProfilePurpose")+c];
					c++;
				}
				sstr[c] = '\0';
				strcpy(tempchargingProfilePurposeStr, sstr);

				if((chargingProfileIdIsNULL == FALSE)&&(tempchargingProfileIdInt == chargingProfileIdInt))
				{
					//------- not write to  fptr2-------//
					sprintf(comfirmstr, "%s", ClearChargingProfileStatusEnumTypeStr[ClearChargingProfileStatusEnumType_Accepted] );
					//clearflag = TRUE;
				}
				else if((chargingProfilePurposeIsNULL == FALSE)&&(strcmp(tempchargingProfilePurposeStr, chargingProfilePurposeStr) == 0))
				{
					//------- not write to  fptr2-------//
					sprintf(comfirmstr, "%s", ClearChargingProfileStatusEnumTypeStr[ClearChargingProfileStatusEnumType_Accepted] );
				}
				else if((stackLevelIsNULL == FALSE) &&(tempstackLevelInt == stackLevelInt))
				{
					//------- not write to  fptr2-------//
					sprintf(comfirmstr, "%s", ClearChargingProfileStatusEnumTypeStr[ClearChargingProfileStatusEnumType_Accepted] );
				}
				else if(chargingProfileIdIsNULL && chargingProfilePurposeIsNULL && stackLevelIsNULL)
				{
					sprintf(comfirmstr, "%s", ClearChargingProfileStatusEnumTypeStr[ClearChargingProfileStatusEnumType_Accepted] );
				}
				else
				{
					fprintf(fptr2, sLineWord);//writing data into file
				}

				memset(sLineWord, 0, ARRAY_SIZE(sLineWord));

		   } //End of while ( fgets( sLineWord, sizeof sLineWord, fptr1 ) != NULL )

		   if(clearflag == TRUE)
		   {
			   fclose(fptr1);
			   fclose(fptr2);

			   sprintf(str,"rm -f %s",chargingProfiles[k]);
			   system(str);

			   // clear temp file
			   sprintf(str,"rm -f %s",temp);
			   system(str);

		   }
		   else
		   {
			   fclose(fptr1);
			   fclose(fptr2);

			   memset(str, 0, ARRAY_SIZE(str));
			   sprintf(str,"rm -f %s",chargingProfiles[k]);
			   system(str);

			   resultRename = rename(temp, chargingProfiles[k]);

			   if(resultRename == 0)
			   {
			       DEBUG_INFO("File ChargingProfile renamed successfully\n");
			   }
			   else
			   {
			       DEBUG_INFO("Error: unable to rename the ChargingProfile file\n");
			   }

			   if(comfirmstr[0]== 0)
			   {
			       sprintf(comfirmstr, "%s", ClearChargingProfileStatusEnumTypeStr[ClearChargingProfileStatusEnumType_Unknown] );
			   }

			    //Check chargingProfile is empty file
			    /*------ Read the file ----------------*/
			    fptr1=fopen(chargingProfiles[k],"r");
			    ch=fgetc(fptr1);
			    rewind(fptr1);
			    memset(sLineWord, 0, ARRAY_SIZE(sLineWord));
			    if(ch!=EOF)
			    {
			        while (fgets( sLineWord, sizeof sLineWord, fptr1) != NULL)
			        {
			        	str[strlen(sLineWord) - 1] = '\0'; // eat the newline fgets() stores
			        	if(sLineWord[0]=='\0')
			        	{
			        		isEmptyFile = TRUE;
			        		break;
			        	}
			        	else
			        	{
			        		isEmptyFile = FALSE;
			        		break;
			        	}
			        }
			    }
			    else
			    	isEmptyFile = TRUE;

			    fclose(fptr1);

			    if(isEmptyFile == TRUE)
			    {
			    	memset(str, 0, ARRAY_SIZE(str));
			        sprintf(str,"rm -f %s",chargingProfiles[k]);
			        system(str);
			    }
			}
	  }// End of while(int k=0; k < ChargePointCount; k++)
	}
	else if((connectorIsNULL == FALSE) && (connectorIdInt != 0) )
	{
		DEBUG_INFO("ChargeProfileCount = %d\n", ChargeProfileCount);
		for(int k=0; k < ChargeProfileCount; k++)
		{
		   fptr1 = fopen(chargingProfiles[k], "r");
		   fptr2 = fopen(temp, "w+");
		   //Check Charging Profile Count
		   while(fscanf(fptr1, "%s", word) != EOF)
		   {
			   //DEBUG_INFO("word=%s\n",word);
			   if(strstr(word, "id")!= NULL)
			   {
				   n_chargingProfile = n_chargingProfile + 1;
			   }
		   }
		   rewind(fptr1);
		   //search Charging Profile Element
		   //int i= 0;
		   while ( fgets( sLineWord, sizeof sLineWord, fptr1 ) != NULL )
		   {
			   //*************************tempconnectorIdInt*********************************/
			   loc = strstr(sLineWord, "connectorId");
			   c = 0;
			   memset(sstr ,0, ARRAY_SIZE(sstr));
			   while (loc[strlen("connectorId")+2+c] != ',')
			   {
				   sstr[c] = loc[strlen("connectorId")+2+c];
				   c++;
			   }
			   sstr[c] = '\0';
			   tempconnectorIdInt = atoi(sstr);

			   //id
			   c = 0;
			   loc = strstr(sLineWord, "id");
			   memset(sstr ,0, ARRAY_SIZE(sstr));
			   while (loc[strlen("id")+2+c] != ',')
			   {
				   sstr[c] = loc[strlen("id")+2+c];
				   //printf("i=%d sstr=%c\n",c, sstr[c]);
				   c++;
			   }
			   sstr[c] = '\0';
			   tempchargingProfileIdInt = atoi(sstr);

			   //stackLevel
			   c = 0;
			   loc = strstr(sLineWord, "stackLevel");
			   memset(sstr ,0, ARRAY_SIZE(sstr));
			   while (loc[strlen("stackLevel")+2+c] != ',')
			   {
				   sstr[c] = loc[strlen("stackLevel")+2+c];
				   //printf("i=%d sstr=%c\n",c, sstr[c]);
				   c++;
			   }
			   sstr[c] = '\0';
			   tempstackLevelInt = atoi(sstr);

			   c = 0;
			   loc = strstr(sLineWord, "chargingProfilePurpose");
			   memset(sstr ,0, ARRAY_SIZE(sstr));
			   while (loc[3+strlen("chargingProfilePurpose")+c] != '\"')
			   {
				   sstr[c] = loc[3+strlen("chargingProfilePurpose")+c];
				   c++;
			   }
			   sstr[c] = '\0';
			   strcpy(tempchargingProfilePurposeStr, sstr);

			   if((chargingProfileIdIsNULL == FALSE)&&(tempchargingProfileIdInt == chargingProfileIdInt))
			   {
				   //------- not write to  fptr2-------//
				   sprintf(comfirmstr, "%s", ClearChargingProfileStatusEnumTypeStr[ClearChargingProfileStatusEnumType_Accepted] );
				   //clearflag = TRUE;
			   }
			   else if((stackLevelIsNULL == FALSE) &&(tempstackLevelInt == stackLevelInt))
			   {
				   //------- not write to  fptr2-------//
				   sprintf(comfirmstr, "%s", ClearChargingProfileStatusEnumTypeStr[ClearChargingProfileStatusEnumType_Accepted] );
			   }
			   else if(stackLevelIsNULL == TRUE)
			   {
				   //Clear Whole File
				   sprintf(comfirmstr, "%s", ClearChargingProfileStatusEnumTypeStr[ClearChargingProfileStatusEnumType_Accepted] );
				   clearflag = TRUE;
				   break;
			   }
			   else
			   {
				   fprintf(fptr2, sLineWord);//writing data into file
			   }

			   memset(sLineWord, 0, ARRAY_SIZE(sLineWord));
		   }

		   if(clearflag == TRUE)
		   {
			   fclose(fptr1);
			   fclose(fptr2);

			   sprintf(str,"rm -f %s",chargingProfiles[k]);
			   system(str);

			   // clear temp file
			   sprintf(str,"rm -f %s",temp);
			   system(str);
		   }
		   else
		   {
			   fclose(fptr1);
			   fclose(fptr2);

			   sprintf(str,"rm -f %s",chargingProfiles[k]);
			   system(str);

			   resultRename = rename(temp, chargingProfiles[k]);

			   if(resultRename == 0)
			   {
				   DEBUG_INFO("File ChargingProfile renamed successfully");
			   }
			   else
			   {
				   DEBUG_INFO("Error: unable to rename the ChargingProfile file");
			   }

			   if(comfirmstr[0]== 0)
			   {
				   sprintf(comfirmstr, "%s", ClearChargingProfileStatusEnumTypeStr[ClearChargingProfileStatusEnumType_Unknown] );
			   }

			   //Check chargingProfile is empty file
			   /*------ Read the file ----------------*/
			   fptr1=fopen(chargingProfiles[k],"r");
			   ch=fgetc(fptr1);
			   rewind(fptr1);
			   memset(sLineWord, 0, ARRAY_SIZE(sLineWord));
			   if(ch!=EOF)
			   {
				   while (fgets( sLineWord, sizeof sLineWord, fptr1) != NULL)
				   {
					   str[strlen(sLineWord) - 1] = '\0'; // eat the newline fgets() stores

					   if(sLineWord[0]=='\0')
					   {
						   isEmptyFile = TRUE;
						   break;
					   }
					   else
					   {
						   isEmptyFile = FALSE;
						   break;
					   }
				   }
			   }
			   else
				   isEmptyFile = TRUE;

			   fclose(fptr1);

			   if(isEmptyFile == TRUE)
			   {
				   memset(str, 0, ARRAY_SIZE(str));
				   sprintf(str,"rm -f %s",chargingProfiles[k]);
				   system(str);
			   }
			   /*------- End of reading ---------------*/
		   }
	  } //  while(int k=0; k < ChargeProfileCount; k++)
	}// (connectorIsNULL == FALSE) && (connectorIdInt != 0)

end:
	if(strcmp(comfirmstr, ClearChargingProfileStatusEnumTypeStr[ClearChargingProfileStatusEnumType_Accepted]) == 0)
    {
		if(connectorIdInt == 0)
		{
			for(uint8_t idx=0;idx<gunTotalNumber;idx++)
			{
				checkChargingStationMaxProfile(86400, &ShmOCPP20Data->MaxChargingProfile, 0, TRUE);
				checkCompositeSchedule((idx+1), 86400, &ShmOCPP20Data->SmartChargingProfile[idx], 0, TRUE);
			}
		}
		else
		{
			checkChargingStationMaxProfile(86400, &ShmOCPP20Data->MaxChargingProfile, 0, TRUE);
			checkCompositeSchedule(connectorIdInt, 86400, &ShmOCPP20Data->SmartChargingProfile[connectorIdInt-1], 0, TRUE);
		}
    }


	sendClearChargingProfileConfirmation(uuid, comfirmstr);
	system("/bin/fsync -d /dev/mtdblock13;/bin/sync &");
	return result;
}

int handleClearDisplayMessageRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	json_object *ClearDisplayMessage;

	DEBUG_INFO("handleClearDisplayMessageRequest...\n");
	sprintf((char*)ShmOCPP20Data->ClearDisplayMessage.Response_status, ClearMessageStatusEnumTypeStr[ClearMessageStatusEnumType_Unknown]);
	ClearDisplayMessage = json_tokener_parse(payload);
	if(!is_error(ClearDisplayMessage))
	{
		// Required data
		if(json_object_object_get(ClearDisplayMessage, "id") != NULL)
		{
			ShmOCPP20Data->ClearDisplayMessage.id = json_object_get_double(json_object_object_get(ClearDisplayMessage, "id"));
			sprintf((char*)ShmOCPP20Data->ClearDisplayMessage.Response_status, ClearMessageStatusEnumTypeStr[ClearMessageStatusEnumType_Accepted]);
		}
	}
	json_object_put(ClearDisplayMessage);

	sendCostUpdatedConfirmation(uuid);

	return result;
}

int handleClearVariableMonitoringRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	json_object *ClearVariableMonitorin;

	DEBUG_INFO("handleClearVariableMonitoringRequest...\n");
	ClearVariableMonitorin = json_tokener_parse(payload);
	if(!is_error(ClearVariableMonitorin))
	{
		// Required data
		if(json_object_array_length(json_object_object_get(ClearVariableMonitorin, "id")) <= ARRAY_SIZE(ShmOCPP20Data->ClearVariableMonitoring.id))
		{
			for(int idx=0;idx<json_object_array_length(json_object_object_get(ClearVariableMonitorin, "id"));idx++)
			{
				ShmOCPP20Data->ClearVariableMonitoring.id[idx] = json_object_get_int(json_object_array_get_idx(json_object_object_get(ClearVariableMonitorin, "id"), idx));

				/*
				 * TODO:
				 * 	1. Check response
				 */
				ShmOCPP20Data->ClearVariableMonitoring.Response_clearMonitoringResult[idx].id = ShmOCPP20Data->ClearVariableMonitoring.id[idx];
				strcpy((char*)ShmOCPP20Data->ClearVariableMonitoring.Response_clearMonitoringResult[idx].status, ClearMonitoringStatusEnumTypeStr[ClearMonitoringStatusEnumType_Accepted]);
			}

			sendClearVariableMonitoringConfirmation(uuid, json_object_array_length(json_object_object_get(ClearVariableMonitorin, "id")));
		}
	}
	json_object_put(ClearVariableMonitorin);

	return result;
}

int handleCostUpdatedRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	json_object *CostUpdate;

	DEBUG_INFO("handleCostUpdatedRequest...\n");
	CostUpdate = json_tokener_parse(payload);
	if(!is_error(CostUpdate))
	{
		// Required data
		if(json_object_object_get(CostUpdate, "totalCost") != NULL)
		{
			ShmOCPP20Data->CostUpdated.totalCost = json_object_get_double(json_object_object_get(CostUpdate, "totalCost"));
		}

		if(json_object_object_get(CostUpdate, "transactionId") != NULL)
		{
			sprintf((char*)ShmOCPP20Data->CostUpdated.transactionId, "%s", json_object_get_string(json_object_object_get(CostUpdate, "transactionId")));
		}
	}
	json_object_put(CostUpdate);

	sendCostUpdatedConfirmation(uuid);

	return result;
}

int handleCustomerInformationRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	json_object *CustomerInformation;

	DEBUG_INFO("handleCustomerInformationRequest...\n");
	CustomerInformation = json_tokener_parse(payload);
	if(!is_error(CustomerInformation))
	{
		// Required data
		if(json_object_object_get(CustomerInformation, "requestId") != NULL)
		{
			ShmOCPP20Data->CustomerInformation.requestId = json_object_get_int(json_object_object_get(CustomerInformation, "requestId"));
		}

		if(json_object_object_get(CustomerInformation, "report") != NULL)
		{
			ShmOCPP20Data->CustomerInformation.report = json_object_get_boolean(json_object_object_get(CustomerInformation, "report"));
		}

		if(json_object_object_get(CustomerInformation, "clear") != NULL)
		{
			ShmOCPP20Data->CustomerInformation.report = json_object_get_boolean(json_object_object_get(CustomerInformation, "clear"));
		}

		// Optional data
		if(json_object_object_get(CustomerInformation, "idToken") != NULL)
		{
			if(json_object_object_get(json_object_object_get(CustomerInformation, "idToken"), "idToken") != NULL)
			{
				sprintf((char*)ShmOCPP20Data->CustomerInformation.idToken.idToken, "%s", json_object_get_string(json_object_object_get(json_object_object_get(CustomerInformation, "idToken"), "idToken")));
			}

			if(json_object_object_get(json_object_object_get(CustomerInformation, "idToken"), "type") != NULL)
			{
				sprintf((char*)ShmOCPP20Data->CustomerInformation.idToken.type, "%s", json_object_get_string(json_object_object_get(json_object_object_get(CustomerInformation, "idToken"), "type")));
			}
		}

		if(json_object_object_get(CustomerInformation, "customerCertificate") != NULL)
		{
			if(json_object_object_get(json_object_object_get(CustomerInformation, "customerCertificate"), "hashAlgorithm") != NULL)
			{
				sprintf((char*)ShmOCPP20Data->CustomerInformation.customerCertificate.hashAlgorithm, "%s", json_object_get_string(json_object_object_get(json_object_object_get(CustomerInformation, "customerCertificate"), "hashAlgorithm")));
			}

			if(json_object_object_get(json_object_object_get(CustomerInformation, "customerCertificate"), "issuerNameHash") != NULL)
			{
				sprintf((char*)ShmOCPP20Data->CustomerInformation.customerCertificate.issuerNameHash, "%s", json_object_get_string(json_object_object_get(json_object_object_get(CustomerInformation, "customerCertificate"), "issuerNameHash")));
			}

			if(json_object_object_get(json_object_object_get(CustomerInformation, "customerCertificate"), "issuerKeyHash") != NULL)
			{
				sprintf((char*)ShmOCPP20Data->CustomerInformation.customerCertificate.issuerKeyHash, "%s", json_object_get_string(json_object_object_get(json_object_object_get(CustomerInformation, "customerCertificate"), "issuerKeyHash")));
			}

			if(json_object_object_get(json_object_object_get(CustomerInformation, "customerCertificate"), "serialNumber") != NULL)
			{
				sprintf((char*)ShmOCPP20Data->CustomerInformation.customerCertificate.serialNumber, "%s", json_object_get_string(json_object_object_get(json_object_object_get(CustomerInformation, "customerCertificate"), "serialNumber")));
			}
		}
		strcpy((char*)ShmOCPP20Data->CustomerInformation.Response_status, CustomerInformationStatusEnumTypeStr[CustomerInformationStatusEnumType_Accepted]);
		ShmOCPP20Data->SpMsg.bits.NotifyCustomerInformationReq = ON;
	}
	else
		strcpy((char*)ShmOCPP20Data->CustomerInformation.Response_status, CustomerInformationStatusEnumTypeStr[CustomerInformationStatusEnumType_Rejected]);

	json_object_put(CustomerInformation);

	sendCustomerInformationConfirmation(uuid);

	return result;
}

void createFirmwareVersionByDataTransfer(void)
{
	json_object *FirmwareDataTransfer = json_object_new_object();

	// AC & DC model
	json_object_object_add(FirmwareDataTransfer, "CsuBootLoadFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.CsuBootLoadFwRev));
	json_object_object_add(FirmwareDataTransfer, "CsuKernelFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.CsuKernelFwRev));
	json_object_object_add(FirmwareDataTransfer, "CsuRootFsFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev));
	json_object_object_add(FirmwareDataTransfer, "CsuPrimFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev));

	// DC model
	if((ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D'))
	{
		if((gunType[1] != GUN_TYPE_UNKNOWN) ||
		   (gunType[2] != GUN_TYPE_UNKNOWN) ||
		   (gunType[3] != GUN_TYPE_UNKNOWN))
		{
			json_object_object_add(FirmwareDataTransfer, "Connector2FwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.Connector2FwRev));
		}

		if((ShmSysConfigAndInfo->SysConfig.ModelName[1]!='B') && (ShmSysConfigAndInfo->SysConfig.ModelName[1]!='K') && (ShmSysConfigAndInfo->SysConfig.ModelName[1]!='O'))
		{
			// DS DM DW
			json_object_object_add(FirmwareDataTransfer, "FanModuleFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.FanModuleFwRev));
			json_object_object_add(FirmwareDataTransfer, "RelayModuleFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev));
			json_object_object_add(FirmwareDataTransfer, "LedModuleFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.LedModuleFwRev));
			json_object_object_add(FirmwareDataTransfer, "Connector1FwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.Connector1FwRev));
			json_object_object_add(FirmwareDataTransfer, "PsuPrimFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.PsuPrimFwRev));
			json_object_object_add(FirmwareDataTransfer, "PsuSecFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.PsuSecFwRev));
		}
		else
		{
			json_object_object_add(FirmwareDataTransfer, "FanModuleFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.FanModuleFwRev));
			json_object_object_add(FirmwareDataTransfer, "RelayModuleFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev));
			json_object_object_add(FirmwareDataTransfer, "PsuPrimFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.PsuPrimFwRev));
			json_object_object_add(FirmwareDataTransfer, "PsuSecFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.PsuSecFwRev));


			json_object_object_add(FirmwareDataTransfer, "DD0_CsuBootLoadFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[0].CsuBootLoadFwRev));
			json_object_object_add(FirmwareDataTransfer, "DD0_CsuKernelFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[0].CsuKernelFwRev));
			json_object_object_add(FirmwareDataTransfer, "DD0_CsuRootFsFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[0].CsuRootFsFwRev));
			json_object_object_add(FirmwareDataTransfer, "DD0_CsuPrimFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[0].CsuPrimFwRev));
			json_object_object_add(FirmwareDataTransfer, "DD0_FanModuleFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[0].FanModuleFwRev));
			json_object_object_add(FirmwareDataTransfer, "DD0_RelayModuleFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[0].RelayModuleFwRev));
			json_object_object_add(FirmwareDataTransfer, "DD0_LedModuleFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[0].LedModuleFwRev));
			json_object_object_add(FirmwareDataTransfer, "DD0_Connector1FwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[0].Connector1FwRev));
			json_object_object_add(FirmwareDataTransfer, "DD0_Connector2FwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[0].Connector2FwRev));

			if(strlen((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[1].CsuBootLoadFwRev) > 0)
				json_object_object_add(FirmwareDataTransfer, "DD1_CsuBootLoadFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[1].CsuBootLoadFwRev));

			if(strlen((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[1].CsuKernelFwRev) > 0)
				json_object_object_add(FirmwareDataTransfer, "DD1_CsuKernelFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[1].CsuKernelFwRev));

			if(strlen((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[1].CsuRootFsFwRev) > 0)
				json_object_object_add(FirmwareDataTransfer, "DD1_CsuRootFsFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[1].CsuRootFsFwRev));

			if(strlen((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[1].CsuPrimFwRev) > 0)
				json_object_object_add(FirmwareDataTransfer, "DD1_CsuPrimFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[1].CsuPrimFwRev));

			if(strlen((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[1].FanModuleFwRev) > 0)
				json_object_object_add(FirmwareDataTransfer, "DD1_FanModuleFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[1].FanModuleFwRev));

			if(strlen((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[1].RelayModuleFwRev) > 0)
				json_object_object_add(FirmwareDataTransfer, "DD1_RelayModuleFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[1].RelayModuleFwRev));

			if(strlen((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[1].LedModuleFwRev) > 0)
				json_object_object_add(FirmwareDataTransfer, "DD1_LedModuleFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[1].LedModuleFwRev));

			if(strlen((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[1].Connector1FwRev) > 0)
				json_object_object_add(FirmwareDataTransfer, "DD1_Connector1FwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[1].Connector1FwRev));

			if(strlen((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[1].Connector2FwRev) > 0)
				json_object_object_add(FirmwareDataTransfer, "D11_Connector2FwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[1].Connector2FwRev));
		}
	}

	// 4G model
	if((ShmSysConfigAndInfo->SysConfig.ModelName[10]=='T'))
	{
		json_object_object_add(FirmwareDataTransfer, "TelcomModemFwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSoftwareVer));
	}

	sprintf((char*)ShmOCPP20Data->DataTransfer[0].Response_data, json_object_to_json_string_ext(FirmwareDataTransfer, JSON_C_TO_STRING_PLAIN));

	json_object_put(FirmwareDataTransfer);
}

int handleDataTransferRequest(char *uuid, char *payload)
{
	mtrace();
	int result = PASS;

	DEBUG_INFO("handleDataTransferRequest...\n");
	if((uuid != NULL) && (payload != NULL))
	{
		json_object *DataTransfer;
		DataTransfer = json_tokener_parse(payload);

		if(!is_error(DataTransfer))
		{
			// Required data
			if(json_object_object_get(DataTransfer, "vendorId") != NULL)
				sprintf((char*)ShmOCPP20Data->DataTransfer[0].vendorId, "%s", json_object_get_string(json_object_object_get(DataTransfer, "vendorId")));

			// Optional data
			if(json_object_object_get(DataTransfer, "messageId") != NULL)
				sprintf((char*)ShmOCPP20Data->DataTransfer[0].messageId, "%s", json_object_get_string(json_object_object_get(DataTransfer, "messageId")));

			if(json_object_object_get(DataTransfer, "data") != NULL)
				sprintf((char*)ShmOCPP20Data->DataTransfer[0].data, "%s", json_object_get_string(json_object_object_get(DataTransfer, "data")));

			result = PASS;
		}
		json_object_put(DataTransfer);

		if(strstr((char*)ShmOCPP20Data->DataTransfer[0].messageId, "ID_FirmwareVersion") != NULL)
		{
			// Send all moudle firmware version on EVSE
			createFirmwareVersionByDataTransfer();
			strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_Accepted]);
		}
		else if(strstr((char*)ShmOCPP20Data->DataTransfer[0].messageId, "ID_Tmate") != NULL)
		{
			system("/usr/bin/run_tmate_restart.sh &");

			strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_Accepted]);
		}
		else if(strstr((char*)ShmOCPP20Data->DataTransfer[0].messageId, "ID_ChargingPreference") != NULL)
		{
			json_object *data;
			data = json_tokener_parse((char*)ShmOCPP20Data->DataTransfer[0].data);
			if(!is_error(data))
			{
				if((json_object_object_get(data, "ConnectorId") != NULL) && (json_object_get_int(json_object_object_get(data, "ConnectorId")) > 0) && (json_object_get_int(json_object_object_get(data, "ConnectorId")) <= gunTotalNumber))
				{
					DEBUG_INFO("ChargeingPreference connector id: %d\n", json_object_get_int(json_object_object_get(data, "ConnectorId")));
					memset(&ShmOCPP20Data->SessionTarget[json_object_get_int(json_object_object_get(data, "ConnectorId"))], 0x00, sizeof(struct StructSessionTarget));

					if(json_object_object_get(data, "SOC") != NULL)
					{
						ShmOCPP20Data->SessionTarget[json_object_get_int(json_object_object_get(data, "ConnectorId"))].targetSoc = json_object_get_int(json_object_object_get(data, "SOC"));
						DEBUG_INFO("ChargeingPreference target soc: %d\n", json_object_get_int(json_object_object_get(data, "SOC")));
					}

					if(json_object_object_get(data, "Energy") != NULL)
					{
						ShmOCPP20Data->SessionTarget[json_object_get_int(json_object_object_get(data, "ConnectorId"))].targetEnergy = json_object_get_int(json_object_object_get(data, "Energy"));
						DEBUG_INFO("ChargeingPreference target energy: %d KWH\n", json_object_get_int(json_object_object_get(data, "Energy")));
					}

					if(json_object_object_get(data, "Duration") != NULL)
					{
						ShmOCPP20Data->SessionTarget[json_object_get_int(json_object_object_get(data, "ConnectorId"))].targetDuration = json_object_get_int(json_object_object_get(data, "Duration"));
						DEBUG_INFO("ChargeingPreference target duration: %d minutes\n", json_object_get_int(json_object_object_get(data, "Duration")));
					}

					strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_Accepted]);
				}
				else
				{
					strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_Rejected]);
					sprintf((char*)ShmOCPP20Data->DataTransfer[0].Response_data, "Connector id must > 0.");
				}
			}
			else
			{
				strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_Rejected]);
				sprintf((char*)ShmOCPP20Data->DataTransfer[0].Response_data, "Configuration content something wrong.");
			}
			json_object_put(data);
		}
		else if(strstr((char*)ShmOCPP20Data->DataTransfer[0].messageId, "SetLEDBar") != NULL)
		{
			json_object *data;
			data = json_tokener_parse((char*)ShmOCPP20Data->DataTransfer[0].data);
			if(!is_error(data))
			{
				ShmSysConfigAndInfo->SysConfig.LedInfo.Intensity = json_object_get_int(json_object_object_get(data, "Intensity"));

				ShmSysConfigAndInfo->SysConfig.LedInfo.Red[0] = json_object_get_int(json_object_object_get(json_object_object_get(data, "Idle"), "R"));
				ShmSysConfigAndInfo->SysConfig.LedInfo.Green[0]= json_object_get_int(json_object_object_get(json_object_object_get(data, "Idle"), "G"));
				ShmSysConfigAndInfo->SysConfig.LedInfo.Blue[0] = json_object_get_int(json_object_object_get(json_object_object_get(data, "Idle"), "B"));
				ShmSysConfigAndInfo->SysConfig.LedInfo.Red[1] = json_object_get_int(json_object_object_get(json_object_object_get(data, "Charging"), "R"));
				ShmSysConfigAndInfo->SysConfig.LedInfo.Green[1]= json_object_get_int(json_object_object_get(json_object_object_get(data, "Charging"), "G"));
				ShmSysConfigAndInfo->SysConfig.LedInfo.Blue[1] = json_object_get_int(json_object_object_get(json_object_object_get(data, "Charging"), "B"));
				ShmSysConfigAndInfo->SysConfig.LedInfo.Red[2] = json_object_get_int(json_object_object_get(json_object_object_get(data, "Fault"), "R"));
				ShmSysConfigAndInfo->SysConfig.LedInfo.Green[2]= json_object_get_int(json_object_object_get(json_object_object_get(data, "Fault"), "G"));
				ShmSysConfigAndInfo->SysConfig.LedInfo.Blue[2] = json_object_get_int(json_object_object_get(json_object_object_get(data, "Fault"), "B"));

				strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_Accepted]);
			}
			else
			{
				strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_Rejected]);
				sprintf((char*)ShmOCPP20Data->DataTransfer[0].Response_data, "Configuration content something wrong.");
			}
			json_object_put(data);
		}
		else if(strstr((char*)ShmOCPP20Data->DataTransfer[0].messageId, "ID_ConfigQR") != NULL)
		{
			json_object *data;
			data = json_tokener_parse((char*)ShmOCPP20Data->DataTransfer[0].data);

			if(!is_error(data))
			{
				strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_Accepted]);

				if(json_object_object_get(data, "Content_Type") != NULL)
				{
					if((0 <= json_object_get_int(json_object_object_get(data, "Content_Type"))) && (json_object_get_int(json_object_object_get(data, "Content_Type")) <= 1))
					{
						ShmSysConfigAndInfo->SysConfig.QRCodeMadeMode = json_object_get_int(json_object_object_get(data, "Content_Type"));

						if(json_object_object_get(data, "Customization_Conent") != NULL)
						{
							sprintf((char*)ShmSysConfigAndInfo->SysConfig.QRCodeContent, "%s", json_object_get_string(json_object_object_get(data, "Customization_Conent")));
						}
					}
					else
						strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_Rejected]);
				}

				StoreUsrConfigData(&ShmSysConfigAndInfo->SysConfig);
			}
			else
			{
				strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_Rejected]);
				strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_data, "Configuration content something wrong.");
			}
			json_object_put(data);
		}
		else if(strstr((char*)ShmOCPP20Data->DataTransfer[0].messageId, "ID_DisplayLcdPage") != NULL)
		{
			json_object *data;
			data = json_tokener_parse((char*)ShmOCPP20Data->DataTransfer[0].data);

			if(!is_error(data))
			{
				strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_Accepted]);

				if(json_object_object_get(data, "ConnectorId") != NULL)
				{
                                        ShmSysConfigAndInfo->SysInfo.LcdOveride.connectorId = json_object_get_int(json_object_object_get(data, "ConnectorId"));
				}

				if(json_object_object_get(data, "Page_Index") != NULL)
				{
					ShmSysConfigAndInfo->SysInfo.LcdOveride.page_index = json_object_get_int(json_object_object_get(data, "Page_Index"));
				}

				if(json_object_object_get(data, "Duration") != NULL)
				{
					ShmSysConfigAndInfo->SysInfo.LcdOveride.duration = json_object_get_int(json_object_object_get(data, "Duration"));
				}

				ShmSysConfigAndInfo->SysInfo.LcdOveride.isOverideReq = ON;
			}
			else
			{
				strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_Rejected]);
				strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_data, "Configuration content something wrong.");
			}
			json_object_put(data);
		}
		else if(strstr((char*)ShmOCPP20Data->DataTransfer[0].messageId, "ID_CpConfiguration") != NULL)
		{
			json_object *data;
			data = json_tokener_parse((char*)ShmOCPP20Data->DataTransfer[0].data);

			if(!is_error(data))
			{
				strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_Accepted]);
				sprintf((char*)ShmOCPP20Data->DataTransfer[0].Response_data, " ");

				if(json_object_object_get(data, "MaxChargingCurrent") != NULL)
				{
					if(json_object_get_int(json_object_object_get(data, "MaxChargingCurrent")) >= 0)
						ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent = json_object_get_int(json_object_object_get(data, "MaxChargingCurrent"));
					else
					{
						strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_Rejected]);
						sprintf((char*)ShmOCPP20Data->DataTransfer[0].Response_data, "Configuration content something wrong.");
					}
				}

				if(json_object_object_get(data, "MaxChargingDuration") != NULL)
				{
					if(json_object_get_int(json_object_object_get(data, "MaxChargingDuration")) >= 0)
						ShmSysConfigAndInfo->SysConfig.MaxChargingDuration = json_object_get_int(json_object_object_get(data, "MaxChargingDuration"));
					else
					{
						strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_Rejected]);
						sprintf((char*)ShmOCPP20Data->DataTransfer[0].Response_data, "Configuration content something wrong.");
					}
				}

				if(json_object_object_get(data, "MaxChargingEnergy") != NULL)
				{
					if(json_object_get_int(json_object_object_get(data, "MaxChargingEnergy")) >= 0)
						ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy = json_object_get_int(json_object_object_get(data, "MaxChargingEnergy"));
					else
					{
						strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_Rejected]);
						sprintf((char*)ShmOCPP20Data->DataTransfer[0].Response_data, "Configuration content something wrong.");
					}
				}

				if(json_object_object_get(data, "MaxChargingPower") != NULL)
				{
					if(json_object_get_int(json_object_object_get(data, "MaxChargingPower")) >= 0)
						ShmSysConfigAndInfo->SysConfig.MaxChargingPower = json_object_get_int(json_object_object_get(data, "MaxChargingPower"));
					else
					{
						strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_Rejected]);
						sprintf((char*)ShmOCPP20Data->DataTransfer[0].Response_data, "Configuration content something wrong.");
					}
				}

				if(json_object_object_get(data, "OfflineMaxChargeEnergy") != NULL)
				{
					if(json_object_get_int(json_object_object_get(data, "OfflineMaxChargeEnergy")) >= 0)
						ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy = json_object_get_int(json_object_object_get(data, "OfflineMaxChargeEnergy"));
					else
					{
						strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_Rejected]);
						sprintf((char*)ShmOCPP20Data->DataTransfer[0].Response_data, "Configuration content something wrong.");
					}
				}

				if(json_object_object_get(data, "OfflinePolicy") != NULL)
				{
					if((json_object_get_int(json_object_object_get(data, "OfflinePolicy")) == 0) ||
						(json_object_get_int(json_object_object_get(data, "OfflinePolicy")) == 2) ||
						(json_object_get_int(json_object_object_get(data, "OfflinePolicy")) == 3))
						ShmSysConfigAndInfo->SysConfig.OfflinePolicy = json_object_get_int(json_object_object_get(data, "OfflinePolicy"));
					else
					{
						strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_Rejected]);
						sprintf((char*)ShmOCPP20Data->DataTransfer[0].Response_data, "Configuration content something wrong.");
					}
				}

				if(json_object_object_get(data, "isAuthentication") != NULL)
				{
					switch(json_object_get_int(json_object_object_get(data, "isAuthentication")))
					{
						case 0:
						case 1:
							ShmSysConfigAndInfo->SysConfig.AuthorisationMode = json_object_get_int(json_object_object_get(data, "isAuthentication"))^1;
							break;
						default:
							strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_Rejected]);
							sprintf((char*)ShmOCPP20Data->DataTransfer[0].Response_data, "Configuration content something wrong.");
							break;
					}
				}

				if(strstr((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_Accepted]) != NULL)
					StoreUsrConfigData(&ShmSysConfigAndInfo->SysConfig);
			}
			else
			{
				strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_Rejected]);
				sprintf((char*)ShmOCPP20Data->DataTransfer[0].Response_data, "Configuration content something wrong.");
			}
			json_object_put(data);
		}
		else
		{
			// Can not find valid message id
			strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_UnknownMessageId]);
			sprintf((char*)ShmOCPP20Data->DataTransfer[0].Response_data,"vendorId: %s messageId: %s data: %s"
																											,ShmOCPP20Data->DataTransfer[0].vendorId
																											,ShmOCPP20Data->DataTransfer[0].messageId
																											,ShmOCPP20Data->DataTransfer[0].data);
		}
	}
	else
	{
		strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_UnknownMessageId]);
		result = FAIL;
	}

	sendDataTransferConfirmation(uuid, 0);

	return result;
}

int handleDeleteCertificateRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	json_object *DeleteCertificate;

	DEBUG_INFO("handleDeleteCertificateRequest...\n");
	DeleteCertificate = json_tokener_parse(payload);
	if(!is_error(DeleteCertificate))
	{
		memset(&ShmOCPP20Data->DeleteCertificate, 0, sizeof(struct DeleteCertificate_20));
		memcpy(&ShmOCPP20Data->DeleteCertificate.guid, uuid, ARRAY_SIZE(ShmOCPP20Data->DeleteCertificate.guid));
		// Required data
		if(json_object_object_get(DeleteCertificate, "certificateHashData") != NULL)
		{
			if(json_object_object_get(json_object_object_get(DeleteCertificate, "certificateHashData"), "hashAlgorithm") != NULL)
			{
				sprintf((char*)ShmOCPP20Data->DeleteCertificate.certificateHashData.hashAlgorithm, "%s", json_object_get_string(json_object_object_get(json_object_object_get(DeleteCertificate, "certificateHashData"), "hashAlgorithm")));
			}

			if(json_object_object_get(json_object_object_get(DeleteCertificate, "certificateHashData"), "issuerNameHash") != NULL)
			{
				sprintf((char*)ShmOCPP20Data->DeleteCertificate.certificateHashData.issuerNameHash, "%s", json_object_get_string(json_object_object_get(json_object_object_get(DeleteCertificate, "certificateHashData"), "issuerNameHash")));
			}

			if(json_object_object_get(json_object_object_get(DeleteCertificate, "certificateHashData"), "issuerKeyHash") != NULL)
			{
				sprintf((char*)ShmOCPP20Data->DeleteCertificate.certificateHashData.issuerKeyHash, "%s", json_object_get_string(json_object_object_get(json_object_object_get(DeleteCertificate, "certificateHashData"), "issuerKeyHash")));
			}

			if(json_object_object_get(json_object_object_get(DeleteCertificate, "certificateHashData"), "serialNumber") != NULL)
			{
				sprintf((char*)ShmOCPP20Data->DeleteCertificate.certificateHashData.serialNumber, "%s", json_object_get_string(json_object_object_get(json_object_object_get(DeleteCertificate, "certificateHashData"), "serialNumber")));
			}

			/*
			 * TODO:
			 * 	1. Delete certification and response
			 */
			if(strstr((char*)ShmOCPP20Data->DeleteCertificate.certificateHashData.hashAlgorithm, HashAlgorithmEnumTypeStr[HashAlgorithmEnumType_SHA256]) != NULL)
			{

			}
			else if(strstr((char*)ShmOCPP20Data->DeleteCertificate.certificateHashData.hashAlgorithm, HashAlgorithmEnumTypeStr[HashAlgorithmEnumType_SHA384]) != NULL)
			{

			}
			else
			{

			}

			strcpy((char*)ShmOCPP20Data->GetBaseReport.Response_status, DeleteCertificateStatusEnumTypeStr[DeleteCertificateStatusEnumType_Accepted]);
		}
	}
	else
		strcpy((char*)ShmOCPP20Data->GetBaseReport.Response_status, DeleteCertificateStatusEnumTypeStr[DeleteCertificateStatusEnumType_Failed]);

	json_object_put(DeleteCertificate);

	sendDeleteCertificateConfirmation(uuid);
	system("/bin/fsync -d /dev/mtdblock13;/bin/sync &");
	return result;
}

int handleGetBaseReportRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	json_object *GetBaseRepor;

	DEBUG_INFO("handleGetBaseReportRequest...\n");
	GetBaseRepor = json_tokener_parse(payload);
	if(!is_error(GetBaseRepor))
	{
		memset(&ShmOCPP20Data->GetBaseReport, 0, sizeof(struct GetBaseReport_20));
		memcpy(&ShmOCPP20Data->GetBaseReport.guid, uuid, ARRAY_SIZE(ShmOCPP20Data->GetBaseReport.guid));
		// Required data
		if(json_object_object_get(GetBaseRepor, "requestId") != NULL)
		{
			ShmOCPP20Data->GetBaseReport.requestId = json_object_get_int(json_object_object_get(GetBaseRepor, "requestId"));
		}

		if(json_object_object_get(GetBaseRepor, "reportBase") != NULL)
		{
			sprintf((char*)ShmOCPP20Data->GetBaseReport.reportBase, "%s", json_object_get_string(json_object_object_get(GetBaseRepor, "reportBase")));
		}

		if(strcmp((char*)ShmOCPP20Data->GetBaseReport.reportBase, ReportBaseEnumTypeStr[ReportBaseEnumType_SummaryInventory]) == 0)
			strcpy((char*)ShmOCPP20Data->GetBaseReport.Response_status, GenericDeviceModelStatusEnumTypeStr[GenericDeviceModelStatusEnumType_NotSupported]);
		else
			strcpy((char*)ShmOCPP20Data->GetBaseReport.Response_status, GenericDeviceModelStatusEnumTypeStr[GenericDeviceModelStatusEnumType_Accepted]);
	}
	else
		strcpy((char*)ShmOCPP20Data->GetBaseReport.Response_status, GenericDeviceModelStatusEnumTypeStr[GenericDeviceModelStatusEnumType_NotSupported]);
	json_object_put(GetBaseRepor);

	sendGetBaseReportConfirmation(uuid);


	return result;
}

int handleGetChargingProfilesRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	int gun_index = -1;
	json_object *GetChargingProfiles;

	DEBUG_INFO("handleGetChargingProfilesRequest...\n");
	GetChargingProfiles = json_tokener_parse(payload);
	if(!is_error(GetChargingProfiles))
	{
		if(json_object_object_get(GetChargingProfiles, "evseId") != NULL)
		{
			gun_index = json_object_get_int(json_object_object_get(GetChargingProfiles, "evseId"))>0?json_object_get_int(json_object_object_get(GetChargingProfiles, "evseId"))-1:0;
		}

		if(gun_index >-1)
		{
			memset(&ShmOCPP20Data->GetChargingProfiles[gun_index], 0, sizeof(struct GetChargingProfiles_20));
			memcpy(&ShmOCPP20Data->GetChargingProfiles[gun_index].guid, uuid, ARRAY_SIZE(ShmOCPP20Data->GetChargingProfiles[gun_index].guid));
			// Required data
			if(json_object_object_get(GetChargingProfiles, "requestId") != NULL)
			{
				ShmOCPP20Data->GetChargingProfiles[gun_index].requestId = json_object_get_int(json_object_object_get(GetChargingProfiles, "requestId"));
			}

			if(json_object_object_get(GetChargingProfiles, "chargingProfile") != NULL)
			{
				if(json_object_object_get(json_object_object_get(GetChargingProfiles, "chargingProfile"), "chargingProfilePurpose") != NULL)
				{
					sprintf((char*)ShmOCPP20Data->GetChargingProfiles[gun_index].chargingProfile.chargingProfilePurpose, "%s", json_object_get_string(json_object_object_get(json_object_object_get(GetChargingProfiles, "chargingProfile"), "chargingProfilePurpose")));
				}

				if(json_object_object_get(json_object_object_get(GetChargingProfiles, "chargingProfile"), "stackLevel") != NULL)
				{
					ShmOCPP20Data->GetChargingProfiles[gun_index].chargingProfile.stackLevel = json_object_get_int(json_object_object_get(json_object_object_get(GetChargingProfiles, "chargingProfile"), "stackLevel"));
				}

				if(json_object_object_get(json_object_object_get(GetChargingProfiles, "chargingProfile"), "chargingLimitSource") != NULL)
				{
					for(int idx=0;idx<json_object_array_length(json_object_object_get(json_object_object_get(GetChargingProfiles, "chargingProfile"), "chargingLimitSource"));idx++)
					{
						sprintf((char*)ShmOCPP20Data->GetChargingProfiles[gun_index].chargingProfile.chargingLimitSource[idx], "%s", json_object_get_string(json_object_array_get_idx(json_object_object_get(json_object_object_get(GetChargingProfiles, "chargingProfile"), "chargingLimitSource"), idx)));
					}
				}

				if(json_object_object_get(json_object_object_get(GetChargingProfiles, "chargingProfile"), "chargingProfileId") != NULL)
				{
					for(int idx=0;idx<json_object_array_length(json_object_object_get(json_object_object_get(GetChargingProfiles, "chargingProfile"), "chargingProfileId"));idx++)
					{
						ShmOCPP20Data->GetChargingProfiles[gun_index].chargingProfile.chargingProfileId[idx] = json_object_get_int(json_object_array_get_idx(json_object_object_get(json_object_object_get(GetChargingProfiles, "chargingProfile"), "chargingProfileId"), idx));
					}
				}
			}

			strcpy((char*)ShmOCPP20Data->GetChargingProfiles[gun_index].Response_status, GetChargingProfileStatusEnumTypeStr[GetChargingProfileStatusEnumType_Accepted]);
		}
		else
			strcpy((char*)ShmOCPP20Data->GetChargingProfiles[gun_index].Response_status, GetChargingProfileStatusEnumTypeStr[GetChargingProfileStatusEnumType_NoProfiles]);
	}
	json_object_put(GetChargingProfiles);

	sendGetChargingProfilesConfirmation(uuid, gun_index);

	return result;
}

int handleGetCompositeScheduleRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	int connectorIdInt, durationInt;
	char chargingRateUnitStr[4]={0};
	char comfirmstr[20];
    int confirmPeriods = 0;

	DEBUG_INFO("handleGetCompositeScheduleRequest...\n");
	json_object *GetCompositeSchedule;
	GetCompositeSchedule = json_tokener_parse(payload);
	if(!is_error(GetCompositeSchedule))
	{
		// Required data
		if(json_object_object_get(GetCompositeSchedule, "evseId") != NULL)
			connectorIdInt = json_object_get_int(json_object_object_get(GetCompositeSchedule, "evseId"));
		else
			connectorIdInt = -1;

		if(json_object_object_get(GetCompositeSchedule, "duration"))
			durationInt = json_object_get_int(json_object_object_get(GetCompositeSchedule, "duration"));
		else
			durationInt = 86400;

		// Optional data
		if(json_object_object_get(GetCompositeSchedule, "chargingRateUnit") != NULL)
			sprintf((char*)chargingRateUnitStr, "%s", json_object_get_string(json_object_object_get(GetCompositeSchedule, "chargingRateUnit")));
	}
	json_object_put(GetCompositeSchedule);

	memset(ShmOCPP20Data->GetCompositeSchedule, 0, sizeof(struct StructChargingSchedulePeriod)*gunTotalNumber);
	if((connectorIdInt == 0) ||
	   ((connectorIdInt > 0) && ((connectorIdInt -1) < gunTotalNumber)))
  	{
		int gun_index = (connectorIdInt==0?0:connectorIdInt-1);
		struct ChargingProfileType tmpProfile[1];

		memset(&ShmOCPP20Data->GetCompositeSchedule[gun_index], 0, sizeof(struct GetCompositeSchedule_20));
		memcpy(&ShmOCPP20Data->GetCompositeSchedule[gun_index].guid, uuid, ARRAY_SIZE(ShmOCPP20Data->GetCompositeSchedule[gun_index].guid));

		if(strstr(chargingRateUnitStr, "W") != NULL || strlen(chargingRateUnitStr) == 0)
		{
			sprintf((char*)ShmOCPP20Data->GetCompositeSchedule[gun_index].Response_schedule.chargingSchedule.chargingRateUnit, "W");
			checkCompositeSchedule(connectorIdInt, durationInt, &tmpProfile[0], 0, FALSE);
		}
		else
		{
			sprintf((char*)ShmOCPP20Data->GetCompositeSchedule[gun_index].Response_schedule.chargingSchedule.chargingRateUnit, "A");
			checkCompositeSchedule(connectorIdInt, durationInt, &tmpProfile[0], 0, TRUE);
		}

  		for(int idx=0;idx<ARRAY_SIZE(ShmOCPP20Data->GetCompositeSchedule[gun_index].Response_schedule.chargingSchedule.chargingSchedulePeriod);idx++)
  		{
			DEBUG_INFO("Smart Period-%02d start: %d\n", idx, tmpProfile[0].chargingSchedule[0].chargingSchedulePeriod[idx].startPeriod);
			DEBUG_INFO("Smart Period-%02d limit: %f\n", idx, tmpProfile[0].chargingSchedule[0].chargingSchedulePeriod[idx].limit);
		}

  		memcpy(&ShmOCPP20Data->GetCompositeSchedule[gun_index].Response_schedule, &tmpProfile[0].chargingSchedule[0], sizeof(struct CompositeScheduleType));
  		for(int idx=0;idx<ARRAY_SIZE(ShmOCPP20Data->GetCompositeSchedule[gun_index].Response_schedule.chargingSchedule.chargingSchedulePeriod);idx++)
  		{
   			DEBUG_INFO("Composite Period-%02d start: %d\n", idx, ShmOCPP20Data->GetCompositeSchedule[gun_index].Response_schedule.chargingSchedule.chargingSchedulePeriod[idx].startPeriod);
  			DEBUG_INFO("Composite Period-%02d limit: %f\n", idx, ShmOCPP20Data->GetCompositeSchedule[gun_index].Response_schedule.chargingSchedule.chargingSchedulePeriod[idx].limit);

  			if((ShmOCPP20Data->GetCompositeSchedule[gun_index].Response_schedule.chargingSchedule.chargingSchedulePeriod[idx].startPeriod==0) &&
  			   (ShmOCPP20Data->GetCompositeSchedule[gun_index].Response_schedule.chargingSchedule.chargingSchedulePeriod[idx].limit==0) &&
			   (idx<(ARRAY_SIZE(ShmOCPP20Data->GetCompositeSchedule[gun_index].Response_schedule.chargingSchedule.chargingSchedulePeriod)-1)?(ShmOCPP20Data->GetCompositeSchedule[gun_index].Response_schedule.chargingSchedule.chargingSchedulePeriod[idx+1].startPeriod==0):TRUE))
  			{
  				confirmPeriods = idx;
  				break;
  			}
  		}

  		if((confirmPeriods == 0) && (tmpProfile[0].id > 0))
  		{
  			confirmPeriods += 1;
  		}

  		sprintf(comfirmstr, "%s", GetCompositeScheduleStatusEnumTypeStr[GenericStatusEnumType_Accepted]);
  	}
  	else
  	{
  		sprintf(comfirmstr, "%s", GetCompositeScheduleStatusEnumTypeStr[GenericStatusEnumType_Rejected]);
  	}

	sendGetCompositeScheduleConfirmation(uuid, comfirmstr, connectorIdInt, confirmPeriods);

	return result;
}

int handleGetDisplayMessagesRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	json_object *GetDisplayMessages;

	DEBUG_INFO("handleGetDisplayMessagesRequest...\n");
	GetDisplayMessages = json_tokener_parse(payload);
	if(!is_error(GetDisplayMessages))
	{
		memset(&ShmOCPP20Data->GetDisplayMessages, 0, sizeof(struct GetDisplayMessages_20));
		memcpy(&ShmOCPP20Data->GetDisplayMessages.guid, uuid, ARRAY_SIZE(ShmOCPP20Data->GetDisplayMessages.guid));
		// Required data
		if(json_object_object_get(GetDisplayMessages, "requestId") != NULL)
		{
			ShmOCPP20Data->GetDisplayMessages.requestId = json_object_get_int(json_object_object_get(GetDisplayMessages, "requestId"));
		}

		// Optional data
		if(json_object_object_get(GetDisplayMessages, "priority") != NULL)
		{
			sprintf((char*)ShmOCPP20Data->GetDisplayMessages.priority, "%s", json_object_get_string(json_object_object_get(GetDisplayMessages, "priority")));
		}

		if(json_object_object_get(GetDisplayMessages, "state") != NULL)
		{
			sprintf((char*)ShmOCPP20Data->GetDisplayMessages.state, "%s", json_object_get_string(json_object_object_get(GetDisplayMessages, "state")));
		}

		if(json_object_array_length(json_object_object_get(GetDisplayMessages, "id")) <= ARRAY_SIZE(ShmOCPP20Data->GetDisplayMessages.id))
		{
			for(int idx=0;idx<json_object_array_length(json_object_object_get(GetDisplayMessages, "id"));idx++)
			{
				ShmOCPP20Data->GetDisplayMessages.id[idx] = json_object_get_int(json_object_array_get_idx(json_object_object_get(GetDisplayMessages, "id"), idx));
			}
			strcpy((char*)ShmOCPP20Data->GetDisplayMessages.Response_status, GetDisplayMessagesStatusEnumTypeStr[GetDisplayMessagesStatusEnumType_Accepted]);
			ShmOCPP20Data->MsMsg.bits.GetDisplayMessagesReq = ON;
		}
		else
			strcpy((char*)ShmOCPP20Data->GetDisplayMessages.Response_status, GetDisplayMessagesStatusEnumTypeStr[GetDisplayMessagesStatusEnumType_Unknown]);
	}
	json_object_put(GetDisplayMessages);



	return result;
}

int handleGetInstalledCertificateIdsRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	json_object *GetInstalledCertificateIds;

	DEBUG_INFO("handleGetInstalledCertificateIdsRequest...\n");
	GetInstalledCertificateIds = json_tokener_parse(payload);
	if(!is_error(GetInstalledCertificateIds))
	{
		memset(&ShmOCPP20Data->GetInstalledCertificateIds, 0, sizeof(struct GetInstalledCertificateIds_20));
		memcpy(&ShmOCPP20Data->GetInstalledCertificateIds.guid, uuid, ARRAY_SIZE(ShmOCPP20Data->GetInstalledCertificateIds.guid));
		// Optional data
		if(json_object_array_length(json_object_object_get(GetInstalledCertificateIds, "certificateType")) <= ARRAY_SIZE(ShmOCPP20Data->GetInstalledCertificateIds.certificateType))
		{
			for(int idx=0;idx<json_object_array_length(json_object_object_get(GetInstalledCertificateIds, "certificateType"));idx++)
			{
				sprintf((char*)ShmOCPP20Data->GetInstalledCertificateIds.certificateType[idx], "%s", json_object_get_string(json_object_array_get_idx(json_object_object_get(GetInstalledCertificateIds, "certificateType"), idx)));

				/*
				 * TODO:
				 * 	1. Get installed certificate info for response
				 */
				if(strstr((char*)ShmOCPP20Data->GetInstalledCertificateIds.certificateType[idx], GetCertificateIdUseEnumTypeStr[GetCertificateIdUseEnumType_V2GRootCertificate]) != NULL)
				{

				}
				else if(strstr((char*)ShmOCPP20Data->GetInstalledCertificateIds.certificateType[idx], GetCertificateIdUseEnumTypeStr[GetCertificateIdUseEnumType_MORootCertificate]) != NULL)
				{

				}
				else if(strstr((char*)ShmOCPP20Data->GetInstalledCertificateIds.certificateType[idx], GetCertificateIdUseEnumTypeStr[GetCertificateIdUseEnumType_CSMSRootCertificate]) != NULL)
				{

				}
				else if(strstr((char*)ShmOCPP20Data->GetInstalledCertificateIds.certificateType[idx], GetCertificateIdUseEnumTypeStr[GetCertificateIdUseEnumType_V2GCertificateChain]) != NULL)
				{

				}
				else
				{

				}
			}
			strcpy((char*)ShmOCPP20Data->GetInstalledCertificateIds.Response_status, GetInstalledCertificateStatusEnumTypeStr[GetInstalledCertificateStatusEnumType_Accepted]);
		}
		else
			strcpy((char*)ShmOCPP20Data->GetInstalledCertificateIds.Response_status, GetInstalledCertificateStatusEnumTypeStr[GetInstalledCertificateStatusEnumType_NotFound]);
	}
	json_object_put(GetInstalledCertificateIds);

	sendInstallCertificateConfirmation(uuid);

	return result;
}

int handleGetLocalListVersionRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	DEBUG_INFO("handle GetLocalListVersionRequest\n");

	if(strcmp((const char *)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Enabled].variableAttribute[0].value, "FALSE") == 0)
	{
		DEBUG_INFO("LocalAuthListEnabled is FALSE \n");
		localversion = 0;
	}
	else
	{
		DEBUG_INFO("handle GetLocalListVersionRequest OCPP_getListVerion \n");
		localversion = 0;
		DB_getListVerion();
	}

	ShmOCPP20Data->GetLocalListVersion.Response_versionNumber = localversion;
	sendGetLocalListVersionConfirmation(uuid);

	return result;
}

static char fnamePlusPath[100]={0};
static char fnamePWithNoPath[60]={0};
void checkUploadLog(void)
{
	FILE *fp;
	/* Open the command for reading. */
	fp = popen("find /mnt/ -type f -name \"*.zip\" |xargs ls -t", "r");
	if (fp == NULL) {
	   printf("Failed to run command\n" );
	   exit(1);
	}

	int ftppathlen = 0;
	memset(fnamePlusPath, 0, ARRAY_SIZE(fnamePlusPath));
	int i = 0;
	/* Read the output a line at a time - output it. */
	while (fgets(fnamePlusPath, sizeof(fnamePlusPath), fp) != NULL) {
		if(i==0)
		{
			ftppathlen = strlen(fnamePlusPath);
			printf("%s\n", fnamePlusPath);
			fnamePlusPath[ftppathlen]='\0';
			break;
		}
		i= i+1;
	}

	/* close */
	pclose(fp);

	for(int k=0; k< ARRAY_SIZE(fnamePlusPath); k++)
	{
		if((fnamePlusPath[k]=='\n') || (fnamePlusPath[k]=='r'))
		{
			fnamePlusPath[k]='\0';
		}
	}


	i=1;
	//char fname[60]={0};
	while(i < ftppathlen)
	{
		int len=ftppathlen-i;
		if(fnamePlusPath[len]== 47) // '/' ascll code: 47
		{
			printf("compare '/' all right\n");
			break;
		}
		i=i+1;
	}

	memset(fnamePWithNoPath, 0, ARRAY_SIZE(fnamePWithNoPath));
	strncpy(fnamePWithNoPath, fnamePlusPath+(ftppathlen-i+1), i+1);
	fnamePWithNoPath[i+1] = '\0';

	for(int j=0; j< ARRAY_SIZE(fnamePWithNoPath); j++)
	{
		if((fnamePWithNoPath[j]=='\n') || (fnamePWithNoPath[j]=='r'))
		{
			fnamePWithNoPath[j]='\0';
		}
	}

	FILE* fp1 = fopen(fnamePlusPath, "r");
	if (fp1)
	{
		printf("testfuc : fnamePlusPath=%s exist.\n", fnamePlusPath);
		// file exists
		fclose(fp1);
	}
	else
	{
		// file doesn't exist
		printf("testfuc : fnamePlusPath=%s not exist!\n", fnamePlusPath);
	}
}
void* GetLogProcess(void* data)
{
	pthread_detach(pthread_self());
	mtrace();
	int requestId, retriesInt=0, retryIntervalInt=0;
	char logType[32], remoteLocation[1024]={0}, oldestTimestamp[30]={0}, latestTimestamp[30]={0};
	char protocol[10]={0}, user[64]={0},password[64]={0},host[128]={0}, path[512]={0}, ftppath[512]={0},host1[128]={0},path1[512]={0};
	int port=0;
	int isSuccess = FALSE;
	char ftpbuf[1024]={0};
	char cmdBuf[2048];
	struct tm *tmNow;
	time_t CurrentTime;
	struct tm tmStart;
	struct tm tmStop;
	CurrentTime = time(NULL);
	tmNow=localtime(&CurrentTime);
	uint16_t targetYear, targetMonth;

	json_object *GetLog;

	DEBUG_INFO("GetGetProcess...\n");

	GetLog = json_tokener_parse(data);
	if(!is_error(GetLog))
	{
		// Required data
		if(json_object_object_get(GetLog, "requestId") != NULL)
			requestId = json_object_get_int(json_object_object_get(GetLog, "requestId"));

		if(json_object_object_get(GetLog, "logType") != NULL)
			sprintf(logType, "%s", json_object_get_string(json_object_object_get(GetLog, "logType")));

		if(json_object_object_get(GetLog, "log") != NULL)
		{
			if(json_object_object_get(json_object_object_get(GetLog, "log"), "remoteLocation") != NULL)
				sprintf(remoteLocation, "%s", json_object_get_string(json_object_object_get(json_object_object_get(GetLog, "log"), "remoteLocation")));

			if(json_object_object_get(json_object_object_get(GetLog, "log"), "oldestTimestamp") != NULL)
				sprintf(oldestTimestamp, "%s", json_object_get_string(json_object_object_get(json_object_object_get(GetLog, "log"), "oldestTimestamp")));

			if(json_object_object_get(json_object_object_get(GetLog, "log"), "latestTimestamp") != NULL)
				sprintf(latestTimestamp, "%s", json_object_get_string(json_object_object_get(json_object_object_get(GetLog, "log"), "latestTimestamp")));
		}

		// Optional data
		if(json_object_object_get(GetLog, "retries") != NULL)
			retriesInt = json_object_get_int(json_object_object_get(GetLog, "retries"));
		else
			retriesInt = 3; // If this field is not present, it is left to Charge Point to decide how many times it wants to retry.

		if(json_object_object_get(GetLog, "retryInterval") != NULL)
			retryIntervalInt = json_object_get_int(json_object_object_get(GetLog, "retryInterval"));
		else
			retryIntervalInt = 30;
	}
	json_object_put(GetLog);

	ShmOCPP20Data->GetLog.requestId = requestId;

	if(strstr(logType, LogEnumTypeStr[LogEnumType_SecurityLog]))
	{
		/*
		 * TODO:
		 * 	1. Pack security log
		 */
	}
	else
	{
		// Pack log to compress file
		if((sscanf((char*)oldestTimestamp, "%4d-%2d-%2dT%2d:%2d:%2d", &tmStart.tm_year, &tmStart.tm_mon, &tmStart.tm_mday, &tmStart.tm_hour, &tmStart.tm_min, &tmStart.tm_sec) == 6) &&
		   (sscanf((char*)latestTimestamp, "%4d-%2d-%2dT%2d:%2d:%2d", &tmStop.tm_year, &tmStop.tm_mon, &tmStop.tm_mday, &tmStop.tm_hour, &tmStop.tm_min, &tmStop.tm_sec) == 6))
		{
			// Pack system log
			memset(cmdBuf, 0x00, ARRAY_SIZE(cmdBuf));
			sprintf(cmdBuf, "exec zip -9 --password %04d%02d%s /mnt/system.zip", tmNow->tm_year+1900, tmNow->tm_mon+1, ShmSysConfigAndInfo->SysConfig.SerialNumber);
			targetYear = tmStart.tm_year;
			targetMonth = tmStart.tm_mon;

			do
			{
				sprintf(cmdBuf, "%s /Storage/SystemLog/*%04d*%02d*", cmdBuf, targetYear, targetMonth);
				sprintf(cmdBuf, "%s /Storage/OCPP/*%04d*%02d*SystemLog*", cmdBuf, targetYear, targetMonth);

				if(targetMonth+1>=13)
				{
					targetYear += 1;
					targetMonth = 1;
				}
				else
				{
					targetMonth += 1;
				}
			}while((targetYear < (tmNow->tm_year+1900)) ||
				   ((targetYear <= (tmNow->tm_year+1900)) && (targetMonth <= (tmNow->tm_mon+1))));

			sprintf(cmdBuf, "%s /Storage/CCS*.zip", cmdBuf);
			system(cmdBuf);

			// Pack charging & event log
			memset(cmdBuf, 0x00, ARRAY_SIZE(cmdBuf));
			sprintf(cmdBuf, "exec zip -9 /mnt/charging_event.zip");
			targetYear = tmStart.tm_year;
			targetMonth = tmStart.tm_mon;

			do
			{
				sprintf(cmdBuf, "%s /Storage/EventLog/*%04d*%02d*", cmdBuf, targetYear, targetMonth);
				sprintf(cmdBuf, "%s /Storage/OCPP/*%04d*%02d*OcppMessageLog*", cmdBuf, targetYear, targetMonth);
				if(targetMonth+1>=13)
				{
					targetYear += 1;
					targetMonth = 1;
				}
				else
				{
					targetMonth += 1;
				}
			}while((targetYear < (tmNow->tm_year+1900)) ||
				   ((targetYear <= (tmNow->tm_year+1900)) && (targetMonth <= (tmNow->tm_mon+1))));

			sprintf(cmdBuf, "%s /Storage/ChargeLog/*.db", cmdBuf);
			sprintf(cmdBuf, "%s /Storage/EventLog/*.db", cmdBuf);
			system(cmdBuf);

			// Combine log file
			system("exec zip -9 /mnt/log.zip /mnt/system.zip /mnt/charging_event.zip");
			system("exec rm -f /mnt/system.zip /mnt/charging_event.zip");
		}
		else
		{
			system("exec /root/logPackTools 'log' 6");
		}
	}

	sprintf(cmdBuf, "mv /mnt/log.zip /mnt/%s", ShmOCPP20Data->GetLog.Response_filename);
	system(cmdBuf);
	checkUploadLog();
	//****************location*******************/
	if(strcmp(remoteLocation,"")==0)
	{
		DEBUG_INFO("remoteLocation is <Empty>!\n");
		sprintf((char*)ShmOCPP20Data->LogStatusNotification.status, "%s", UploadLogStatusEnumTypeStr[UploadLogStatusEnumType_UploadFailure]);
		ShmOCPP20Data->SpMsg.bits.LogStatusNotificationReq = ON;
		goto end;
	}

	memset(protocol, 0, ARRAY_SIZE(protocol));
	memset(user, 0, ARRAY_SIZE(user) );
	memset(password, 0, ARRAY_SIZE(password));
	memset(host, 0, ARRAY_SIZE(host));

	memset(path, 0, ARRAY_SIZE(path));
	memset(ftppath, 0, ARRAY_SIZE(ftppath));
	memset(host1, 0, ARRAY_SIZE(host1));
	memset(path1, 0, ARRAY_SIZE(path1));
	/*location: ftp://user:password@host:port/path*/

	//DEBUG_INFO("fnamePlusPath =%s\n",fnamePlusPath);
	if((access(fnamePlusPath,F_OK))!=-1)
	{
		DEBUG_INFO("fnamePlusPath exist.\n");
	}
	else
	{
		DEBUG_INFO("fnamePlusPath not exist!\n");
		sprintf((char*)ShmOCPP20Data->LogStatusNotification.status, "%s", UploadLogStatusEnumTypeStr[UploadLogStatusEnumType_UploadFailure]);
		ShmOCPP20Data->SpMsg.bits.LogStatusNotificationReq = ON;
		goto end;
	}

	if(strchr(remoteLocation,'@')==NULL)
	{
		sscanf(remoteLocation,
			         "%[^:]:%*2[/]%[^:]:%i/%[a-zA-Z0-9._/-]",
			         protocol, host, &port, path);
		strcpy(user,"anonymous");
		strcpy(password,"");
	}
	else
	{
		//DEBUG_INFO("pch=%s\n", pch);
		sscanf(remoteLocation,"%[^:]:%*2[/]%[^:]:%[^@]@%[^:]:%i/%199[^\n]",
				   protocol, user, password, host, &port, path);
	}

	if((strcmp(protocol,"ftp")!=0)&&(strcmp(protocol,"http")!=0)&&(strcmp(protocol,"https")!=0))
	{
		DEBUG_INFO("protocol is not ftp/http ! \n");
		sprintf((char*)ShmOCPP20Data->LogStatusNotification.status, "%s", UploadLogStatusEnumTypeStr[UploadLogStatusEnumType_UploadFailure]);
		ShmOCPP20Data->SpMsg.bits.LogStatusNotificationReq = ON;
		goto end;
	}

	if(strncmp(remoteLocation,"http", 4) == 0)
	{
		sscanf(remoteLocation,"%[^:]:%*2[/]%[^/]/%199[^\n]", protocol, host, path);
		sprintf(ftppath,"/%s", path);

		do
		{
			sprintf((char*)ShmOCPP20Data->LogStatusNotification.status, "%s", UploadLogStatusEnumTypeStr[UploadLogStatusEnumType_Uploading]);
			ShmOCPP20Data->SpMsg.bits.LogStatusNotificationReq = ON;
			sleep(3);

			isSuccess = httpUploadFile(host, ftppath, fnamePlusPath, remoteLocation);
			if(!isSuccess)
			{
				DEBUG_INFO("sendLogStatusNotificationRequest fail...retries: %d\n", retriesInt);
				sprintf((char*)ShmOCPP20Data->LogStatusNotification.status, "%s", UploadLogStatusEnumTypeStr[UploadLogStatusEnumType_UploadFailure]);
				ShmOCPP20Data->SpMsg.bits.LogStatusNotificationReq = ON;
				sleep(retryIntervalInt);

			}
			else
			{
				DEBUG_INFO("sendLogStatusNotificationRequest Uploaded\n");
				sprintf((char*)ShmOCPP20Data->LogStatusNotification.status, "%s", UploadLogStatusEnumTypeStr[UploadLogStatusEnumType_Uploaded]);
				ShmOCPP20Data->SpMsg.bits.LogStatusNotificationReq = ON;
			}
			retriesInt--;
		}while((isSuccess == 0)&&(retriesInt >= 0));
	}
	else
	{
		sscanf(host,"%[^/]%s",host1, path1);
		if(strlen(path) > 0)
			sprintf(ftppath,"/%s", path);
		else
			sprintf(ftppath,"/%s", path1);

		int ftppathlen=strlen(ftppath);
		int i=1;
		char filenametemp[50];
		while(i < ftppathlen)
		{
			int len=ftppathlen-i;
			if(ftppath[len]== 47) // '/' ascll code: 47
			{
				 DEBUG_INFO("find '/' all right\n");
			     break;
			}
			i=i+1;
		}

		memset(filenametemp, 0, ARRAY_SIZE(filenametemp));
		strncpy(filenametemp, ftppath+(ftppathlen-i+1), i+1);
		filenametemp[i+1] = 0;
		memset(ftpbuf, 0, ARRAY_SIZE(ftpbuf));

		if(port == 0)
		   port = 21;

		do
		{
			sprintf((char*)ShmOCPP20Data->LogStatusNotification.status, "%s", UploadLogStatusEnumTypeStr[UploadLogStatusEnumType_Uploading]);
			ShmOCPP20Data->SpMsg.bits.LogStatusNotificationReq = ON;
			sleep(3);

		    isSuccess = ftpUploadFile(host1, user, password, port, ftppath, fnamePlusPath, fnamePWithNoPath);
		    if(!isSuccess)
			{
				DEBUG_INFO("sendLogStatusNotificationRequest fail...retries: %d\n", retriesInt);
				sprintf((char*)ShmOCPP20Data->LogStatusNotification.status, "%s", UploadLogStatusEnumTypeStr[UploadLogStatusEnumType_UploadFailure]);
				ShmOCPP20Data->SpMsg.bits.LogStatusNotificationReq = ON;
				sleep(retryIntervalInt);
			}
			else
			{
				DEBUG_INFO("sendLogStatusNotificationRequest Uploaded\n");
				sprintf((char*)ShmOCPP20Data->LogStatusNotification.status, "%s", UploadLogStatusEnumTypeStr[UploadLogStatusEnumType_Uploaded]);
				ShmOCPP20Data->SpMsg.bits.LogStatusNotificationReq = ON;
			}
		    retriesInt--;
		}while((!isSuccess)&&(retriesInt >= 0));
	}

end:
	system("rm -f /mnt/*");
	sleep(5);
	LogStatusNotificationStatus = UploadLogStatusEnumType_Idle;
	ShmOCPP20Data->SpMsg.bits.LogStatusNotificationReq = ON;
	interLock.isGetLogGoing = OFF;
	pthread_exit(NULL);
}

int handleGetLogRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	char fName[258];
	time_t CurrentTime;
	struct tm *tm;
	pthread_t th_Status;

	CurrentTime = time(NULL);
	tm = localtime(&CurrentTime);
	sprintf(fName ,"%s-%s-%04d%02d%02d%02d%02d%02d.zip", ShmSysConfigAndInfo->SysConfig.ModelName, ShmSysConfigAndInfo->SysConfig.SerialNumber, (tm->tm_year+1900), (tm->tm_mon+1),tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec);
	sprintf((char*)ShmOCPP20Data->GetLog.Response_filename, "%s", fName);
	sprintf((char*)ShmOCPP20Data->GetLog.Response_status, "%s", LogStatusEnumTypeStr[LogStatusEnumType_Accepted]);
	sendGetLogConfirmation(uuid);


	if(!interLock.isGetLogGoing)
	{
		interLock.isGetLogGoing = ON;
		pthread_create(&th_Status, NULL, GetLogProcess, stringtrimspace(payload));
		sleep(1);
	}
	else
		DEBUG_WARN("Other GetDiagnostic request on going.\n");

	return result;
}

int handleGetMonitoringReportRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	json_object *GetMonitoringReport;

	DEBUG_INFO("handleGetMonitoringReportRequest...\n");
	GetMonitoringReport = json_tokener_parse(payload);
	if(!is_error(GetMonitoringReport))
	{
		memset(&ShmOCPP20Data->GetMonitoringReport, 0, sizeof(struct GetMonitoringReport_20));
		memcpy(&ShmOCPP20Data->GetMonitoringReport.guid, uuid, ARRAY_SIZE(ShmOCPP20Data->GetMonitoringReport.guid));
		// Required data
		if(json_object_object_get(GetMonitoringReport, "requestId") != NULL)
		{
			ShmOCPP20Data->GetMonitoringReport.requestId = json_object_get_int(json_object_object_get(GetMonitoringReport, "requestId"));
		}

		// Optional data
		if(json_object_object_get(GetMonitoringReport, "monitoringCriteria") != NULL)
		{
			sprintf((char*)ShmOCPP20Data->GetMonitoringReport.monitoringCriteria, "%s", json_object_get_string(json_object_object_get(GetMonitoringReport, "monitoringCriteria")));
		}

		if(json_object_object_get(GetMonitoringReport, "componentVariable") != NULL)
		{
			if(json_object_array_length(json_object_object_get(GetMonitoringReport, "componentVariable")) <= ARRAY_SIZE(ShmOCPP20Data->GetMonitoringReport.componentVariable))
			{
				for(int idx=0;idx<json_object_array_length(json_object_object_get(GetMonitoringReport, "componentVariable"));idx++)
				{
					if(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetMonitoringReport, "componentVariable"), idx), "component") != NULL)
					{
						if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetMonitoringReport, "componentVariable"), idx), "component"), "name") != NULL)
						{
							sprintf((char*)ShmOCPP20Data->GetMonitoringReport.componentVariable[idx].component.name, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetMonitoringReport, "componentVariable"), idx), "component"), "name")));
						}

						if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetMonitoringReport, "componentVariable"), idx), "component"), "instance") != NULL)
						{
							sprintf((char*)ShmOCPP20Data->GetMonitoringReport.componentVariable[idx].component.instance, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetMonitoringReport, "componentVariable"), idx), "component"), "instance")));
						}

						if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetMonitoringReport, "componentVariable"), idx), "component"), "evse") != NULL)
						{
							if(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetMonitoringReport, "componentVariable"), idx), "component"), "evse"), "id") != NULL)
							{
								ShmOCPP20Data->GetMonitoringReport.componentVariable[idx].component.evse.id = json_object_get_int(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetMonitoringReport, "componentVariable"), idx), "component"), "instance"), "id"));
							}

							if(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetMonitoringReport, "componentVariable"), idx), "component"), "evse"), "connectorId") != NULL)
							{
								ShmOCPP20Data->GetMonitoringReport.componentVariable[idx].component.evse.connectorId = json_object_get_int(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetMonitoringReport, "componentVariable"), idx), "component"), "instance"), "connectorId"));
							}
						}
					}

					if(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetMonitoringReport, "componentVariable"), idx), "variable") != NULL)
					{
						if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetMonitoringReport, "componentVariable"), idx), "variable"), "name") != NULL)
						{
							sprintf((char*)ShmOCPP20Data->GetMonitoringReport.componentVariable[idx].variable.name, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetMonitoringReport, "componentVariable"), idx), "variable"), "name")));
						}

						if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetMonitoringReport, "componentVariable"), idx), "variable"), "instance") != NULL)
						{
							sprintf((char*)ShmOCPP20Data->GetMonitoringReport.componentVariable[idx].variable.instance, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetMonitoringReport, "componentVariable"), idx), "variable"), "instance")));
						}
					}
				}
			}
		}
	}
	json_object_put(GetMonitoringReport);

	/*
	 * TODO:
	 * 	1. Response result
	 */
	strcpy((char*)ShmOCPP20Data->GetMonitoringReport.Response_status, GenericDeviceModelStatusEnumTypeStr[GenericDeviceModelStatusEnumType_Accepted]);
	sendGetMonitoringReportConfirmation(uuid);

	return result;
}

int handleGetReportRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	json_object *GetReport;

	DEBUG_INFO("handleGetReportRequest...\n");
	GetReport = json_tokener_parse(payload);
	if(!is_error(GetReport))
	{
		memset(&ShmOCPP20Data->GetReport, 0, sizeof(struct GetReport_20));
		memcpy(&ShmOCPP20Data->GetReport.guid, uuid, ARRAY_SIZE(ShmOCPP20Data->GetReport.guid));
		// Required data
		if(json_object_object_get(GetReport, "requestId") != NULL)
		{
			ShmOCPP20Data->GetReport.requestId = json_object_get_int(json_object_object_get(GetReport, "requestId"));
		}
		// Optional data
		if(json_object_object_get(GetReport, "componentCriteria") != NULL)
		{
			sprintf((char*)ShmOCPP20Data->GetReport.componentCriteria, "%s", json_object_get_string(json_object_object_get(GetReport, "componentCriteria")));
		}

		if(json_object_object_get(GetReport, "componentVariable") != NULL)
		{
			if(json_object_array_length(json_object_object_get(GetReport, "componentVariable")) <= ARRAY_SIZE(ShmOCPP20Data->GetReport.componentVariable))
			{
				for(int idx=0;idx<json_object_array_length(json_object_object_get(GetReport, "componentVariable"));idx++)
				{
					if(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetReport, "componentVariable"), idx), "component") != NULL)
					{
						if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetReport, "componentVariable"), idx), "component"), "name") != NULL)
						{
							sprintf((char*)ShmOCPP20Data->GetReport.componentVariable[idx].component.name, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetReport, "componentVariable"), idx), "component"), "name")));
						}

						if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetReport, "componentVariable"), idx), "component"), "instance") != NULL)
						{
							sprintf((char*)ShmOCPP20Data->GetReport.componentVariable[idx].component.instance, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetReport, "componentVariable"), idx), "component"), "instance")));
						}

						if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetReport, "componentVariable"), idx), "component"), "evse") != NULL)
						{
							if(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetReport, "componentVariable"), idx), "component"), "evse"), "id") != NULL)
							{
								ShmOCPP20Data->GetReport.componentVariable[idx].component.evse.id = json_object_get_int(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetReport, "componentVariable"), idx), "component"), "evse"), "id"));
							}

							if(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetReport, "componentVariable"), idx), "component"), "evse"), "connectorId") != NULL)
							{
								ShmOCPP20Data->GetReport.componentVariable[idx].component.evse.connectorId = json_object_get_int(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetReport, "componentVariable"), idx), "component"), "evse"), "connectorId"));
							}
						}
					}

					if(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetReport, "componentVariable"), idx), "variable") != NULL)
					{
						if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetReport, "componentVariable"), idx), "variable"), "name") != NULL)
						{
							sprintf((char*)ShmOCPP20Data->GetReport.componentVariable[idx].variable.name, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetReport, "componentVariable"), idx), "variable"), "name")));
						}

						if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetReport, "componentVariable"), idx), "variable"), "instance") != NULL)
						{
							sprintf((char*)ShmOCPP20Data->GetReport.componentVariable[idx].variable.instance, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetReport, "componentVariable"), idx), "variable"), "instance")));
						}
					}
				}
			}
		}
	}
	json_object_put(GetReport);

	/*
	 * TODO:
	 * 	1. Response result
	 */
	strcpy((char*)ShmOCPP20Data->GetReport.Response_status, GenericDeviceModelStatusEnumTypeStr[GenericDeviceModelStatusEnumType_Accepted]);
	sendGetReportConfirmation(uuid);

	return result;
}

int handleGetTransactionStatusRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	int8_t	gun_index = -1;
	json_object *GetTransactionStatus;

	DEBUG_INFO("handleGetTransactionStatusRequest...\n");
	GetTransactionStatus = json_tokener_parse(payload);
	if(!is_error(GetTransactionStatus))
	{

		/*
		 * TODO:
		 * 	1. Check transaction locate which connector
		 */

		memset(&ShmOCPP20Data->GetTransactionStatus[gun_index], 0, sizeof(struct GetTransactionStatus_20));
		memcpy(&ShmOCPP20Data->GetTransactionStatus[gun_index].guid, uuid, ARRAY_SIZE(ShmOCPP20Data->GetTransactionStatus[gun_index].guid));
		if(json_object_object_get(GetTransactionStatus, "transactionId") != NULL)
		{
			sprintf((char*)ShmOCPP20Data->GetTransactionStatus[gun_index].transactionId, "%s", json_object_get_string(json_object_object_get(GetTransactionStatus, "transactionId")));
		}

		ShmOCPP20Data->GetTransactionStatus[gun_index].Response_messagesInQueue = FALSE;
		ShmOCPP20Data->GetTransactionStatus[gun_index].Response_ongoingIndicator = FALSE;
	}
	json_object_put(GetTransactionStatus);

	sendGetTransactionStatusConfirmation(uuid, gun_index);

	return result;
}

int handleGetVariablesRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	int isUnknownComponent = TRUE;
	json_object *GetVariables;

	DEBUG_INFO("handleGetVariablesRequest...\n");
	GetVariables = json_tokener_parse(payload);
	if(!is_error(GetVariables))
	{
		memset(&ShmOCPP20Data->GetVariables, 0, sizeof(struct SetVariables_20));
		memcpy(&ShmOCPP20Data->GetVariables.guid, uuid, ARRAY_SIZE(ShmOCPP20Data->GetVariables.guid));
		// Required data
		if(json_object_array_length(json_object_object_get(GetVariables, "getVariableData")) <= ARRAY_SIZE(ShmOCPP20Data->GetVariables.getVariableData))
		{
			for(int idx=0;idx<json_object_array_length(json_object_object_get(GetVariables, "getVariableData"));idx++)
			{
				if(json_object_array_get_idx(json_object_object_get(GetVariables, "getVariableData"), idx) != NULL)
				{
					if(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetVariables, "getVariableData"), idx), "attributeType") != NULL)
					{
						sprintf((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].attributeType, "%s", json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetVariables, "getVariableData"), idx), "attributeType")));
						strcpy((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeType, (char*)ShmOCPP20Data->GetVariables.getVariableData[idx].attributeType);
					}

					/*if(ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeType != NULL)
					{
						strcpy((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeType, "Actual");
					}*/

					if(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetVariables, "getVariableData"), idx), "component") != NULL)
					{
						if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetVariables, "getVariableData"), idx), "component"), "name") != NULL)
						{
							sprintf((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].component.name, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetVariables, "getVariableData"), idx), "component"), "name")));
						}

						if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetVariables, "getVariableData"), idx), "component"), "instance") != NULL)
						{
							sprintf((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].component.instance, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetVariables, "getVariableData"), idx), "component"), "instance")));
						}

						if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetVariables, "getVariableData"), idx), "component"), "evse") != NULL)
						{
							if(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetVariables, "getVariableData"), idx), "component"), "evse"), "id") != NULL)
							{
								ShmOCPP20Data->GetVariables.getVariableData[idx].component.evse.id = json_object_get_int(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetVariables, "getVariableData"), idx), "component"), "instance"), "id"));
							}

							if(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetVariables, "getVariableData"), idx), "component"), "evse"), "connectorId") != NULL)
							{
								ShmOCPP20Data->GetVariables.getVariableData[idx].component.evse.connectorId = json_object_get_int(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetVariables, "getVariableData"), idx), "component"), "instance"), "connectorId"));
							}
						}

						memcpy(&ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].component, &ShmOCPP20Data->GetVariables.getVariableData[idx].component, sizeof(struct ComponentType));
					}

					if(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetVariables, "getVariableData"), idx), "variable") != NULL)
					{
						if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetVariables, "getVariableData"), idx), "variable"), "name") != NULL)
						{
							sprintf((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].variable.name, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetVariables, "getVariableData"), idx), "variable"), "name")));
						}

						if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetVariables, "getVariableData"), idx), "variable"), "instance") != NULL)
						{
							sprintf((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].variable.instance, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(GetVariables, "getVariableData"), idx), "variable"), "instance")));
						}

						memcpy(&ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].variable , &ShmOCPP20Data->GetVariables.getVariableData[idx].variable, sizeof(struct VariableType));
					}

					for(uint8_t idx_var=0;idx_var<CtrlrVariable_CNT;idx_var++)
					{
						if((strcmp((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].component.name, (char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].component.name) == 0) &&
						   (strcmp((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].component.instance, (char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].component.instance) == 0) &&
						   (strcmp((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].variable.name, (char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variable.name) == 0) &&
						   (strcmp((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].variable.instance, (char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variable.instance) == 0))
						{
							strcpy((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeStatus, GetVariableStatusEnumTypeStr[GetVariableStatusEnumType_Accepted]);
							isUnknownComponent = FALSE;

							if((strcmp((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].attributeType, (char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableAttribute[0].type) != 0) &&
							   (json_object_object_get(json_object_array_get_idx(json_object_object_get(GetVariables, "getVariableData"), idx), "attributeType") != NULL))
							{
								strcpy((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeStatus, GetVariableStatusEnumTypeStr[GetVariableStatusEnumType_NotSupportedAttributeType]);
								break;
							}

							if((strcmp((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].component.name, "ChargingStation") == 0) &&
							   (strcmp((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].variable.name, "SystemUptimeSec") == 0))
							{
								struct sysinfo s_info;
								int error = sysinfo(&s_info);
								if(error != 0)
								{
									DEBUG_WARN("System uptime get error: %d\n", error);
								}
								else
								{
									sprintf((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeValue, "%ld", s_info.uptime);
									sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableAttribute[0].value, "%ld", s_info.uptime);
								}
							}
							else if((strcmp((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].component.name, "ChargingStation") == 0) &&
									(strcmp((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].variable.name, "FreeVend") == 0))
							{
								sprintf((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeValue, "%s", (ShmSysConfigAndInfo->SysConfig.AuthorisationMode?"TRUE":"FALSE"));
							}
							else
							{
								strcpy((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeValue, (char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableAttribute[0].value);
								strcpy((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeType, (char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableAttribute[0].type);
							}

							break;
						}
						else
						{
							if(strcmp((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].component.name, (char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].component.name) != 0)
							{
								isUnknownComponent = FALSE;
							}

							strcpy((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeStatus, GetVariableStatusEnumTypeStr[GetVariableStatusEnumType_UnknownVariable]);
							memset(ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeValue, 0x00, ARRAY_SIZE(ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeValue));
						}
					}

					if(isUnknownComponent == TRUE)
					{
						strcpy((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeStatus, GetVariableStatusEnumTypeStr[GetVariableStatusEnumType_UnknownComponent]);
					}
				}
			}
		}
		sendGetVariablesConfirmation(uuid, json_object_array_length(json_object_object_get(GetVariables, "getVariableData")));
	}
	json_object_put(GetVariables);

	return result;
}

int handleInstallCertificateRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	json_object *InstallCertificate;

	DEBUG_INFO("handleInstallCertificateRequest...\n");
	InstallCertificate = json_tokener_parse(payload);
	if(!is_error(InstallCertificate))
	{
		memset(&ShmOCPP20Data->InstallCertificate, 0, sizeof(struct InstallCertificate_20));
		memcpy(&ShmOCPP20Data->InstallCertificate.guid, uuid, ARRAY_SIZE(ShmOCPP20Data->InstallCertificate.guid));
		// Required data
		if(json_object_object_get(InstallCertificate, "certificateType") != NULL)
		{
			sprintf((char*)ShmOCPP20Data->InstallCertificate.certificateType, "%s", json_object_get_string(json_object_object_get(InstallCertificate, "certificateType")));
		}

		if(json_object_object_get(InstallCertificate, "certificate") != NULL)
		{
			sprintf((char*)ShmOCPP20Data->InstallCertificate.certificate, "%s", json_object_get_string(json_object_object_get(InstallCertificate, "certificate")));
		}
	}
	json_object_put(InstallCertificate);

	/*
	 * TODO:
	 * 	1. Install certification preocess and response
	 */
	if(strstr((char*)ShmOCPP20Data->InstallCertificate.certificateType, InstallCertificateUseEnumTypeStr[InstallCertificateUseEnumType_V2GRootCertificate]))
	{

	}
	else if(strstr((char*)ShmOCPP20Data->InstallCertificate.certificateType, InstallCertificateUseEnumTypeStr[InstallCertificateUseEnumType_MORootCertificate]))
	{

	}
	else if(strstr((char*)ShmOCPP20Data->InstallCertificate.certificateType, InstallCertificateUseEnumTypeStr[InstallCertificateUseEnumType_CSMSRootCertificate]))
	{

	}
	else
	{

	}

	strcpy((char*)ShmOCPP20Data->InstallCertificate.Response_status, InstallCertificateStatusEnumTypeStr[GenericStatusEnumType_Accepted]);
	sendInstallCertificateConfirmation(uuid);
	system("/bin/fsync -d /dev/mtdblock13;/bin/sync &");
	return result;
}

int handlePublishFirmwareRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	json_object *PublishFirmware;

	DEBUG_INFO("handlePublishFirmwareRequest...\n");
	PublishFirmware = json_tokener_parse(payload);
	if(!is_error(PublishFirmware))
	{
		memset(&ShmOCPP20Data->PublishFirmware, 0, sizeof(struct PublishFirmware_20));
		memcpy(&ShmOCPP20Data->PublishFirmware.guid, uuid, ARRAY_SIZE(ShmOCPP20Data->PublishFirmware.guid));
		// Required data
		if(json_object_object_get(PublishFirmware, "requestId") != NULL)
		{
			ShmOCPP20Data->PublishFirmware.requestId = json_object_get_int(json_object_object_get(PublishFirmware, "requestId"));
		}

		if(json_object_object_get(PublishFirmware, "checksum") != NULL)
		{
			sprintf((char*)ShmOCPP20Data->PublishFirmware.requestId, "%s", json_object_get_string(json_object_object_get(PublishFirmware, "checksum")));
		}

		// Optional data
		if(json_object_object_get(PublishFirmware, "location") != NULL)
		{
			sprintf((char*)ShmOCPP20Data->PublishFirmware.location, "%s", json_object_get_string(json_object_object_get(PublishFirmware, "location")));
		}

		if(json_object_object_get(PublishFirmware, "retries") != NULL)
		{
			ShmOCPP20Data->PublishFirmware.retries = json_object_get_int(json_object_object_get(PublishFirmware, "retries"));
		}

		if(json_object_object_get(PublishFirmware, "retryInterval") != NULL)
		{
			ShmOCPP20Data->PublishFirmware.retryInterval = json_object_get_int(json_object_object_get(PublishFirmware, "retryInterval"));
		}
	}
	json_object_put(PublishFirmware);

	/*
	 * TODO:
	 * 	1. Publish firmware preocess and response
	 */
	strcpy((char*)ShmOCPP20Data->PublishFirmware.Response_status, GenericStatusEnumTypeStr[GenericStatusEnumType_Accepted]);
	sendPublishFirmwareConfirmation(uuid);

	return result;
}

int handleRequestStartTransactionRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	int8_t connectorIdx = -1;
	uint8_t tempIndex;
	uint8_t isOverConnectorMax = FALSE;
	uint8_t isPeriodOverMax = FALSE;
	uint8_t isTxProfile = TRUE;
	uint8_t isAllowStart = TRUE;
	uint8_t filename[128]={0};
	char cmdBuf[128];
	FILE *filePtr;
	json_object *RemoteStartTransaction;

	DEBUG_INFO("handleRequestStartTransactionRequest...\n");
	RemoteStartTransaction = json_tokener_parse(payload);
	if(!is_error(RemoteStartTransaction))
	{
		if(json_object_object_get(RemoteStartTransaction, "evseId") != NULL)
		{
			if((0 < json_object_get_int(json_object_object_get(RemoteStartTransaction, "evseId"))) && (json_object_get_int(json_object_object_get(RemoteStartTransaction, "evseId"))<=gunTotalNumber))
			{
				connectorIdx = json_object_get_int(json_object_object_get(RemoteStartTransaction, "evseId"));
			}
			else
			{
				isOverConnectorMax = TRUE;
				DEBUG_WARN("Connector id shall not equal 0 and less than max connector id.\n");
			}
		}
		else
		{
			for(uint8_t idx=0;idx<gunTotalNumber;idx++)
			{
				if(!cpinitateMsg.bits[idx].isOnCharging && (strstr((char*)ShmOCPP20Data->StatusNotification[idx].connectorStatus, ConnectorStatusEnumTypeStr[ConnectorStatusEnumType_Occupied]) != NULL))
				{
					connectorIdx = (idx+1);

					DEBUG_INFO("Remote start without connectorId but detect connector-%02d connected ready to start.\n", connectorIdx);
					break;
				}
			}
		}

		if(isOverConnectorMax == FALSE)
		{
			if(connectorIdx > 0)
			{
				DEBUG_INFO("Connector id: %d\n", connectorIdx);
				memset(&ShmOCPP20Data->RequestStartTransaction[connectorIdx-1], 0, sizeof(struct RequestStartTransaction_20));
				memcpy(&ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].guid, uuid, ARRAY_SIZE(ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].guid));
				// Required data
				if(json_object_object_get(RemoteStartTransaction, "remoteStartId") != NULL)
				{
					ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].remoteStartId = json_object_get_int(json_object_object_get(RemoteStartTransaction, "remoteStartId"));
				}

				if(json_object_object_get(RemoteStartTransaction, "idToken") != NULL)
				{
					if(json_object_object_get(json_object_object_get(RemoteStartTransaction, "idToken"), "idToken") != NULL)
					{
						sprintf((char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].idToken.idToken, "%s", json_object_get_string(json_object_object_get(json_object_object_get(RemoteStartTransaction, "idToken"), "idToken")));
					}

					if(json_object_object_get(json_object_object_get(RemoteStartTransaction, "idToken"), "type") != NULL)
					{
						sprintf((char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].idToken.type, "%s", json_object_get_string(json_object_object_get(json_object_object_get(RemoteStartTransaction, "idToken"), "type")));
					}
				}

				// Optional data
				if(json_object_object_get(RemoteStartTransaction, "groupIdToken") != NULL)
				{
					if(json_object_object_get(json_object_object_get(RemoteStartTransaction, "groupIdToken"), "idToken") != NULL)
					{
						sprintf((char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].groupIdToken.idToken, "%s", json_object_get_string(json_object_object_get(json_object_object_get(RemoteStartTransaction, "groupIdToken"), "idToken")));
					}

					if(json_object_object_get(json_object_object_get(RemoteStartTransaction, "groupIdToken"), "type") != NULL)
					{
						sprintf((char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].groupIdToken.type, "%s", json_object_get_string(json_object_object_get(json_object_object_get(RemoteStartTransaction, "groupIdToken"), "type")));
					}
				}

				if(json_object_object_get(RemoteStartTransaction, "chargingProfile") != NULL)
				{
					// Check periods is over max configuration
					if(json_object_array_length(json_object_object_get(json_object_object_get(json_object_object_get(RemoteStartTransaction, "chargingProfile"), "chargingSchedule"), "chargingSchedulePeriod")) > atoi((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_PeriodsPerSchedule].variableAttribute[0].value))
					{
						isPeriodOverMax = TRUE;
					}

					// Check profile purpose is TxProfile
					if(strstr(json_object_get_string(json_object_object_get(json_object_object_get(RemoteStartTransaction, "chargingProfile"), "chargingProfilePurpose")), ChargingProfilePurposeEnumTypeStr[ChargingProfilePurposeEnumType_TxProfile]) != NULL)
					{
						ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].chargingProfile.id = json_object_get_int(json_object_object_get(json_object_object_get(RemoteStartTransaction, "chargingProfile"), "id"));
						sprintf((char*)filename, "/Storage/OCPP/TxProfile_%d_OCPP20.json", connectorIdx);
					}
					else
					{
						isTxProfile = FALSE;
					}
				}

				//check Transaction active
				if(gunType[connectorIdx-1] == GUN_TYPE_CHAdeMO)
				{
					if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
					{
						tempIndex =  ((connectorIdx-1) == 2) ? 1: 0;
					}
					else
					{
						tempIndex = (connectorIdx-1);
					}

					for (int index = 0; index < CHAdeMO_QUANTITY; index++)
					{
						if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex )
						{

							if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ReservationId != -1)&&(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ReservationId >= 0)&&(strcmp((const char *)ShmOCPP20Data->ReserveNow[index].idToken.idToken, (char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].idToken.idToken) == 0))
							{
								//Reserved
								DEBUG_INFO("CHAdeMO connector already reserved and idTag match.\n");
							}
							else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ReservationId != -1)&&(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ReservationId >= 0)&&(strcmp((const char *)ShmOCPP20Data->ReserveNow[index].idToken.idToken, (char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].idToken.idToken) != 0))
							{
								//Reserved
								DEBUG_INFO("CHAdeMO connector already reserved and idTag does not match.\n");
								isAllowStart = FALSE;
							}
							else
							{
								if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus != SYS_MODE_IDLE)				//S_IDLE
									&& (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus != SYS_MODE_PREPARING ) 	//S_PRECHARGE
									&& (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus != SYS_MODE_PREPARE_FOR_EV ) 	//S_PREPARING_FOR_EV
									&& (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus != SYS_MODE_PREPARE_FOR_EVSE ))   // S_PREPARING_FOR_EVSE
								{
									DEBUG_WARN("CHAdeMO connector not allow start cause busy.\n.");
									isAllowStart = FALSE;
								}
							}//END FOR ELSE
						}
					}// END FOR CHAdeMO_QUANTITY
				}
				else if(gunType[connectorIdx-1] == GUN_TYPE_CCS)
				{
					if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
					{
						tempIndex =  ((connectorIdx-1) == 2) ? 1: 0;
					}
					else
					{
						tempIndex = (connectorIdx-1);
					}

					for (int index = 0; index < CCS_QUANTITY; index++)
					{
						if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
						{
							if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ReservationId != -1)&&(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ReservationId >= 0)&&(strcmp((const char *)ShmOCPP20Data->ReserveNow[index].idToken.idToken, (char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].idToken.idToken) == 0))
							{
								//Reserved
								DEBUG_INFO("CCS connector already reserved and idTag match.\n");
							}
							else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ReservationId != -1)&&(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ReservationId >= 0)&&(strcmp((const char *)ShmOCPP20Data->ReserveNow[index].idToken.idToken, (char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].idToken.idToken) != 0))
							{
								//Reserved
								DEBUG_INFO("CCS connector already reserved and idTag does not match.\n");
								isAllowStart = FALSE;
							}
							else
							{
								if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != SYS_MODE_IDLE)          //S_IDLE
									&& (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != SYS_MODE_PREPARING)   	//S_PRECHARGE
									&& (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != SYS_MODE_PREPARE_FOR_EV)   	//S_PREPARING_FOR_EV
									&& (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != SYS_MODE_PREPARE_FOR_EVSE)) 	// S_PREPARING_FOR_EVSE
								{
									DEBUG_WARN("CCS connector not allow start cause busy.\n.");
									isAllowStart = FALSE;
								}

							}// END FOR ELSE
						}
					}// END FOR CCS_QUANTITY
				}
				else if(gunType[connectorIdx-1] == GUN_TYPE_GBT)
				{
					if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
					{
						tempIndex =  ((connectorIdx-1) == 2) ? 1: 0;
					}
					else
					{
						tempIndex = (connectorIdx-1);
					}

					for (int index = 0; index < GB_QUANTITY; index++)
					{
						if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex )
						{
							if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ReservationId != -1)&&(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ReservationId >= 0)&&(strcmp((const char *)ShmOCPP20Data->ReserveNow[index].idToken.idToken, (char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].idToken.idToken) == 0))
							{
								//Reserved
								DEBUG_INFO("GBT connector already reserved and idTag match.\n");
							}
							else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ReservationId != -1)&&(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ReservationId >= 0)&&(strcmp((const char *)ShmOCPP20Data->ReserveNow[index].idToken.idToken, (char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].idToken.idToken) != 0))
							{
								//Reserved
								DEBUG_INFO("GBT connector already reserved and idTag does not match.\n");
								isAllowStart = FALSE;
							}
							else
							{
								if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus != SYS_MODE_IDLE)         	//S_IDLE
									&& (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus != SYS_MODE_PREPARING)		//S_PRECHARGE
									&& (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus != SYS_MODE_PREPARE_FOR_EV)		//S_PREPARING_FOR_EV
									&& (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus != SYS_MODE_PREPARE_FOR_EVSE)) 		// S_PREPARING_FOR_EVSE
								{
									DEBUG_WARN("GBT connector not allow start cause busy.\n");
									isAllowStart = FALSE;
								}

							}// END FOR ELSE
						}
					} // END FOR GB_QUANTITY
				}
				else if(gunType[connectorIdx-1] == GUN_TYPE_DO)
				{
					tempIndex = (connectorIdx-1);

					for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
					{
						if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex )
						{
							if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ReservationId != -1)&&(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ReservationId >= 0)&&(strcmp((const char *)ShmOCPP20Data->ReserveNow[index].idToken.idToken, (char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].idToken.idToken) == 0))
							{
								//Reserved
								DEBUG_INFO("Dispenser connector already reserved and idTag match.\n");
							}
							else if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ReservationId != -1)&&(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ReservationId >= 0)&&(strcmp((const char *)ShmOCPP20Data->ReserveNow[index].idToken.idToken, (char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].idToken.idToken) != 0))
							{
								//Reserved
								DEBUG_INFO("Dispenser connector already reserved and idTag does not match.\n");
								isAllowStart = FALSE;
							}
							else
							{
								if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus != SYS_MODE_IDLE)         	//S_IDLE
									&& (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus != SYS_MODE_PREPARING)		//S_PRECHARGE
									&& (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus != SYS_MODE_PREPARE_FOR_EV)		//S_PREPARING_FOR_EV
									&& (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus != SYS_MODE_PREPARE_FOR_EVSE)) 		// S_PREPARING_FOR_EVSE
								{
									DEBUG_WARN("Dispenser connector not allow start cause busy.\n");
									isAllowStart = FALSE;
								}

							}// END FOR ELSE
						}
					} // END FOR GB_QUANTITY
				}
				else
				{
					if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D') // 'D' means DC
					{
						tempIndex = 2;
					}
					else
					{
						tempIndex = (connectorIdx-1);
					}

					for (int index = 0; index < AC_QUANTITY; index++)
					{
						if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex )
						{

							if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].ReservationId != -1)&&(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].ReservationId >= 0)&&(strcmp((const char *)ShmOCPP20Data->ReserveNow[index].idToken.idToken, (char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].idToken.idToken) == 0))
							{
								//Reserved
								DEBUG_INFO("AC connector already reserved and idTag match.\n");
							}
							else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].ReservationId != -1)&&(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].ReservationId >= 0)&&(strcmp((const char *)ShmOCPP20Data->ReserveNow[index].idToken.idToken, (char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].idToken.idToken) != 0))
							{
								//Reserved
								DEBUG_INFO("AC connector already reserved and idTag does not match.\n");
								isAllowStart = FALSE;
							}
							else
							{
								if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != SYS_MODE_IDLE)				//S_IDLE
									&& (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != SYS_MODE_PREPARING) 	//S_PRECHARGE
									&& (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != SYS_MODE_PREPARE_FOR_EV) 	//S_PREPARING_FOR_EV
									&& (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != SYS_MODE_PREPARE_FOR_EVSE))   // S_PREPARING_FOR_EVSE
								{
									DEBUG_WARN("AC connector not allow start cause busy.\n");
									isAllowStart = FALSE;
								}

							}//END FOR ELSE
						}
					}// END FOR AC_QUANTITY
				}
			}
			else
			{
				DEBUG_INFO("Connector id does not specific.\n");

				for(uint8_t gun_index=0;gun_index<gunTotalNumber;gun_index++)
				{
					memset(&ShmOCPP20Data->RequestStartTransaction[gun_index], 0, sizeof(struct RequestStartTransaction_20));
					memcpy(&ShmOCPP20Data->RequestStartTransaction[gun_index].guid, uuid, ARRAY_SIZE(ShmOCPP20Data->RequestStartTransaction[gun_index].guid));
					// Required data
					if(json_object_object_get(RemoteStartTransaction, "remoteStartId") != NULL)
					{
						ShmOCPP20Data->RequestStartTransaction[gun_index].remoteStartId = json_object_get_int(json_object_object_get(RemoteStartTransaction, "remoteStartId"));
					}

					if(json_object_object_get(RemoteStartTransaction, "idToken") != NULL)
					{
						if(json_object_object_get(json_object_object_get(RemoteStartTransaction, "idToken"), "idToken") != NULL)
						{
							sprintf((char*)ShmOCPP20Data->RequestStartTransaction[gun_index].idToken.idToken, "%s", json_object_get_string(json_object_object_get(json_object_object_get(RemoteStartTransaction, "idToken"), "idToken")));
						}

						if(json_object_object_get(json_object_object_get(RemoteStartTransaction, "idToken"), "type") != NULL)
						{
							sprintf((char*)ShmOCPP20Data->RequestStartTransaction[gun_index].idToken.type, "%s", json_object_get_string(json_object_object_get(json_object_object_get(RemoteStartTransaction, "idToken"), "type")));
						}
					}

					// Optional data
					if(json_object_object_get(RemoteStartTransaction, "groupIdToken") != NULL)
					{
						if(json_object_object_get(json_object_object_get(RemoteStartTransaction, "groupIdToken"), "idToken") != NULL)
						{
							sprintf((char*)ShmOCPP20Data->RequestStartTransaction[gun_index].groupIdToken.idToken, "%s", json_object_get_string(json_object_object_get(json_object_object_get(RemoteStartTransaction, "groupIdToken"), "idToken")));
						}

						if(json_object_object_get(json_object_object_get(RemoteStartTransaction, "groupIdToken"), "type") != NULL)
						{
							sprintf((char*)ShmOCPP20Data->RequestStartTransaction[gun_index].groupIdToken.type, "%s", json_object_get_string(json_object_object_get(json_object_object_get(RemoteStartTransaction, "groupIdToken"), "type")));
						}
					}

					if(json_object_object_get(RemoteStartTransaction, "chargingProfile") != NULL)
					{
						// Check periods is over max configuration
						if(json_object_array_length(json_object_object_get(json_object_object_get(json_object_object_get(RemoteStartTransaction, "chargingProfile"), "chargingSchedule"), "chargingSchedulePeriod")) > atoi((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_PeriodsPerSchedule].variableAttribute[0].value))
						{
							isPeriodOverMax = TRUE;
						}

						// Check profile purpose is TxProfile
						if(strstr(json_object_get_string(json_object_object_get(json_object_object_get(RemoteStartTransaction, "chargingProfile"), "chargingProfilePurpose")), ChargingProfilePurposeEnumTypeStr[ChargingProfilePurposeEnumType_TxProfile]) != NULL)
						{
							ShmOCPP20Data->RequestStartTransaction[gun_index].chargingProfile.id = json_object_get_int(json_object_object_get(json_object_object_get(RemoteStartTransaction, "chargingProfile"), "id"));
							sprintf((char*)filename, "/Storage/OCPP/TxProfile_Tmp_OCPP20.json");
						}
						else
						{
							isTxProfile = FALSE;
						}
					}
				}
			}
		}

		// Profile replace or add info
		if((isOverConnectorMax == FALSE) && !isPeriodOverMax && isTxProfile && isAllowStart)
		{
			if(connectorIdx != -1)
			{
				if(strlen((char*)filename) > 0)
				{
					// Save profile to file
					sprintf(cmdBuf, "rm -f /Storage/OCPP/TxProfile_%d_OCPP20.json", connectorIdx);
					system(cmdBuf);

					sprintf((char*)filename, "/Storage/OCPP/TxProfile_%d_OCPP20.json.json", connectorIdx);
					filePtr = fopen((char*)filename, "w");
					fprintf(filePtr, "{\"evseId\":%d,\"chargingProfile\":%s}\n", connectorIdx, json_object_to_json_string_ext(json_object_object_get(RemoteStartTransaction, "chargingProfile"), JSON_C_TO_STRING_PLAIN));
					fclose(filePtr);
				}

				ShmOCPP20Data->CsMsg.bits[connectorIdx-1].RequestStartTransactionReq = ON;
				sprintf((char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].Response_status, "%s", RequestStartStopStatusEnumTypeStr[RequestStartStopStatusEnumType_Accepted]);
				random_uuid((char*)ShmOCPP20Data->RequestStartTransaction[connectorIdx-1].Response_transactionId);
				result = PASS;
			}
			else
			{
				 uint8_t isHasIdleConnector = FALSE;
				 for(uint8_t gun_index=0;gun_index<gunTotalNumber;gun_index++)
				 {
					 if(!cpinitateMsg.bits[gun_index].isOnCharging)
					 {
						 isHasIdleConnector = TRUE;
						 break;
					 }
				 }

				 if(isHasIdleConnector == TRUE)
				 {
					 DEBUG_INFO("Start wait connector link to EV in %s seconds.\n", ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_EVConnectionTimeOut].variableAttribute[0].value);

					 if(strlen((char*)filename) > 0)
					 {
						 // Save profile to file
						 sprintf(cmdBuf, "rm -f /Storage/OCPP/TxProfile_Tmp_OCPP20.json");
						 system(cmdBuf);

						 sprintf((char*)filename, "/Storage/OCPP/TxProfile_Tmp_OCPP20.json.json");
						 filePtr = fopen((char*)filename, "w");
						 fprintf(filePtr, "{\"evseId\":0,\"chargingProfile\":%s}\n", json_object_to_json_string_ext(json_object_object_get(RemoteStartTransaction, "chargingProfile"), JSON_C_TO_STRING_PLAIN));
						 fclose(filePtr);
					 }

					 refreshStartTimer(&clientTime.RemoteStartWait);
					 ShmOCPP20Data->MsMsg.bits.isRemoteStartWaitReq = ON;

					 for(uint8_t gun_index=0;gun_index<gunTotalNumber;gun_index++)
	 				 {
						 sprintf((char*)ShmOCPP20Data->RequestStartTransaction[gun_index].Response_status, "%s", RequestStartStopStatusEnumTypeStr[RequestStartStopStatusEnumType_Accepted]);
						 random_uuid((char*)ShmOCPP20Data->RequestStartTransaction[gun_index].Response_transactionId);
	 				 }

					 result = PASS;
				 }
				 else
				 {
					 DEBUG_INFO("There is not any connector is idle.\n");

					 for(uint8_t gun_index=0;gun_index<gunTotalNumber;gun_index++)
						 strcpy((char*)ShmOCPP20Data->RequestStartTransaction[gun_index].Response_status, RequestStartStopStatusEnumTypeStr[RequestStartStopStatusEnumType_Rejected]);
				 }
			}
		}
		else
		{
			if(isOverConnectorMax != FALSE)
				DEBUG_WARN("evseId id equal 0 or over maximun id.\n");

			if(isPeriodOverMax)
				DEBUG_WARN("Profile periods quantity is over spec.\n");

			if(!isTxProfile)
				DEBUG_WARN("Profile purpose is not TxProfile.\n");

			if(!isAllowStart)
				DEBUG_WARN("Target connector does not allow start.\n");

			sprintf((char*)ShmOCPP20Data->RequestStartTransaction[((connectorIdx-1)<0?0:(connectorIdx-1))].Response_status, "%s", RequestStartStopStatusEnumTypeStr[RequestStartStopStatusEnumType_Rejected] );
		}
	}
	json_object_put(RemoteStartTransaction);

	sendRemoteStartTransactionConfirmation(uuid, ((connectorIdx-1)<0?0:(connectorIdx-1)));

	return result;
}

int handleRequestStopTransactionRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	int match = FALSE;
	int GunNO = 0;
	int tempIndex = 0;
	char transactionIdStr[37];
	int transactionIdIsNULL= TRUE;
	json_object *RemoteStopTransaction;

	DEBUG_INFO("handleRequestStopTransactionRequest...\n");

	if(server_pending == TRUE)
	{
		return 0;
	}

	RemoteStopTransaction = json_tokener_parse(payload);
	if(!is_error(RemoteStopTransaction))
	{
		if(json_object_object_get(RemoteStopTransaction, "transactionId") != NULL)
		{
			sprintf(transactionIdStr, "%s", json_object_get_string(json_object_object_get(RemoteStopTransaction, "transactionId")));
			transactionIdIsNULL = FALSE;
		}
	}
	json_object_put(RemoteStopTransaction);


	if(transactionIdIsNULL == FALSE)
	{
		for(int gun_index=0;gun_index < gunTotalNumber;gun_index++)
	    {
			if(strstr((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId, transactionIdStr) != NULL)
	        {
				//check Transaction active
				if(gunType[gun_index] == GUN_TYPE_CHAdeMO)
				{
					if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
					{
						tempIndex = ((gun_index==2) ? 1: 0);
					}
					else
					{
						tempIndex = gun_index;
					}

					for (int index = 0; index < CHAdeMO_QUANTITY; index++)
					{
						if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex)
						{
							if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_TERMINATING)) // SYS_MODE_CHARGING, SYS_MODE_TERMINATING
							{
								match = TRUE;
								GunNO = gun_index;
							}
						}
					}// END FOR CHAdeMO_QUANTITY

				}
				else if(gunType[gun_index] == GUN_TYPE_CCS)
				{
					if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
					{
						tempIndex = ((gun_index==2) ? 1: 0);
					}
					else
					{
						tempIndex = gun_index;
					}

					for (int index = 0; index < CCS_QUANTITY; index++)
					{
						if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
						{
							if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_TERMINATING) ) // SYS_MODE_CHARGING, SYS_MODE_TERMINATING
							{
								match = TRUE;
								GunNO = gun_index;
							}
						}
					}// END FOR CCS_QUANTITY
				}
				else if(gunType[gun_index] == GUN_TYPE_GBT)
				{
					if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
					{
						tempIndex = ((gun_index==2) ? 1: 0);
					}
					else
					{
						tempIndex = gun_index;
					}

					for (int index = 0; index < GB_QUANTITY; index++)
					{
						if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex)
						{
							if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_TERMINATING)) // SYS_MODE_CHARGING, SYS_MODE_TERMINATING
							{
								match = TRUE;
								GunNO = gun_index;
							}
						}
					}// END FOR GB_QUANTITY

				}
				else if(gunType[gun_index] == GUN_TYPE_DO)
				{
					tempIndex = gun_index;

					for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
					{
						if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
						{
							if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_TERMINATING)) // SYS_MODE_CHARGING, SYS_MODE_TERMINATING
							{
								match = TRUE;
								GunNO = gun_index;
							}
						}
					}// END FOR GB_QUANTITY

				}
				else
				{
					if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D') // 'D' means DC
					{
						tempIndex = 2;
					}
					else
					{
						tempIndex = gun_index;
					}

					for (int index = 0; index < AC_QUANTITY; index++)
					{
						if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
						{
							if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_TERMINATING)) // SYS_MODE_CHARGING, SYS_MODE_TERMINATING
							{
								match = TRUE;
								GunNO = gun_index;
							}
						}
					}// END FOR CHAdeMO_QUANTITY

				} // END FOR AC ELSE

	        }// CHECK IF ResponseTransactionId == transactionIdInt

	    }//END FOR

		if(	match == TRUE)
		{
			ShmOCPP20Data->CsMsg.bits[GunNO].RequestStopTransactionReq = ON; // inform csu of StopTransaction
			strcpy((char*)ShmOCPP20Data->RequestStopTransaction[GunNO].Response_status, RemoteStartStopStatusEnumTypeStr[RequestStartStopStatusEnumType_Accepted]);
		}
		else
		{
			strcpy((char*)ShmOCPP20Data->RequestStopTransaction[GunNO].Response_status, RemoteStartStopStatusEnumTypeStr[RequestStartStopStatusEnumType_Rejected]);
		}
	}
	else
		strcpy((char*)ShmOCPP20Data->RequestStopTransaction[GunNO].Response_status, RemoteStartStopStatusEnumTypeStr[RequestStartStopStatusEnumType_Rejected]);

	sendRemoteStopTransactionConfirmation(uuid, GunNO);
	return result;
}

int handleReserveNowRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	int connectorIdInt=0, reservationIdInt=0;
	int tempIndex = 0;
	json_object *ReserveNow;


	DEBUG_INFO("handleReserveNowRequest ...\n");
	ReserveNow = json_tokener_parse(payload);

	if(!is_error(ReserveNow))
	{
		if(json_object_object_get(ReserveNow, "evseId") != NULL)
		{
			connectorIdInt = json_object_get_int(json_object_object_get(ReserveNow, "evseId"));
			connectorIdInt = (connectorIdInt==0)?1:connectorIdInt;
			memset(&ShmOCPP20Data->ReserveNow[connectorIdInt-1], 0x00, sizeof(struct ReserveNow_20));

			ShmOCPP20Data->ReserveNow[connectorIdInt-1].evseId = json_object_get_int(json_object_object_get(ReserveNow, "evseId"));
		}

		// Required data
		if(json_object_object_get(ReserveNow, "reservationId") != NULL)
			ShmOCPP20Data->ReserveNow[connectorIdInt-1].id = json_object_get_int(json_object_object_get(ReserveNow, "reservationId"));

		if(json_object_object_get(ReserveNow, "expiryDateTime") != NULL)
			sprintf((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].expiryDateTime, "%s", json_object_get_string(json_object_object_get(ReserveNow, "expiryDateTime")));

		if(json_object_object_get(json_object_object_get(ReserveNow, "idToken"), "idToken") != NULL)
			sprintf((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].idToken.idToken, "%s", json_object_get_string(json_object_object_get(json_object_object_get(ReserveNow, "idToken"), "idToken")));

		if(json_object_object_get(json_object_object_get(ReserveNow, "idToken"), "type") != NULL)
			sprintf((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].idToken.type, "%s", json_object_get_string(json_object_object_get(json_object_object_get(ReserveNow, "idToken"), "type")));

		// Optional data
		if(json_object_object_get(ReserveNow, "connectorType") != NULL)
			sprintf((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].connectorType, "%s", json_object_get_string(json_object_object_get(ReserveNow, "connectorType")));

		if(json_object_object_get(json_object_object_get(ReserveNow, "groupIdToken"), "idToken") != NULL)
			sprintf((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].groupIdToken.idToken, "%s", json_object_get_string(json_object_object_get(json_object_object_get(ReserveNow, "groupIdToken"), "idToken")));

		if(json_object_object_get(json_object_object_get(ReserveNow, "groupIdToken"), "type") != NULL)
			sprintf((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].groupIdToken.type, "%s", json_object_get_string(json_object_object_get(json_object_object_get(ReserveNow, "groupIdToken"), "type")));

		result = PASS;
	}
	json_object_put(ReserveNow);

	strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Faulted]);

	if((connectorIdInt > 0) && ((connectorIdInt -1) <= gunTotalNumber))
	{
		//check Transaction active
		if(gunType[connectorIdInt -1] == GUN_TYPE_CHAdeMO)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = (((connectorIdInt -1)==2) ? 1: 0);
			}
			else
			{
				tempIndex = connectorIdInt -1;
			}

			for (int index = 0; index < CHAdeMO_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex)
				{
					if(reservationIdInt != ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ReservationId)
					{
						if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus != SYS_MODE_FAULT)&&(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus != SYS_MODE_ALARM)) //S_FAULT
						{
							if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_IDLE) //S_IDLE
							{
								if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ConnectorPlugIn == 1) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].InProgress == 1))
								{
									strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
								}
								else
								{
									ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
									strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]);
								}
							}
							else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_MAINTAIN)||(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //S_TERMINATING  //else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == 11) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == '9'))
							{
								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Unavailable]);

							}
							else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_PREPARING) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_RESERVATION) ) //S_PRECHARGE
							{
								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
							}
							else
							{
								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Rejected]);
							}
						}
						else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_FAULT) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_ALARM) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_TERMINATING)) // SYS_MODE_FAULT, SYS_MODE_ALARM, SYS_MODE_TERMINATING   ---> SuspendedEV
						{
							strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Faulted]);
						}
					}
					else
					{
						//replace reservation
						ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
						strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]);
					}

				}
			} // END FOR CHAdeMO_QUANTITY

		}
		else if(gunType[connectorIdInt -1] == GUN_TYPE_CCS)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = (((connectorIdInt -1)==2) ? 1: 0);
			}
			else
			{
				tempIndex = connectorIdInt -1;
			}

			for (int index = 0; index < CCS_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
				{

					if(reservationIdInt != ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ReservationId)
					{
						//SystemStatus:   0: Booting, 1: idle, 2: authorizing, 3: preparing, 4: charging, 5: terminating, 6: alarm, 7: fault, 8: Reserved, 9: maintain
						if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != SYS_MODE_FAULT)&&(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != SYS_MODE_ALARM)) //S_FAULT
						{
							if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_IDLE) //S_IDLE
							{
								if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ConnectorPlugIn == 1) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].InProgress == 1))
								{
									strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
								}
								else
								{
									ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
									strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]);
								}
							}
							else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_MAINTAIN) ||(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //S_TERMINATING  //else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == '6') || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == '9'))
							{
								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Unavailable]);
							}
							else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_PREPARING) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_RESERVATION)) //S_PRECHARGE
							{
								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
							}
							else
							{
								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Rejected]);
							}
						}
						else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus ==SYS_MODE_FAULT) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus ==SYS_MODE_ALARM) ||(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_TERMINATING)) //SYS_MODE_FAUL, SYS_MODE_TERMINATING  ---> SuspendedEV
						{
							strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Faulted]);
						}
					}
					else
					{
						//replace reservation
						ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
						strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]);
					}
				}
			} // END FOR CCS_QUANTITY

		}
		else if(gunType[connectorIdInt -1] == GUN_TYPE_GBT)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = (((connectorIdInt -1)==2) ? 1: 0);
			}
			else
			{
				tempIndex = connectorIdInt -1;
			}

			for (int index = 0; index < GB_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex)
				{

					if(reservationIdInt != ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ReservationId)
					{
						//SystemStatus:   0: Booting, 1: idle, 2: authorizing, 3: preparing, 4: charging, 5: terminating, 6: alarm, 7: fault, 8: Reserved, 9: maintain
						if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus != SYS_MODE_FAULT)&&(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus != SYS_MODE_ALARM)) //SYS_MODE_FAULT, SYS_MODE_ALARM
						{

							if(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_IDLE) //S_IDLE
							{
								if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ConnectorPlugIn == 1) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].InProgress == 1))
								{
									strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
								}
								else
								{
									ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
									strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]);
								}
							}
							else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //S_TERMINATING //else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == '6') || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == '9'))
							{
								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Unavailable]);
							}
							else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_PREPARING) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_RESERVATION) ) //S_PRECHARGE
							{
								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
							}
							else
							{
								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Rejected]);
							}
						}
						else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus ==SYS_MODE_FAULT) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus ==SYS_MODE_ALARM) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus ==SYS_MODE_TERMINATING)) //SYS_MODE_FAULT, SYS_MODE_ALARM ,SYS_MODE_TERMINATING  ---> SuspendedEV
						{
							strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Faulted]);
						}
					}
					else
					{
						//replace reservation
						ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
						strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]);
					}

				}
			}// END FOR GB_QUANTITY
		}
		else if(gunType[connectorIdInt -1] == GUN_TYPE_DO)
		{
			tempIndex = connectorIdInt -1;

			for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
				{

					if(reservationIdInt != ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ReservationId)
					{
						//SystemStatus:   0: Booting, 1: idle, 2: authorizing, 3: preparing, 4: charging, 5: terminating, 6: alarm, 7: fault, 8: Reserved, 9: maintain
						if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus != SYS_MODE_FAULT)&&(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus != SYS_MODE_ALARM)) //SYS_MODE_FAULT, SYS_MODE_ALARM
						{

							if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_IDLE) //S_IDLE
							{
								if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ConnectorPlugIn == 1) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.InProgress == 1))
								{
									strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
								}
								else
								{
									ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
									strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]);
								}
							}
							else if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_UPDATE)) //S_TERMINATING //else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == '6') || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == '9'))
							{
								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Unavailable]);
							}
							else if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_PREPARING) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_RESERVATION) ) //S_PRECHARGE
							{
								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
							}
							else
							{
								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Rejected]);
							}
						}
						else if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus ==SYS_MODE_FAULT) || (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus ==SYS_MODE_ALARM) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus ==SYS_MODE_TERMINATING)) //SYS_MODE_FAULT, SYS_MODE_ALARM ,SYS_MODE_TERMINATING  ---> SuspendedEV
						{
							strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Faulted]);
						}
					}
					else
					{
						//replace reservation
						ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
						strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]);
					}

				}
			}// END FOR DO_QUANTITY
		}
		else
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D') // 'D' means DC
			{
				tempIndex = 2;
			}
			else
			{
				tempIndex = (connectorIdInt -1);
			}

			for (int index = 0; index < AC_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
				{

					if(reservationIdInt != ShmSysConfigAndInfo->SysInfo.AcChargingData[index].ReservationId)
					{

						if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != SYS_MODE_FAULT)&&(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != SYS_MODE_ALARM)) //SYS_MODE_FAULT, SYS_MODE_ALARM
						{
							if(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_IDLE) //S_IDLE
							{
								if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState == CP_STATE_B) ||(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState == CP_STATE_C) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState == CP_STATE_D))
								{
									strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
								}
								else
								{
									ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
									strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]);
								}
							}
							else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_MAINTAIN) ||(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //S_TERMINATING  //else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == 11) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == '9'))
							{
								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Unavailable]);

							}
							else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_PREPARING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_RESERVATION) ) //S_PRECHARGE
							{
								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
							}
							else
							{
								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Rejected]);
							}
						}
						else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_FAULT) ||(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_ALARM) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_TERMINATING)) //SYS_MODE_FAULT, SYS_MODE_ALARM, SYS_MODE_TERMINATING ---> SuspendedEV
						{
							strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Faulted]);
						}
					}
					else
					{
						//replace reservation
						ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
						strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]);
					}
				}
			} // END FOR AC_QUANTITY
		}
	}
	else if(connectorIdInt == 0)
	{
		//check Transaction active
		for (int index = 0; index < CHAdeMO_QUANTITY; index++)
		{
			if(reservationIdInt != ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ReservationId)
			{
				if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //S_TERMINATING  //else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == 11) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == '9'))
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Unavailable]);
					 goto end;
				}
				else if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_PREPARING) //S_PRECHARGE
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
					goto end;
				}
				else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_FAULT) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_ALARM) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_TERMINATING)) //SYS_MODE_FAULT, SYS_MODE_TERMINATING ---> SuspendedEV
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Faulted]);
					goto end;
				}
				else if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus != SYS_MODE_IDLE) //S_IDLE
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Rejected]);
					goto end;
				}
			}

		}// END FOR CHAdeMO_QUANTITY

		for (int index = 0; index < CCS_QUANTITY; index++)
		{
			if(reservationIdInt != ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ReservationId)
			{
				if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_MAINTAIN)||(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //S_TERMINATING  //else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == '6') || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == '9'))
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Unavailable]);
					goto end;
				}
				else if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_PREPARING) //SYS_MODE_PREPARING
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
					goto end;
				}
				else if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus ==SYS_MODE_FAULT) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus ==SYS_MODE_ALARM) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus ==SYS_MODE_TERMINATING)) //SYS_MODE_FAULT, SYS_MODE_TERMINATING ---> SuspendedEV
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Faulted]);
					goto end;
				}
				else if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != SYS_MODE_IDLE) //S_IDLE
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Rejected]);
					goto end;
				}
			}
		} // END FOR CCS_QUANTITY

		for (int index = 0; index < GB_QUANTITY; index++)
		{
			if(reservationIdInt != ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ReservationId)
			{
				if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_MAINTAIN)||(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //S_TERMINATING //else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == '6') || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == '9'))
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Unavailable]);
					goto end;
				}
				else if(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_PREPARING) //S_PRECHARGE
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
					goto end;
				}
				else if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus ==SYS_MODE_FAULT) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus ==SYS_MODE_ALARM) || (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus ==SYS_MODE_TERMINATING) ) //SYS_MODE_FAULT, SYS_MODE_TERMINATING ---> SuspendedEV
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Faulted]);
					goto end;
				}
				else if(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus != SYS_MODE_IDLE) //S_IDLE
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Rejected]);
					goto end;
				}
			}

		} // END FOR GB_QUANTITY

		for (int index = 0; index < AC_QUANTITY; index++)
		{
			if(reservationIdInt != ShmSysConfigAndInfo->SysInfo.AcChargingData[index].ReservationId)
			{
				if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_MAINTAIN) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_DEBUG) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_UPDATE)) //S_TERMINATING  //else if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == 11) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == '9'))
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Unavailable]);
					goto end;
				}
				else if(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_PREPARING) //S_PRECHARGE
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
					goto end;
				}
				else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_FAULT) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_ALARM) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_TERMINATING)) //SYS_MODE_FAULT, SYS_MODE_TERMINATING ---> SuspendedEV
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Faulted]);
					goto end;
				}
				if(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_IDLE) //S_IDLE
				{
					if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState == CP_STATE_B) ||(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState == CP_STATE_C) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState == CP_STATE_D))
					{
						strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
						goto end;
					}
				}
				else if(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != SYS_MODE_IDLE) //S_IDLE
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Rejected]);
					goto end;
				}
			}

		}// END FOR AC_QUANTITY

		//The connectorId is 0
		ShmOCPP20Data->CsMsg.bits[0].ReserveNowReq = ON;
		strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]);
		strcpy((char *)ShmOCPP20Data->ReserveNow[0].guid, uuid);

		result = TRUE;
		return result;
	}
	else
	{
		strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Rejected]);
	}

	if(strcmp((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status,ReserveNowStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]) == 0)
	{
	    strcpy((char *)ShmOCPP20Data->ReserveNow[connectorIdInt-1].guid, uuid);

	    result = TRUE;
	    return result;
	}

end:
	sendReserveNowConfirmation(uuid, (connectorIdInt==0?connectorIdInt:connectorIdInt-1));
	return result;
}

int handleResetRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	json_object *Reset = json_object_new_object();

	DEBUG_INFO("handleResetRequest...\n");
	Reset = json_tokener_parse(payload);

	if(!is_error(Reset))
	{
		// Required data
		if(json_object_object_get(Reset, "type") != NULL)
		{
			sprintf((char*)ShmOCPP20Data->Reset.type, "%s", json_object_get_string(json_object_object_get(Reset, "type")));
		}

		if(json_object_object_get(Reset, "evseId") != NULL)
		{
			ShmOCPP20Data->Reset.evseId = json_object_get_int(json_object_object_get(Reset, "evseId"));
		}
	}
	json_object_put(Reset);

	if((strcmp((char*)ShmOCPP20Data->Reset.type, ResetEnumTypeStr[ResetEnumType_Immediate])==0) || (strcmp((char*)ShmOCPP20Data->Reset.type, ResetEnumTypeStr[ResetEnumType_OnIdle])==0))
	{
	    strcpy((char *)ShmOCPP20Data->Reset.guid, uuid);
	    strcpy((char*)ShmOCPP20Data->Reset.Response_status, ResetStatusEnumTypeStr[ResetStatusEnumType_Accepted]);
	    ShmOCPP20Data->MsMsg.bits.ResetReq = ON;

	    result = PASS;
	}
	else
	{
		strcpy((char*)ShmOCPP20Data->Reset.Response_status, ResetStatusEnumTypeStr[ResetStatusEnumType_Rejected]);
	}

	if(strlen((char*)ShmOCPP20Data->Reset.Response_status) > 0)
		sendResetConfirmation(uuid);

	return result;
}

int handleSendLocalListRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	int checkState_Faulted = FALSE;
	json_object *SendLocalList;

	DEBUG_INFO("handleSendLocalListRequest...\n");
	if(strcmp((const char *)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Enabled].variableAttribute[0].value, "FALSE") == 0)
	{
		strcpy((char*)ShmOCPP20Data->SendLocalList.Response_status, UpdateStatusEnumTypeStr[UpdateStatusEnumType_Failed]);
		goto end;
	}

	SendLocalList = json_tokener_parse(payload);
	if(!is_error(SendLocalList))
	{
		memset(&ShmOCPP20Data->SendLocalList, 0x00, sizeof(struct SendLocalList_20));

		// Required data
		if(json_object_object_get(SendLocalList, "versionNumber") != NULL)
		{
			ShmOCPP20Data->SendLocalList.versionNumber = json_object_get_int(json_object_object_get(SendLocalList, "versionNumber"));
		}

		if(json_object_object_get(SendLocalList, "updateType") != NULL)
			sprintf((char*)ShmOCPP20Data->SendLocalList.updateType, "%s", json_object_get_string(json_object_object_get(SendLocalList, "updateType")));

		// Optional data
		if(json_object_object_get(SendLocalList, "localAuthorizationList") != NULL)
		{
			for(int idx=0;idx<json_object_array_length(json_object_object_get(SendLocalList, "localAuthorizationList"));idx++)
			{
				// Required data
				if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SendLocalList, "localAuthorizationList"), idx), "idToken") != NULL)
				{
					sprintf((char*)ShmOCPP20Data->SendLocalList.localAuthorizationList[idx].idToken.idToken, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SendLocalList, "localAuthorizationList"), idx), "idToken"), "idToken")));
					sprintf((char*)ShmOCPP20Data->SendLocalList.localAuthorizationList[idx].idToken.type, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SendLocalList, "localAuthorizationList"), idx), "idToken"), "type")));
				}

				if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SendLocalList, "localAuthorizationList"), idx), "idTagInfo") != NULL)
				{
					sprintf((char*)ShmOCPP20Data->SendLocalList.localAuthorizationList[idx].idTokenInfo.status, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SendLocalList, "localAuthorizationList"), idx), "idTagInfo"), "status")));

					if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SendLocalList, "localAuthorizationList"), idx), "idTagInfo"), "cacheExpiryDateTime") != NULL)
						sprintf((char*)ShmOCPP20Data->SendLocalList.localAuthorizationList[idx].idTokenInfo.cacheExpiryDateTime, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SendLocalList, "localAuthorizationList"), idx), "idTagInfo"), "cacheExpiryDateTime")));

					if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SendLocalList, "localAuthorizationList"), idx), "idTagInfo"), "chargingPriority") != NULL)
						ShmOCPP20Data->SendLocalList.localAuthorizationList[idx].idTokenInfo.chargingPriority = json_object_get_int(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SendLocalList, "localAuthorizationList"), idx), "idTagInfo"), "chargingPriority"));

					if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SendLocalList, "localAuthorizationList"), idx), "idTagInfo"), "groupIdToken") != NULL)
					{
						sprintf((char*)ShmOCPP20Data->SendLocalList.localAuthorizationList[idx].idTokenInfo.groupIdToken.idToken, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SendLocalList, "localAuthorizationList"), idx), "idTagInfo"), "groupIdToken"), "idToken")));
						sprintf((char*)ShmOCPP20Data->SendLocalList.localAuthorizationList[idx].idTokenInfo.groupIdToken.type, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SendLocalList, "localAuthorizationList"), idx), "idTagInfo"), "groupIdToken"), "type")));
					}
				}
			}
		}
	}
	json_object_put(SendLocalList);

	//check Charge Point state
	for (int index = 0; index < CHAdeMO_QUANTITY; index++)
	{
		if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_FAULT) //S_FAULT   ---> Faulted
		{
			checkState_Faulted = TRUE; //OCPP Status: Faulted
		}
	}

	for (int index = 0; index < CCS_QUANTITY; index++)
	{
		if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_FAULT) //S_FAULT   ---> Faulted
		{
			checkState_Faulted = TRUE; //OCPP Status
		}
	}

	for (int index = 0; index < GB_QUANTITY; index++)
	{
		if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_FAULT) //S_FAULT   ---> Faulted
		{
			checkState_Faulted = TRUE; //OCPP Status: Faulted
		}
	}

	for (int index = 0; index < AC_QUANTITY; index++)
	{
		if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_FAULT) //S_FAULT   ---> Faulted
		{
			checkState_Faulted = TRUE; //OCPP Status: Faulted
		}
	}

	if(checkState_Faulted == TRUE)
	{
		strcpy((char*)ShmOCPP20Data->SendLocalList.Response_status, UpdateStatusEnumTypeStr[UpdateStatusEnumType_Failed]);
		goto end;
	}

	// Check update type
	if(strcmp((char*)ShmOCPP20Data->SendLocalList.updateType, UpdateEnumTypeStr[UpdateEnumType_Full]) == 0)
	{
		//Local list full update
		DEBUG_INFO("Local list full update.\n");

		DB_getListVerion();

		/*if(ShmOCPP20Data->SendLocalList.versionNumber < localversion )//if(listVersionInt <= localversion ) for OCTT Case ---remove temporally
		{
			strcpy((char*)ShmOCPP20Data->SendLocalList.Response_status, UpdateStatusEnumTypeStr[UpdateStatusEnumType_Failed]);
			goto end;
		}*/

		DB_cleanLocalList();

		for(int idx=0;idx<ARRAY_SIZE(ShmOCPP20Data->SendLocalList.localAuthorizationList);idx++)
			DB_addLocalList(ShmOCPP20Data->SendLocalList.versionNumber, &ShmOCPP20Data->SendLocalList.localAuthorizationList[idx]);
	}
	else if(strcmp((char*)ShmOCPP20Data->SendLocalList.updateType, UpdateEnumTypeStr[UpdateEnumType_Differential]) == 0)
	{
		//Local list different update
		DEBUG_INFO("Local list different update.\n");

		DB_getListVerion();

		if(ShmOCPP20Data->SendLocalList.versionNumber < localversion )//if(listVersionInt <= localversion ) for OCTT Case ---remove temporally
		{
			strcpy((char*)ShmOCPP20Data->SendLocalList.Response_status, UpdateStatusEnumTypeStr[UpdateStatusEnumType_VersionMismatch]);
			goto end;
		}

		for(int idx=0;idx<ARRAY_SIZE(ShmOCPP20Data->SendLocalList.localAuthorizationList);idx++)
			DB_addLocalList(ShmOCPP20Data->SendLocalList.versionNumber, &ShmOCPP20Data->SendLocalList.localAuthorizationList[idx]);
	}
	else
	{
		strcpy((char*)ShmOCPP20Data->SendLocalList.Response_status, UpdateStatusEnumTypeStr[UpdateStatusEnumType_Failed]);
		goto end;
	}
	strcpy((char*)ShmOCPP20Data->SendLocalList.Response_status, UpdateStatusEnumTypeStr[UpdateStatusEnumType_Accepted]);

end:
	sendSendLocalListConfirmation(uuid);
	system("/bin/fsync -d /dev/mtdblock13;/bin/sync &");
	return result;
}

int handleSetChargingProfileRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	struct SetChargingProfile_20 SetProfileReq = {0};
	uint8_t isLostConnectorId = FALSE;
	uint8_t isPeriodOverMax = FALSE;
	uint8_t isStackOverMax = FALSE;
	uint8_t isProfileOverMax = FALSE;
	uint8_t isConnectorMismatch = FALSE;
	uint8_t isTransactiodIdMismatch = FALSE;
	uint8_t isInvalidLimit = FALSE;
	uint8_t isWrongFormat = FALSE;
	uint8_t replaceableProfileCnt = 0;
	uint8_t existProfileQuantity = 0;
	uint8_t filename[128]={0};
	uint8_t dataLine[4096]={0};
	FILE *filePtr;
	json_object *SetChargingProfile;

	DEBUG_INFO("handleSetChargingProfileRequest...\n");
	SetChargingProfile = json_tokener_parse(payload);
	if(!is_error(SetChargingProfile))
	{
		// Required data
		if(json_object_object_get(SetChargingProfile, "evseId") != NULL)
			SetProfileReq.evseId = json_object_get_int(json_object_object_get(SetChargingProfile, "evseId"));
		else
			isLostConnectorId = TRUE;

		if(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "id") != NULL)
			SetProfileReq.chargingProfile.id = json_object_get_int((json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "id")));

		if(json_object_object_get(SetChargingProfile, "chargingProfile") != NULL)
		{
			sprintf((char*)SetProfileReq.chargingProfile.chargingProfilePurpose, "%s", json_object_get_string(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingProfilePurpose")));

			if(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "stackLevel") != NULL)
			{
				SetProfileReq.chargingProfile.stackLevel = json_object_get_int(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "stackLevel"));
			}

			if(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingProfilePurpose") != NULL)
			{
				strcpy((char*)SetProfileReq.chargingProfile.chargingProfilePurpose, json_object_get_string(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingProfilePurpose")));
			}

			if(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingProfileKind") != NULL)
			{
				strcpy((char*)SetProfileReq.chargingProfile.chargingProfileKind, json_object_get_string(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingProfileKind")));
			}

			if(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "transactionId") != NULL)
			{
				strcpy((char*)SetProfileReq.chargingProfile.transactionId, json_object_get_string(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "transactionId")));
			}

			if(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "recurrencyKind") != NULL)
			{
				strcpy((char*)SetProfileReq.chargingProfile.recurrencyKind, json_object_get_string(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "recurrencyKind")));
			}

			if(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "validFrom") != NULL)
			{
				strcpy((char*)SetProfileReq.chargingProfile.validFrom, json_object_get_string(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "validFrom")));
			}

			if(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "validTo") != NULL)
			{
				strcpy((char*)SetProfileReq.chargingProfile.validTo, json_object_get_string(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "validTo")));
			}

			if(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingSchedule") != NULL)
			{
				int chargingScheduleCount = 0;
				int chargingSchedulePeriodCount = 0;
				if(json_object_is_type(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingSchedule"), 5))
				{
					chargingScheduleCount = json_object_array_length(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingSchedule"));
					for(int idxSchedule=0;idxSchedule<chargingScheduleCount;idxSchedule++)
					{
						if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingSchedule"), idxSchedule), "chargingRateUnit") != NULL)
						{
							strcpy((char*)SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingRateUnit, json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingSchedule"), idxSchedule), "chargingRateUnit")));
						}

						if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingSchedule"), idxSchedule), "duration") != NULL)
						{
							SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].duration = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingSchedule"), idxSchedule), "duration"));
						}

						if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingSchedule"), idxSchedule), "minChargingRate") != NULL)
						{
							SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].minChargingRate = json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingSchedule"), idxSchedule), "minChargingRate"));
						}

						if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingSchedule"), idxSchedule), "startSchedule") != NULL)
						{
							strcpy((char*)SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].startSchedule, json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingSchedule"), idxSchedule), "startSchedule")));
						}

						if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingSchedule"), idxSchedule), "chargingSchedulePeriod") != NULL)
						{
							chargingSchedulePeriodCount = json_object_array_length(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingSchedule"), idxSchedule), "chargingSchedulePeriod"));
							if(chargingSchedulePeriodCount <= atoi((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_PeriodsPerSchedule].variableAttribute[0].value))
							{
								for(int idxPeriod=0;idxPeriod<chargingSchedulePeriodCount;idxPeriod++)
								{
									if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingSchedule"), idxSchedule), "chargingSchedulePeriod"), idxPeriod), "startPeriod") != NULL)
									{
										SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].startPeriod = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingSchedule"), idxSchedule), "chargingSchedulePeriod"), idxPeriod), "startPeriod"));
									}

									if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingSchedule"), idxSchedule), "chargingSchedulePeriod"), idxPeriod), "limit") != NULL)
									{
										SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit = json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingSchedule"), idxSchedule), "chargingSchedulePeriod"), idxPeriod), "limit"));
									}

									if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingSchedule"), idxSchedule), "chargingSchedulePeriod"), idxPeriod), "numberPhases") != NULL)
									{
										SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingSchedule"), idxSchedule), "chargingSchedulePeriod"), idxPeriod), "numberPhases"));
									}

									if(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingSchedule"), idxSchedule), "chargingSchedulePeriod"), idxPeriod), "phaseToUse") != NULL)
									{
										SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].phaseToUse = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_array_get_idx(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingSchedule"), idxSchedule), "chargingSchedulePeriod"), idxPeriod), "phaseToUse"));
									}

									// Check invalid limit
									if((strstr((char*)SetProfileReq.chargingProfile.chargingProfilePurpose, ChargingProfilePurposeEnumTypeStr[ChargingProfilePurposeEnumType_ChargingStationMaxProfile]) == NULL) ||
									   ((strstr((char*)SetProfileReq.chargingProfile.chargingProfilePurpose, ChargingProfilePurposeEnumTypeStr[ChargingProfilePurposeEnumType_ChargingStationMaxProfile]) != NULL) && (ShmSysConfigAndInfo->SysConfig.isEnableLocalPowerSharing != 1)))
									{
										if(ShmSysConfigAndInfo->SysConfig.ModelName[0] == 'A')
										{
											if(((0 < SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit) && (SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit < (SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingRateUnit[0]=='A'?6:6*220*(SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases==0?3:SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases)))) ||
												(SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit > (SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingRateUnit[0]=='W'?modelnameInfo.ratedPower:ShmSysConfigAndInfo->SysConfig.RatingCurrent)))
											{
												DEBUG_WARN("Profile chargingSchedule-%d period-%02d is invalid limit: %.2f %s with phase %d.\n", idxSchedule, idxPeriod,
																															 SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit,
																															 SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingRateUnit,
																															 (SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases==0?3:SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases));
												DEBUG_WARN("Rated Power: %d, Rating Current: %d\n", modelnameInfo.ratedPower, ShmSysConfigAndInfo->SysConfig.RatingCurrent);
												isInvalidLimit = TRUE;
											}
										}
										else
										{
											if((SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit*(SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingRateUnit[0]=='W'?1:220*(SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases==0?3:SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases)) > modelnameInfo.ratedPower) ||
											   (SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit*(SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingRateUnit[0]=='W'?1:220*(SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases==0?3:SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases)) < (modelnameInfo.ratedPower*0.01)))
											{
												DEBUG_WARN("Profile period-%02d is invalid limit: %.2f %s with phase %d.\n", idxPeriod,
																															 SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].limit,
																															 SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingRateUnit,
																															 (SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases==0?3:SetProfileReq.chargingProfile.chargingSchedule[idxSchedule].chargingSchedulePeriod[idxPeriod].numberPhases));
												DEBUG_WARN("Rated Power: %d \n", modelnameInfo.ratedPower);
												isInvalidLimit = TRUE;
											}
										}
									}
								}
							}
							else
							{
								isPeriodOverMax = TRUE;
							}
						}
					}
				}
				else
				{
					isWrongFormat = TRUE;
				}
			}

			// Check periods is over max configuration
			if(strstr((char*)SetProfileReq.chargingProfile.chargingProfilePurpose, ChargingProfilePurposeEnumTypeStr[ChargingProfilePurposeEnumType_ChargingStationMaxProfile]) != NULL)
			{
				if(SetProfileReq.evseId == 0)
				{
					sprintf((char*)filename, ChargingStationMaxProfile_JSON);
					filePtr = fopen((char*)filename, "r");
					if (!filePtr)
					{
						DEBUG_INFO("%s not exist, create it.\n", ChargingStationMaxProfile_JSON);
						filePtr = fopen((char*)filename, "w+");
					}
					else
					{
						//Check Charging Profile Count
						//while(fscanf(filePtr, "%s", dataLine) != EOF)
						char *line = NULL;
						size_t len = 0;
						while(getline(&line, &len, filePtr) != -1)
						{
							json_object *obj = NULL;

							obj = json_tokener_parse(line);
							if(is_error(obj))
							{
								DEBUG_ERROR("Parse ChargingStationMaxProfile from file error.\n");
							}
							else
							{
								if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "id")) != SetProfileReq.chargingProfile.id) &&
								   (json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "stackLevel")) != SetProfileReq.chargingProfile.stackLevel))
								{
									existProfileQuantity += 1;
								}
								else
									replaceableProfileCnt += 1;
							}

							//DEBUG_INFO("word=%s\n",word);
							/*if(strstr((char*)dataLine, "id")!= NULL)
							{
								existProfileQuantity += 1;
							}*/
						}
						DEBUG_INFO("existProfileQuantity: %d, Max stack limit: %d\n", existProfileQuantity, atoi((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ProfileStackLevel].variableAttribute[0].value));

						if(existProfileQuantity >= atoi((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ProfileStackLevel].variableAttribute[0].value))
						{
							isStackOverMax = TRUE;
						}
					}
					fclose(filePtr);
				}
				else
					isConnectorMismatch = TRUE;
			}
			else if(strstr((char*)SetProfileReq.chargingProfile.chargingProfilePurpose, ChargingProfilePurposeEnumTypeStr[ChargingProfilePurposeEnumType_TxDefaultProfile]) != NULL)
			{
				if((0 < SetProfileReq.evseId) && (SetProfileReq.evseId > gunTotalNumber))
					isConnectorMismatch = TRUE;

				if(!isConnectorMismatch)
				{
					if(SetProfileReq.evseId == 0)
					{
						int tmpExistProfileQuantity;

						for(int idxCon=1;idxCon<=gunTotalNumber;idxCon++)
						{
							tmpExistProfileQuantity = 0;
							sprintf((char*)filename, "/Storage/OCPP/TxDefaultProfile_%d_OCPP20.json", idxCon);
							filePtr = fopen((char*)filename, "r");
							if (!filePtr)
							{
								DEBUG_INFO("%s not exist, create it.\n", filename);
								filePtr = fopen((char*)filename, "w+");
							}
							else
							{
								//Check Charging Profile Count
								//while(fscanf(filePtr, "%s", dataLine) != EOF)
								char *line = NULL;
								size_t len = 0;
								while(getline(&line, &len, filePtr) != -1)
								{
									json_object *obj = NULL;

									obj = json_tokener_parse(line);
									if(is_error(obj))
									{
										DEBUG_ERROR("Parse ChargingStationMaxProfile from file error.\n");
									}
									else
									{
										if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "id")) != SetProfileReq.chargingProfile.id) &&
										   (json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "stackLevel")) != SetProfileReq.chargingProfile.stackLevel))
										{
											tmpExistProfileQuantity += 1;
										}
										else
											replaceableProfileCnt += 1;
									}

									//DEBUG_INFO("word=%s\n",word);
									/*if(strstr((char*)dataLine, "id")!= NULL)
									{
										tmpExistProfileQuantity += 1;
									}*/
								}
							}
							fclose(filePtr);
							DEBUG_INFO("existProfileQuantity: %d, Max stack limit: %d\n", tmpExistProfileQuantity, atoi((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ProfileStackLevel].variableAttribute[0].value));

							if(tmpExistProfileQuantity >= atoi((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ProfileStackLevel].variableAttribute[0].value))
							{
								isStackOverMax = TRUE;
							}
							//existProfileQuantity = (existProfileQuantity < tmpExistProfileQuantity) ? tmpExistProfileQuantity : existProfileQuantity;
						}
					}
					else
					{
						sprintf((char*)filename, "/Storage/OCPP/TxDefaultProfile_%d_OCPP20.json", SetProfileReq.evseId);
						filePtr = fopen((char*)filename, "r");
						if (!filePtr)
						{
							DEBUG_INFO("%s not exist, create it.\n", filename);
							filePtr = fopen((char*)filename, "w+");
						}
						else
						{
							//Check Charging Profile Count
							//while(fscanf(filePtr, "%s", dataLine) != EOF)
							char *line = NULL;
							size_t len = 0;
							while(getline(&line, &len, filePtr) != -1)
							{
								json_object *obj = NULL;

								obj = json_tokener_parse(line);
								if(is_error(obj))
								{
									DEBUG_ERROR("Parse TxDefaultProfile from file error.\n");
								}
								else
								{
									if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "id")) != SetProfileReq.chargingProfile.id) &&
									   (json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "stackLevel")) != SetProfileReq.chargingProfile.stackLevel))
									{
										existProfileQuantity += 1;
									}
									else
										replaceableProfileCnt += 1;
								}

								//DEBUG_INFO("word=%s\n",word);
								/*if(strstr((char*)dataLine, "id")!= NULL)
								{
									existProfileQuantity += 1;
								}*/
							}
							DEBUG_INFO("existProfileQuantity: %d, Max stack limit: %d\n", existProfileQuantity, atoi((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ProfileStackLevel].variableAttribute[0].value));
							if(existProfileQuantity >= atoi((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ProfileStackLevel].variableAttribute[0].value))
							{
								isStackOverMax = TRUE;
							}
						}
						fclose(filePtr);
					}
				}
			}
			else if(strstr((char*)SetProfileReq.chargingProfile.chargingProfilePurpose, ChargingProfilePurposeEnumTypeStr[ChargingProfilePurposeEnumType_TxProfile]) != NULL)
			{
				if((SetProfileReq.evseId > 0) && (SetProfileReq.evseId <= gunTotalNumber))
					sprintf((char*)filename, "/Storage/OCPP/TxProfile_%d_OCPP20.json", SetProfileReq.evseId);
				else
					isConnectorMismatch = TRUE;

				if(!isConnectorMismatch)
				{
					filePtr = fopen((char*)filename, "r");
					if (!filePtr)
					{
						DEBUG_INFO("%s not exist, create it.\n", filename);
						filePtr = fopen((char*)filename, "w+");
					}
					else
					{
						//Check Charging Profile Count
						//while(fscanf(filePtr, "%s", dataLine) != EOF)
						char *line = NULL;
						size_t len = 0;
						while(getline(&line, &len, filePtr) != -1)
						{
							json_object *obj = NULL;

							obj = json_tokener_parse(line);
							if(is_error(obj))
							{
								DEBUG_ERROR("Parse TxProfile from file error.\n");
							}
							else
							{
								if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "id")) != SetProfileReq.chargingProfile.id) &&
								   (json_object_get_int(json_object_object_get(json_object_object_get(obj, "chargingProfile"), "stackLevel")) != SetProfileReq.chargingProfile.stackLevel))
								{
									existProfileQuantity += 1;
								}
								else
									replaceableProfileCnt += 1;
							}
							//DEBUG_INFO("word=%s\n",word);
							/*if(strstr((char*)dataLine, "id")!= NULL)
							{
								existProfileQuantity += 1;
							}*/
						}
						DEBUG_INFO("existProfileQuantity: %d, Max stack limit: %d\n", existProfileQuantity, atoi((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ProfileStackLevel].variableAttribute[0].value));

						if(existProfileQuantity >= atoi((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_ProfileStackLevel].variableAttribute[0].value))
						{
							isStackOverMax = TRUE;
						}
					}
					fclose(filePtr);

					if(SetProfileReq.chargingProfile.transactionId != ShmOCPP20Data->TransactionEvent[SetProfileReq.evseId-1].transactionInfo.transactionId)
						isTransactiodIdMismatch = TRUE;
				}
			}
			else if(strstr((char*)SetProfileReq.chargingProfile.chargingProfilePurpose, ChargingProfilePurposeEnumTypeStr[ChargingProfilePurposeEnumType_ChargingStationExternalConstraints]) != NULL)
			{
				/*
				 *	TODO:
				 *
				 */
			}
			else
			{}

			//------------------------------Start: Check ChargingProfileEntries Logic---------------------------------------//
			{
				FILE *fp;
				char dataLine[4096]={0};
				char fnametemp[128]={0};
				int tmpProfileQuantity;
				//Check ChargePointMaxProfile.json exit
				existProfileQuantity = 0;

				if((access(ChargingStationMaxProfile_JSON,F_OK))!=-1)
				{
					fp = fopen(ChargingStationMaxProfile_JSON, "r");
					//Check Charging Profile Count
					tmpProfileQuantity = 0;
					while(fscanf(fp, "%s", dataLine) != EOF)
					{
						if(strstr(dataLine, "id")!= NULL)
						{
							existProfileQuantity += 1;
							tmpProfileQuantity += 1;
						}
						memset(dataLine, 0, ARRAY_SIZE(dataLine));
					}
					fclose(fp);
					DEBUG_INFO("ChargePointMaxProfile_OCPP20.json has %d charging Profile\n", tmpProfileQuantity);
				}

				//Check TxDefaultProfile_%d.json
				for(int idxCon=1; idxCon <= gunTotalNumber; idxCon++)
				{
					memset(fnametemp, 0, ARRAY_SIZE(fnametemp));
					sprintf(fnametemp, "/Storage/OCPP/TxDefaultProfile_%d_OCPP20.json", idxCon);
					if((access(fnametemp,F_OK))!=-1)
					{
						fp = fopen(fnametemp, "r");
						//Check Charging Profile Count
						tmpProfileQuantity = 0;
						while(fscanf(fp, "%s", dataLine) != EOF)
						{
							//DEBUG_INFO("word=%s\n",word);
							if(strstr(dataLine, "id")!= NULL)
							{
								existProfileQuantity += 1;
								tmpProfileQuantity += 1;
							}
							memset(dataLine, 0, ARRAY_SIZE(dataLine));
						}
						fclose(fp);
						DEBUG_INFO("%s has %d charging Profile\n",fnametemp, tmpProfileQuantity);
					}
				}

				//Check TxProfile_%d.json
				for(int idxCon=1; idxCon <= gunTotalNumber; idxCon++)
				{
					memset(fnametemp, 0, ARRAY_SIZE(fnametemp));
					sprintf(fnametemp, "/Storage/OCPP/TxProfile_%d_OCPP20.json", idxCon);
					if((access(fnametemp,F_OK))!=-1)
					{
						fp = fopen(fnametemp, "r");
						//Check Charging Profile Count
						tmpProfileQuantity = 0;
						while(fscanf(fp, "%s", dataLine) != EOF)
						{
							if(strstr(dataLine, "id")!= NULL)
							{
								existProfileQuantity += 1;
								tmpProfileQuantity += 1;
							}
							memset(dataLine, 0, ARRAY_SIZE(dataLine));
						}
						fclose(fp);
						DEBUG_INFO("%s has %d charging Profile\n",fnametemp, tmpProfileQuantity);
					}
				}

				DEBUG_INFO("All purpose profile quantity: %d\n", existProfileQuantity);
				DEBUG_INFO("Replaceable profile quantity: %d\n", replaceableProfileCnt);

				// To check total Profile quantity
				if((SetProfileReq.evseId > 0) || (strstr((char*)SetProfileReq.chargingProfile.chargingProfilePurpose, ChargingProfilePurposeEnumTypeStr[ChargingProfilePurposeEnumType_ChargingStationMaxProfile]) != NULL))
				{
					if((existProfileQuantity-replaceableProfileCnt) >= atoi((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].variableAttribute[0].value))
						isProfileOverMax = TRUE;
				}
				else
				{
					if((existProfileQuantity+gunTotalNumber-replaceableProfileCnt) > atoi((char*)ShmOCPP20Data->ControllerComponentVariable[SmartChargingCtrlr_Entries].variableAttribute[0].value))
						isProfileOverMax = TRUE;
				}
			}
			//------------------------------End: Check ChargingProfileEntries Logic---------------------------------------//
		}

		// Profile replace or add info
		if(!isLostConnectorId && !isPeriodOverMax && !isProfileOverMax && !isConnectorMismatch && !isTransactiodIdMismatch && !isInvalidLimit && !isWrongFormat && !isStackOverMax)
		{
			FILE *infile;
			FILE *outfile;
			char tmpProfileName[] = "/Storage/OCPP/SetChargingProfiletemp_OCPP20.json";
			char rmFileCmd[128];
			int tempchargingProfileIdInt;
			int tempchargingProfileStackLevelInt;
			int chkChar;

			for(int idxCon=1; idxCon <= (SetProfileReq.evseId==0?gunTotalNumber:1); idxCon++)
			{
				if(strcmp((char*)SetProfileReq.chargingProfile.chargingProfilePurpose, ChargingProfilePurposeEnumTypeStr[ChargingProfilePurposeEnumType_ChargingStationMaxProfile]) == 0)
				{
					sprintf((char*)filename, "%s", ChargingStationMaxProfile_JSON);
				}
				else if(strcmp((char*)SetProfileReq.chargingProfile.chargingProfilePurpose, ChargingProfilePurposeEnumTypeStr[ChargingProfilePurposeEnumType_TxDefaultProfile]) == 0)
				{
					if(SetProfileReq.evseId==0)
						sprintf((char*)filename, "/Storage/OCPP/TxDefaultProfile_%d_OCPP20.json", idxCon);
					else
						sprintf((char*)filename, "/Storage/OCPP/TxDefaultProfile_%d_OCPP20.json", SetProfileReq.evseId);
				}
				else if(strcmp((char*)SetProfileReq.chargingProfile.chargingProfilePurpose, ChargingProfilePurposeEnumTypeStr[ChargingProfilePurposeEnumType_TxProfile]) == 0)
				{
					sprintf((char*)filename, "/Storage/OCPP/TxProfile_%d_OCPP20.json", SetProfileReq.evseId);
				}
				else
				{
					/*
					 *	TODO:
					 *
					 */
				}


				infile = fopen ((char*)filename, "r");
				outfile = fopen ((char*)tmpProfileName, "w");

				chkChar = fgetc(infile);
				rewind(infile);
				if(chkChar == EOF)
				{
					// Profile is empty
					if((strcmp((char*)SetProfileReq.chargingProfile.chargingProfilePurpose, ChargingProfilePurposeEnumTypeStr[ChargingProfilePurposeEnumType_TxDefaultProfile]) == 0) && (SetProfileReq.evseId==0))
						json_object_object_add(SetChargingProfile, "evseId", json_object_new_int(idxCon));
					fprintf(outfile,"%s\n",json_object_to_json_string_ext(SetChargingProfile, JSON_C_TO_STRING_PLAIN));

					fclose(infile);
					fclose(outfile);

					sprintf(rmFileCmd,"rm -f %s",filename);
					system(rmFileCmd);

					rename((char*)tmpProfileName, (char*)filename);
				}
				else
				{
					// Profile is not empty
					int ChargingProfileAdded = FALSE;

					while (fgets((char*)dataLine, ARRAY_SIZE(dataLine), infile) != NULL)
					{
						dataLine[strlen((char*)dataLine) - 1] = '\0'; // eat the newline fgets() stores

						json_object *tmpChargingProfile;
						tmpChargingProfile = json_tokener_parse((char*)dataLine);
						if(!is_error(tmpChargingProfile))
						{
							if(json_object_object_get(tmpChargingProfile, "chargingProfile") != NULL)
							{
								if(json_object_object_get(json_object_object_get(tmpChargingProfile, "chargingProfile"), "id") != NULL)
								{
									tempchargingProfileIdInt = json_object_get_int(json_object_object_get(json_object_object_get(tmpChargingProfile, "chargingProfile"), "id"));
									DEBUG_INFO("tempchargingProfileIdInt: %d\n", tempchargingProfileIdInt);
									DEBUG_INFO("SetProfileReq.chargingProfile.id: %d\n", SetProfileReq.chargingProfile.id);
								}

								if(json_object_object_get(json_object_object_get(tmpChargingProfile, "chargingProfile"), "stackLevel") != NULL)
								{
									tempchargingProfileStackLevelInt = json_object_get_int(json_object_object_get(json_object_object_get(tmpChargingProfile, "chargingProfile"), "stackLevel"));
									DEBUG_INFO("tempchargingProfileStackLevelInt: %d\n", tempchargingProfileStackLevelInt);
									DEBUG_INFO("SetProfileReq.chargingProfile.stackLevel: %d\n", SetProfileReq.chargingProfile.stackLevel);
								}
							}
						}
						json_object_put(tmpChargingProfile);

						if((tempchargingProfileIdInt == SetProfileReq.chargingProfile.id) || (tempchargingProfileStackLevelInt == SetProfileReq.chargingProfile.stackLevel))
						{
							if(ChargingProfileAdded == FALSE)
							{
								if((strcmp((char*)SetProfileReq.chargingProfile.chargingProfilePurpose, ChargingProfilePurposeEnumTypeStr[ChargingProfilePurposeEnumType_TxDefaultProfile]) == 0) && (SetProfileReq.evseId==0))
									json_object_object_add(SetChargingProfile, "evseId", json_object_new_int(idxCon));
								fprintf(outfile,"%s\n",json_object_to_json_string_ext(SetChargingProfile, JSON_C_TO_STRING_PLAIN));
								ChargingProfileAdded = TRUE;
							}
						}
						else
						{
							fprintf(outfile,"%s\n",dataLine);
							if(ChargingProfileAdded == FALSE)
							{
								if((strcmp((char*)SetProfileReq.chargingProfile.chargingProfilePurpose, ChargingProfilePurposeEnumTypeStr[ChargingProfilePurposeEnumType_TxDefaultProfile]) == 0) && (SetProfileReq.evseId==0))
									json_object_object_add(SetChargingProfile, "evseId", json_object_new_int(idxCon));
								fprintf(outfile,"%s\n",json_object_to_json_string_ext(SetChargingProfile, JSON_C_TO_STRING_PLAIN));
								ChargingProfileAdded = TRUE;
							}
						}
					} // end of while loop

					fclose(infile);
					fclose(outfile);

					sprintf(rmFileCmd,"rm -f %s",filename);
					system(rmFileCmd);

					rename((char*)tmpProfileName, (char*)filename);
				}
			}

			sleep(1);
			sprintf((char*)ShmOCPP20Data->SetChargingProfile[(SetProfileReq.evseId==0?SetProfileReq.evseId:SetProfileReq.evseId-1)].Response_status, "%s", ChargingProfileStatusEnumTypeStr[ChargingProfileStatusEnumType_Accepted] );
			result = PASS;
		}
		else
		{
			if(isLostConnectorId)
				DEBUG_WARN("Connector id is wrong.\n");

			if(isConnectorMismatch)
				DEBUG_WARN("Connector id is mismatch.\n");

			if(isPeriodOverMax)
				DEBUG_WARN("Profile periods quantity is over spec.\n");

			if(isProfileOverMax)
				DEBUG_WARN("Profile quantity is over spec.\n");

			if(isTransactiodIdMismatch)
				DEBUG_WARN("Transaction id is mismatch.\n");

			if(isInvalidLimit)
				DEBUG_WARN("Limit value is invalid.\n");

			if(isStackOverMax)
				DEBUG_WARN("Profile stack is over spec.\n");

			if(isWrongFormat)
				DEBUG_WARN("Profile format is wrong.\n");

			sprintf((char*)ShmOCPP20Data->SetChargingProfile[(SetProfileReq.evseId==0?SetProfileReq.evseId:SetProfileReq.evseId-1)].Response_status, "%s", ChargingProfileStatusEnumTypeStr[ChargingProfileStatusEnumType_Rejected] );
		}
	}
	json_object_put(SetChargingProfile);

	if(strcmp((char*)ShmOCPP20Data->SetChargingProfile[(SetProfileReq.evseId==0?SetProfileReq.evseId:SetProfileReq.evseId-1)].Response_status, ChargingProfileStatusEnumTypeStr[ChargingProfileStatusEnumType_Accepted]) == 0)
	{
		if(SetProfileReq.evseId == 0)
		{
			for(uint8_t idx=0;idx<gunTotalNumber;idx++)
			{
				//ShmOCPP20Data->CSUMsg.bits[idx].ChargingProfileReq = ON;
				checkChargingStationMaxProfile(86400, &ShmOCPP20Data->MaxChargingProfile, 0, TRUE);
				checkCompositeSchedule((idx+1), 86400, &ShmOCPP20Data->SmartChargingProfile[idx], 0, TRUE);
			}
		}
		else
		{
			//ShmOCPP20Data->CSUMsg.bits[SetProfileReq.evseId-1].ChargingProfileReq = ON;
			checkChargingStationMaxProfile(86400, &ShmOCPP20Data->MaxChargingProfile, 0, TRUE);
			checkCompositeSchedule(SetProfileReq.evseId, 86400, &ShmOCPP20Data->SmartChargingProfile[SetProfileReq.evseId-1], 0, TRUE);
		}
	}

	sendSetChargingProfileConfirmation(uuid, (SetProfileReq.evseId==0?SetProfileReq.evseId:SetProfileReq.evseId-1));
	system("/bin/fsync -d /dev/mtdblock13;/bin/sync &");
	return result;
}

int handleSetDisplayMessageRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	json_object *SetDisplayMessage;

	DEBUG_INFO("handleSetDisplayMessageRequest...\n");

	SetDisplayMessage = json_tokener_parse(payload);
	if(!is_error(SetDisplayMessage))
	{
		memset(&ShmOCPP20Data->SetDisplayMessage, 0, sizeof(struct SetDisplayMessage_20));
		memcpy(&ShmOCPP20Data->SetDisplayMessage.guid, uuid, ARRAY_SIZE(ShmOCPP20Data->SetDisplayMessage.guid));
		// Required data
		if(json_object_object_get(SetDisplayMessage, "message") != NULL)
		{
			if(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "id") != NULL)
				ShmOCPP20Data->SetDisplayMessage.message.id = json_object_get_int(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "id"));

			if(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "priority") != NULL)
				sprintf((char*)ShmOCPP20Data->SetDisplayMessage.message.priority, "%s",json_object_get_string(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "priority")));

			if(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "state") != NULL)
				sprintf((char*)ShmOCPP20Data->SetDisplayMessage.message.state, "%s",json_object_get_string(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "state")));

			if(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "startDateTime") != NULL)
				sprintf((char*)ShmOCPP20Data->SetDisplayMessage.message.startDateTime, "%s",json_object_get_string(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "startDateTime")));

			if(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "endDateTime") != NULL)
				sprintf((char*)ShmOCPP20Data->SetDisplayMessage.message.endDateTime, "%s",json_object_get_string(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "endDateTime")));

			if(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "transactionId") != NULL)
				sprintf((char*)ShmOCPP20Data->SetDisplayMessage.message.transactionId, "%s",json_object_get_string(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "transactionId")));

			if(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "message") != NULL)
			{
				if(json_object_object_get(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "message"), "format") != NULL)
					sprintf((char*)ShmOCPP20Data->SetDisplayMessage.message.message.format, "%s",json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "message"), "format")));

				if(json_object_object_get(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "message"), "language") != NULL)
					sprintf((char*)ShmOCPP20Data->SetDisplayMessage.message.message.language, "%s",json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "message"), "language")));

				if(json_object_object_get(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "message"), "content") != NULL)
					sprintf((char*)ShmOCPP20Data->SetDisplayMessage.message.message.content, "%s",json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "message"), "content")));
			}

			if(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "display") != NULL)
			{
				if(json_object_object_get(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "display"), "name") != NULL)
					sprintf((char*)ShmOCPP20Data->SetDisplayMessage.message.display.name, "%s",json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "display"), "name")));

				if(json_object_object_get(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "display"), "instance") != NULL)
					sprintf((char*)ShmOCPP20Data->SetDisplayMessage.message.display.instance, "%s",json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "display"), "instance")));

				if(json_object_object_get(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "display"), "evse") != NULL)
				{
					if(json_object_object_get(json_object_object_get(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "display"), "evse"), "id") != NULL)
						ShmOCPP20Data->SetDisplayMessage.message.display.evse.id = json_object_get_int(json_object_object_get(json_object_object_get(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "display"), "evse"), "id"));

					if(json_object_object_get(json_object_object_get(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "display"), "evse"), "connectorId") != NULL)
						ShmOCPP20Data->SetDisplayMessage.message.display.evse.connectorId = json_object_get_int(json_object_object_get(json_object_object_get(json_object_object_get(json_object_object_get(SetDisplayMessage, "message"), "display"), "evse"), "connectorId"));
				}
			}
		}
	}
	json_object_put(SetDisplayMessage);
	strcpy((char*)ShmOCPP20Data->SetDisplayMessage.Response_status, DisplayMessageStatusEnumTypeStr[DisplayMessageStatusEnumType_Accepted]);
	sendSetDisplayMessagesConfirmation(uuid);
	// Announce CSU there is display request come from server
	ShmOCPP20Data->MsMsg.bits.SetDisplayMessageReq = ON;

	return result;
}

int handleSetMonitoringBaseRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	json_object *SetMonitoringBase;

	DEBUG_INFO("handleSetMonitoringBaseRequest...\n");
	SetMonitoringBase = json_tokener_parse(payload);
	if(!is_error(SetMonitoringBase))
	{
		memset(&ShmOCPP20Data->SetMonitoringBase, 0, sizeof(struct SetMonitoringBase_20));
		memcpy(&ShmOCPP20Data->SetMonitoringBase.guid, uuid, ARRAY_SIZE(ShmOCPP20Data->SetMonitoringBase.guid));
		// Required data
		if(json_object_object_get(SetMonitoringBase, "monitoringBase") != NULL)
			sprintf((char*)ShmOCPP20Data->SetMonitoringBase.monitoringBase, "%s",json_object_get_string(json_object_object_get(SetMonitoringBase, "monitoringBase")));
	}
	json_object_put(SetMonitoringBase);

	/*
	 * TODO:
	 * 	1. Configure monitor base and response
	 */
	strcpy((char*)ShmOCPP20Data->SetMonitoringBase.Response_status, GenericDeviceModelStatusEnumTypeStr[GenericDeviceModelStatusEnumType_Accepted]);
	sendSetMonitoringBaseConfirmation(uuid);
	return result;
}

int handleSetMonitoringLevelRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	json_object *SetMonitoringLevel;

	DEBUG_INFO("handleSetMonitoringLevelRequest...\n");
	SetMonitoringLevel = json_tokener_parse(payload);
	if(!is_error(SetMonitoringLevel))
	{
		memset(&ShmOCPP20Data->SetMonitoringLevel, 0, sizeof(struct SetMonitoringLevel_20));
		memcpy(&ShmOCPP20Data->SetMonitoringLevel.guid, uuid, ARRAY_SIZE(ShmOCPP20Data->SetMonitoringLevel.guid));
		// Required data
		if(json_object_object_get(SetMonitoringLevel, "severity") != NULL)
			ShmOCPP20Data->SetMonitoringLevel.severity = json_object_get_int(json_object_object_get(SetMonitoringLevel, "severity"));
	}
	json_object_put(SetMonitoringLevel);

	/*
	 * TODO:
	 * 	Configure monitor status and response
	 */
	strcpy((char*)ShmOCPP20Data->SetMonitoringLevel.Response_status, GenericStatusEnumTypeStr[GenericStatusEnumType_Accepted]);
	sendSetMonitoringLevelConfirmation(uuid);

	return result;
}

int handleSetNetworkProfileRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	json_object *SetNetworkProfile;

	DEBUG_INFO("handleSetNetworkProfileRequest...\n");
	SetNetworkProfile = json_tokener_parse(payload);
	if(!is_error(SetNetworkProfile))
	{
		memset(&ShmOCPP20Data->SetNetworkProfile, 0, sizeof(struct SetNetworkProfile_20));
		memcpy(&ShmOCPP20Data->SetNetworkProfile.guid, uuid, ARRAY_SIZE(ShmOCPP20Data->SetNetworkProfile.guid));
		// Required data
		if(json_object_object_get(SetNetworkProfile, "configurationSlot") != NULL)
			ShmOCPP20Data->SetNetworkProfile.configurationSlot = json_object_get_int(json_object_object_get(SetNetworkProfile, "configurationSlot"));

		if(json_object_object_get(SetNetworkProfile, "connectionData") != NULL)
		{
			if(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "ocppVersion") != NULL)
				sprintf((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.ocppVersion, "%s", json_object_get_string(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "ocppVersion")));

			if(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "ocppTransport") != NULL)
				sprintf((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.ocppTransport, "%s", json_object_get_string(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "ocppTransport")));

			if(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "ocppCsmsUrl") != NULL)
			{
				sprintf((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.ocppCsmsUrl, "%s", json_object_get_string(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "ocppCsmsUrl")));

				memcpy((char*)ShmOCPP20Data->OcppServerURL, (char*)ShmOCPP20Data->SetNetworkProfile.connectionData.ocppCsmsUrl, ARRAY_SIZE(ShmOCPP20Data->SetNetworkProfile.connectionData.ocppCsmsUrl));
			}

			if(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "messageTimeout") != NULL)
				ShmOCPP20Data->SetNetworkProfile.connectionData.messageTimeout = json_object_get_int(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "messageTimeout"));

			if(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "ocppInterface") != NULL)
				sprintf((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.ocppInterface, "%s", json_object_get_string(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "ocppInterface")));

			if(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "vpn") != NULL)
			{
				if(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "vpn"), "server") != NULL)
					sprintf((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.vpn.server, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "vpn"), "server")));

				if(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "vpn"), "user") != NULL)
					sprintf((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.vpn.user, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "vpn"), "user")));

				if(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "vpn"), "group") != NULL)
					sprintf((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.vpn.group, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "vpn"), "group")));

				if(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "vpn"), "password") != NULL)
					sprintf((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.vpn.password, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "vpn"), "password")));

				if(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "vpn"), "key") != NULL)
					sprintf((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.vpn.key, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "vpn"), "key")));

				if(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "vpn"), "type") != NULL)
					sprintf((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.vpn.type, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "vpn"), "type")));
			}

			if(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "apn") != NULL)
			{
				if(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "apn"), "apn") != NULL)
				{
					memset(ShmOCPP20Data->SetNetworkProfile.connectionData.apn.apn, 0x00, ARRAY_SIZE(ShmOCPP20Data->SetNetworkProfile.connectionData.apn.apn));
					sprintf((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.apn.apn, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "apn"), "apn")));
					strcpy((char*)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomApn, (char*)ShmOCPP20Data->SetNetworkProfile.connectionData.apn.apn);
				}

				if(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "apn"), "apnUserName") != NULL)
				{
					memset(ShmOCPP20Data->SetNetworkProfile.connectionData.apn.apnUserName, 0x00, ARRAY_SIZE(ShmOCPP20Data->SetNetworkProfile.connectionData.apn.apnUserName));
					sprintf((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.apn.apnUserName, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "apn"), "apnUserName")));
					strcpy((char*)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapId, (char*)ShmOCPP20Data->SetNetworkProfile.connectionData.apn.apnUserName);
				}

				if(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "apn"), "apnPassword") != NULL)
				{
					memset(ShmOCPP20Data->SetNetworkProfile.connectionData.apn.apnPassword, 0x00, ARRAY_SIZE(ShmOCPP20Data->SetNetworkProfile.connectionData.apn.apnPassword));
					sprintf((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.apn.apnPassword, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "apn"), "apnPassword")));
					strcpy((char*)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapPwd, (char*)ShmOCPP20Data->SetNetworkProfile.connectionData.apn.apnPassword);
				}

				if(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "apn"), "simPin") != NULL)
					ShmOCPP20Data->SetNetworkProfile.connectionData.apn.simPin = json_object_get_int(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "apn"), "simPin"));

				if(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "apn"), "preferredNetwork") != NULL)
					sprintf((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.apn.preferredNetwork, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "apn"), "preferredNetwork")));

				if(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "apn"), "useOnlyPreferredNetwork") != NULL)
					ShmOCPP20Data->SetNetworkProfile.connectionData.apn.useOnlyPreferredNetwork = json_object_get_boolean(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "apn"), "useOnlyPreferredNetwork"));

				if(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "apn"), "apnAuthentication") != NULL)
					sprintf((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.apn.apnAuthentication, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(SetNetworkProfile, "connectionData"), "apn"), "apnAuthentication")));
			}

			DB_addNetworkProfile(ShmOCPP20Data->SetNetworkProfile.configurationSlot, (char*)json_object_get_string(json_object_object_get(SetNetworkProfile, "connectionData")));
		}
	}
	json_object_put(SetNetworkProfile);

	/*
	 * TODO:
	 * 	1. Process network configuration and response
	 */
	if(strcmp((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.ocppVersion, OCPPVersionEnumTypeStr[OCPPVersionEnumType_OCPP12]) == 0)
	{

	}
	else if(strcmp((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.ocppVersion, OCPPVersionEnumTypeStr[OCPPVersionEnumType_OCPP15]) == 0)
	{

	}
	else if(strcmp((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.ocppVersion, OCPPVersionEnumTypeStr[OCPPVersionEnumType_OCPP16]) == 0)
	{

	}
	else if(strcmp((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.ocppVersion, OCPPVersionEnumTypeStr[OCPPVersionEnumType_OCPP20]) == 0)
	{

	}
	else
	{

	}

	if(strcmp((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.ocppTransport, OCPPTransportEnumTypeStr[OCPPTransportEnumType_JSON]) == 0)
	{

	}
	else if(strcmp((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.ocppTransport, OCPPTransportEnumTypeStr[OCPPTransportEnumType_SOAP]) == 0)
	{

	}
	else
	{

	}

	if(strcmp((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.vpn.type, OCPPInterfaceEnumTypeStr[OCPPInterfaceEnumType_Wired0]) == 0)
	{

	}
	else if(strcmp((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.vpn.type, OCPPInterfaceEnumTypeStr[OCPPInterfaceEnumType_Wired1]) == 0)
	{

	}
	else if(strcmp((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.vpn.type, OCPPInterfaceEnumTypeStr[OCPPInterfaceEnumType_Wired2]) == 0)
	{

	}
	else if(strcmp((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.vpn.type, OCPPInterfaceEnumTypeStr[OCPPInterfaceEnumType_Wired3]) == 0)
	{

	}
	else if(strcmp((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.vpn.type, OCPPInterfaceEnumTypeStr[OCPPInterfaceEnumType_Wireless0]) == 0)
	{

	}
	else if(strcmp((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.vpn.type, OCPPInterfaceEnumTypeStr[OCPPInterfaceEnumType_Wireless1]) == 0)
	{

	}
	else if(strcmp((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.vpn.type, OCPPInterfaceEnumTypeStr[OCPPInterfaceEnumType_Wireless2]) == 0)
	{

	}
	else if(strcmp((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.vpn.type, OCPPInterfaceEnumTypeStr[OCPPInterfaceEnumType_Wireless3]) == 0)
	{

	}
	else
	{

	}


	if(strcmp((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.vpn.type, VPNEnumTypeStr[VPNEnumType_IKEv2]) == 0)
	{

	}
	else if(strcmp((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.vpn.type, VPNEnumTypeStr[VPNEnumType_IPSec]) == 0)
	{

	}
	else if(strcmp((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.vpn.type, VPNEnumTypeStr[VPNEnumType_L2TP]) == 0)
	{

	}
	else if(strcmp((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.vpn.type, VPNEnumTypeStr[VPNEnumType_PPTP]) == 0)
	{

	}
	else
	{

	}

	if(strcmp((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.apn.apnAuthentication, APNAuthenticationEnumTypeStr[APNAuthenticationEnumType_CHAP]) == 0)
	{

	}
	else if(strcmp((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.apn.apnAuthentication, APNAuthenticationEnumTypeStr[APNAuthenticationEnumType_NONE]) == 0)
	{

	}
	else if(strcmp((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.apn.apnAuthentication, APNAuthenticationEnumTypeStr[APNAuthenticationEnumType_PAP]) == 0)
	{

	}
	else if(strcmp((char*)ShmOCPP20Data->SetNetworkProfile.connectionData.apn.apnAuthentication, APNAuthenticationEnumTypeStr[APNAuthenticationEnumType_AUTO]) == 0)
	{

	}
	else
	{

	}





	strcpy((char*)ShmOCPP20Data->SetNetworkProfile.Response_status, SetNetworkProfileStatusEnumTypeStr[SetNetworkProfileStatusEnumType_Accepted]);
	sendSetNetworkProfileConfirmation(uuid);

	return result;
}

int handleSetVariableMonitoringRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	json_object *SetVariableMonitoring;
	uint8_t variableQuantity = 0;

	DEBUG_INFO("handleSetVariableMonitoringRequest...\n");
	SetVariableMonitoring = json_tokener_parse(payload);
	if(!is_error(SetVariableMonitoring))
	{
		memset(&ShmOCPP20Data->SetVariableMonitoring, 0, sizeof(struct SetVariableMonitoring_20));
		memcpy(&ShmOCPP20Data->SetVariableMonitoring.guid, uuid, ARRAY_SIZE(ShmOCPP20Data->SetVariableMonitoring.guid));
		// Required data
		for(int idx=0;idx<json_object_array_length(json_object_object_get(SetVariableMonitoring, "setMonitoringData"));idx++)
		{
			variableQuantity++;
			if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "id") != NULL)
			{
				ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].id = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "id"));
				ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].id = ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].id;
			}

			if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "value") != NULL)
			{
				ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].value = json_object_get_double(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "value"));
			}

			if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "type") != NULL)
			{
				sprintf((char*)ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].type, "%s", json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "type")));
				strcpy((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].type, (char*)ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].type);
			}
			else
			{
				sprintf((char*)ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].type, "Actual");
				strcpy((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].type, (char*)ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].type);
			}

			if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "severity") != NULL)
			{
				ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].severity = json_object_get_int(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "severity"));
				ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].severity = ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].severity;
			}

			if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "transaction") != NULL)
			{
				ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].transaction = json_object_get_boolean(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "transaction"));
			}

			if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "component") != NULL)
			{
				if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "component"), "name") != NULL)
				{
					sprintf((char*)ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].component.name, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "component"), "name")));
				}

				if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "component"), "instance") != NULL)
				{
					sprintf((char*)ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].component.instance, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "component"), "instance")));
				}

				if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "component"), "evse") != NULL)
				{
					if(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "component"), "evse"), "id") != NULL)
					{
						ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].component.evse.id = json_object_get_int(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "component"), "instance"), "id"));
					}

					if(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "component"), "evse"), "connectorId") != NULL)
					{
						ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].component.evse.connectorId = json_object_get_int(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "component"), "instance"), "connectorId"));
					}
				}

				memcpy(&ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].component, &ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].component, sizeof(struct ComponentType));
			}

			if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "variable") != NULL)
			{
				if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "variable"), "name") != NULL)
				{
					sprintf((char*)ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].variable.name, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "variable"), "name")));
				}

				if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "variable"), "instance") != NULL)
				{
					sprintf((char*)ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].variable.instance, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "setMonitoringData"), idx), "variable"), "instance")));
				}

				memcpy(&ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].variable , &ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].variable, sizeof(struct VariableType));
			}

			/*
			 * TODO
			 * Set Variables and save to DB
			 */
			strcpy((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].status, SetMonitoringStatusEnumTypeStr[SetMonitoringStatusEnumType_Accepted]);
		}
	}
	json_object_put(SetVariableMonitoring);

	sendSetVariableMonitoringConfirmation(uuid, variableQuantity);

	return result;
}

int handleSetVariablesRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	int isUnknownComponent = TRUE;
	json_object *SetVariables;

	DEBUG_INFO("handleSetVariablesRequest...\n");
	SetVariables = json_tokener_parse(payload);
	if(!is_error(SetVariables))
	{
		memset(&ShmOCPP20Data->SetVariables, 0, sizeof(struct SetVariables_20));
		memcpy(&ShmOCPP20Data->SetVariables.guid, uuid, ARRAY_SIZE(ShmOCPP20Data->SetVariables.guid));
		// Required data
		for(int idx=0;idx<json_object_array_length(json_object_object_get(SetVariables, "setVariableData"));idx++)
		{
			if(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx) != NULL)
			{
				if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx), "component") != NULL)
				{
					if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx), "component"), "name") != NULL)
					{
						sprintf((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.name, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx), "component"), "name")));
					}

					if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx), "component"), "instance") != NULL)
					{
						sprintf((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.instance, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx), "component"), "instance")));
					}

					if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx), "component"), "evse") != NULL)
					{
						if(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx), "component"), "evse"), "id") != NULL)
						{
							ShmOCPP20Data->SetVariables.setVariableData[idx].component.evse.id = json_object_get_int(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx), "component"), "evse"), "id"));
						}

						if(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx), "component"), "evse"), "connectorId") != NULL)
						{
							ShmOCPP20Data->SetVariables.setVariableData[idx].component.evse.connectorId = json_object_get_int(json_object_object_get(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx), "component"), "evse"), "connectorId"));

						}
					}

					memcpy(&ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].component, &ShmOCPP20Data->SetVariables.setVariableData[idx].component, sizeof(struct ComponentType));
				}

				if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx), "variable") != NULL)
				{
					if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx), "variable"), "name") != NULL)
					{
						sprintf((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.name, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx), "variable"), "name")));
					}

					if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx), "variable"), "instance") != NULL)
					{
						sprintf((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.instance, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx), "variable"), "instance")));
					}

					memcpy(&ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].variable , &ShmOCPP20Data->SetVariables.setVariableData[idx].variable, sizeof(struct VariableType));
				}

				if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx), "attributeType") != NULL)
				{
					sprintf((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeType, "%s", json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx), "attributeType")));
					strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeType, (char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeType);
				}

				if(strlen((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeType) == 0)
				{
					strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeType, "Actual");
				}

				if(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx), "attributeValue") != NULL)
				{
					sprintf((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue, "%s", json_object_get_string(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx), "attributeValue")));

					strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_UnknownComponent]);
					for(uint8_t idx_var=0;idx_var<CtrlrVariable_CNT;idx_var++)
					{
						if((strstr((char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].component.name, (char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.name) != NULL) &&
						   (strlen((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.instance)>0?(strstr((char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].component.instance, (char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.instance) != NULL):TRUE) &&
						   (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variable.name, (char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.name) != NULL) &&
						   (strlen((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.instance)>0?(strstr((char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variable.instance, (char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.instance) != NULL):TRUE))
						{
							isUnknownComponent = FALSE;

							if((strstr((char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableAttribute[0].type, (char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeType) == NULL) &&
							   (json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariables, "setVariableData"), idx), "attributeType") != NULL))
							{
								strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_NotSupportedAttributeType]);
								break;
							}

							if(strstr((char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableAttribute[0].mutability, MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]) != NULL)
							{
								strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_Rejected]);
								break;
							}

							if(((strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.name, "OCPPCommCtrlr") != NULL)) && (strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.name, "NetworkConfigurationPriority") != NULL))
							{
								strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_RebootRequired]);
							}
							else
								strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_Accepted]);

							if((strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.name, "OCPPCommCtrlr") != NULL) && (strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.name, "WebSocketPingInterval") != NULL))
							{
								if((0 < atoi((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue)) && (atoi((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue) < 10) )
									strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_OutOfRange]);
								else
									strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_Accepted]);
							}

							if((strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.name, "OCPPCommCtrlr") != NULL) && (strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.name, "HeartbeatInterval") != NULL))
							{
								if((atoi((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue) < (int)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableCharacteristics.minLimit) )
								{
									strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_OutOfRange]);
								}
								else
									HeartBeatWaitTime = atoi((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue);

							}

							if((strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.name, "OCPPCommCtrlr") != NULL) && (strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.name, "StatusNotificationPeriodically") != NULL))
							{
								char tmp[ARRAY_SIZE(ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue)];

								for(int tmpidx=0;tmpidx<ARRAY_SIZE(tmp);tmpidx++)
									tmp[idx] = tolower(ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue[tmpidx]);
								if((strstr((char*)tmp, "true") != NULL) || (strstr((char*)tmp, "false") != NULL))
								{
									strcpy((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue,(strstr((char*)tmp, "true") != NULL)? "TRUE" : "FALSE");
									strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_Accepted]);
								}
							}

							if((strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.name, "OCPPCommCtrlr") != NULL) && (strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.name, "StatusNotificationInterval") != NULL))
							{
								if((atoi((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue) < (int)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableCharacteristics.minLimit) )
								{
									strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_OutOfRange]);
								}
								else
									strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_Accepted]);
							}

							if((strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.name, "SecurityCtrlr") != NULL) &&
							   ((strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.name, "SecurityProfile") != NULL) || (strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.name, "BasicAuthPassword") != NULL)))
							{
								StoreUsrConfigData(&ShmSysConfigAndInfo->SysConfig);
								SetOcppConnStatus(FALSE);
							}

							if((strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.name, "AlignedDataCtrlr") != NULL) && (strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.name, "Interval") != NULL))
							{
								if((0 < atoi((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue)) && (atoi((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue) < (int)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableCharacteristics.minLimit) )
								{
									strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_OutOfRange]);
								}
								else
									strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_Accepted]);
							}

							if((strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.name, "SampledDataCtrlr") != NULL) && (strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.name, "TxUpdatedInterval") != NULL))
							{
								if((0 < atoi((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue)) && (atoi((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue) < (int)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableCharacteristics.minLimit) )
								{
									strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_OutOfRange]);
								}
								else
									strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_Accepted]);
							}

							if((strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.name, "ChargingStation") != NULL) && (strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.name, "FreeVend") != NULL))
							{
								char tmp[ARRAY_SIZE(ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue)];

								for(int tmpidx=0;tmpidx<ARRAY_SIZE(tmp);tmpidx++)
									tmp[idx] = tolower(ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue[tmpidx]);

								if((strstr((char*)tmp, "true") != NULL) || (strstr((char*)tmp, "false") != NULL))
								{
									strcpy((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue,(strstr((char*)tmp, "true") != NULL)? "TRUE" : "FALSE");
									ShmSysConfigAndInfo->SysConfig.AuthorisationMode =((strstr((char*)tmp, "true") != NULL)? 1 : 0);
									StoreUsrConfigData(&ShmSysConfigAndInfo->SysConfig);
									strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_Accepted]);
								}
							}

							if((strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.name, "ChargingStation") != NULL) && (strstr((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].variable.name, "FreeVendIdtag") != NULL))
							{
								if(strlen((char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue) > 20)
								{
									strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_OutOfRange]);
								}
								else
									strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_Accepted]);
							}

							if((strstr((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_Accepted]) != NULL) ||
							   (strstr((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_RebootRequired]) != NULL))
							{
								strcpy((char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableAttribute[0].value, (char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue);
								DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[idx_var]);
							}

							break;
						}
						else
						{
							if(strstr((char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].component.name, (char*)ShmOCPP20Data->SetVariables.setVariableData[idx].component.name) != NULL)
							{
								isUnknownComponent = FALSE;
							}

							strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_UnknownVariable]);
						}
					}

					if(isUnknownComponent == TRUE)
					{
						strcpy((char*)ShmOCPP20Data->SetVariables.Response_setVariableResult[idx].attributeStatus, SetVariableStatusEnumTypeStr[SetVariableStatusEnumType_UnknownComponent]);
					}
				}
			}
		}

		sendSetVariableConfirmation(uuid, json_object_array_length(json_object_object_get(SetVariables, "setVariableData")));
	}
	json_object_put(SetVariables);

	return result;
}

int handleTriggerMessageRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	int connectorIdIsNULL = FALSE;
	int connectorIdInt =0;
	json_object *TriggerMessage;

	DEBUG_INFO("handleTriggerMessageRequest\n");
	TriggerMessage = json_tokener_parse(payload);

	if(!is_error(TriggerMessage))
	{
		memset(&ShmOCPP20Data->TriggerMessage, 0, sizeof(struct TriggerMessage_20));
		memcpy(&ShmOCPP20Data->TriggerMessage.guid, uuid, ARRAY_SIZE(ShmOCPP20Data->TriggerMessage.guid));
		// Required data
		if(json_object_object_get(TriggerMessage, "requestedMessage") != NULL)
			sprintf((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, "%s", json_object_get_string(json_object_object_get(TriggerMessage, "requestedMessage")));

		// Optional data
		if(json_object_object_get(TriggerMessage, "evse") != NULL)
		{
			// Required data
			if(json_object_object_get(json_object_object_get(TriggerMessage, "evse"), "id") != NULL)
				ShmOCPP20Data->TriggerMessage.evse.id = json_object_get_int(json_object_object_get(json_object_object_get(TriggerMessage, "evse"), "id"));

			// Optional data
			if(json_object_object_get(json_object_object_get(TriggerMessage, "evse"), "connectorId") != NULL)
			{
				ShmOCPP20Data->TriggerMessage.evse.connectorId = json_object_get_int(json_object_object_get(json_object_object_get(TriggerMessage, "evse"), "connectorId"));
				connectorIdInt = ShmOCPP20Data->TriggerMessage.evse.connectorId;
			}
			else
				connectorIdIsNULL = TRUE;
		}
		else
			connectorIdIsNULL = TRUE;
	}
	json_object_put(TriggerMessage);

	if((connectorIdIsNULL == TRUE) || ((connectorIdIsNULL == FALSE) && ((connectorIdInt > 0)  && (connectorIdInt <= gunTotalNumber /*(CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY)*/ ))) )
	{
		if((strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_BootNotification]) != 0) &&
			(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_LogStatusNotification]) != 0) &&
			(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_FirmwareStatusNotification]) != 0 ) &&
			(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_Heartbeat]) != 0) &&
			(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_MeterValues]) != 0) &&
			(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_SignChargingStationCertificate]) != 0 ) &&
			(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_SignV2GCertificate]) != 0 ) &&
			(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_StatusNotification]) != 0 ) &&
			(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_TransactionEvent]) != 0 ) &&
			(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_SignCombinedCertificate]) != 0 ) &&
			(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_PublishFirmwareStatusNotification]) != 0 ))
		{
			sprintf((char*)ShmOCPP20Data->TriggerMessage.Response_status, "%s",TriggerMessageStatusEnumTypeStr[TriggerMessageStatusEnumType_NotImplemented] );
			sendTriggerMessageConfirmation(uuid);
			return TRUE;
		}
		else
		{
			sprintf((char*)ShmOCPP20Data->TriggerMessage.Response_status, "%s",TriggerMessageStatusEnumTypeStr[TriggerMessageStatusEnumType_Accepted] );
			sendTriggerMessageConfirmation(uuid);
		}
	}
	else if(connectorIdIsNULL == FALSE && ((connectorIdInt <= 0)  || (connectorIdInt > gunTotalNumber /*(CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY)*/)  ))
	{
		sprintf((char*)ShmOCPP20Data->TriggerMessage.Response_status, "%s",TriggerMessageStatusEnumTypeStr[TriggerMessageStatusEnumType_Rejected] );
		sendTriggerMessageConfirmation(uuid);
		return TRUE;
	}

	//==========================
	// Trigger message
	//==========================
	if( strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_FirmwareStatusNotification]) == 0)
	{
		if((strlen((char*)ShmOCPP20Data->FirmwareStatusNotification.status) == 0) ||
		   ((FirmwareStatusNotificationStatus != FirmwareStatusEnumType_Downloading) && (FirmwareStatusNotificationStatus != FirmwareStatusEnumType_Downloaded) && (FirmwareStatusNotificationStatus != FirmwareStatusEnumType_Idle) && (FirmwareStatusNotificationStatus != FirmwareStatusEnumType_Installing)))
		{
			FirmwareStatusNotificationStatus = FirmwareStatusEnumType_Idle;
			sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s", FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Idle]);
		}

		ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
	}
	else if(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_LogStatusNotification]) == 0 )
	{
		if(strlen((char*)ShmOCPP20Data->LogStatusNotification.status) == 0)
			sprintf((char*)ShmOCPP20Data->LogStatusNotification.status, "%s", UploadLogStatusEnumTypeStr[UploadLogStatusEnumType_Idle]);
		ShmOCPP20Data->SpMsg.bits.LogStatusNotificationReq = ON;
	}
	else if(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_BootNotification]) == 0 )
	{
		if(DB_updateBootType(BootReasonEnumType_Triggered))
			server_sign = FALSE;
	}
	else if(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_Heartbeat]) == 0 )
	{
		refreshStartTimer(&clientTime.Heartbeat);
		clientTime.Heartbeat.tv_sec -= ShmOCPP20Data->BootNotification.Response_interval;
	}
	else if (strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_MeterValues]) == 0 )
	{
		if(connectorIdIsNULL == FALSE)
		{
			if((connectorIdInt > 0) && ((connectorIdInt-1) < gunTotalNumber))
			{
				cpinitateMsg.bits[connectorIdInt-1].TriggerMeterValueReq = ON;
			}
		}
		else
		{
			for(int idx=0;idx< gunTotalNumber;idx++)
			{
				cpinitateMsg.bits[idx].TriggerMeterValueReq = ON;
			}
		}
	}
	else if(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_StatusNotification]) == 0 )
	{
		if(connectorIdIsNULL == FALSE)
		{
			if((connectorIdInt > 0) && ((connectorIdInt-1) < gunTotalNumber))
			{
				cpinitateMsg.bits[connectorIdInt-1].TriggerStatusNotificationReq = ON;
				//clientTime.StatusNotification[connectorIdInt-1] = time((time_t*)NULL);
			}
		}
		else
		{
			for(int idx=0;idx< gunTotalNumber;idx++)
			{
				cpinitateMsg.bits[idx].TriggerStatusNotificationReq = ON;
				//clientTime.StatusNotification[idx] = time((time_t*)NULL);
			}
		}
	}
	else if(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_SignChargingStationCertificate]) == 0 )
	{
		ShmOCPP20Data->SpMsg.bits.SignCertificateReq = ON;

		if(access("/Storage/OCPP/certCP.csr",F_OK) == -1)
		{
			system("openssl req -newkey rsa:2048 -out /Storage/OCPP/certCP.csr -nodes -keyout /Storage/OCPP/certCP.key -subj \"/C=TW/ST=Taiwan/L=Taoyuan/O=Phihong Technology/OU=IT/CN=phihong.com\" &");
		}
	}
	else if(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_SignV2GCertificate]) == 0 )
	{
		ShmOCPP20Data->SpMsg.bits.SignCertificateReq = ON;

		if(access("/Storage/OCPP/certV2G.csr",F_OK) == -1)
		{
			system("openssl req -newkey rsa:2048 -out /Storage/OCPP/certV2G.csr -nodes -keyout /Storage/OCPP/certV2G.key -subj \"/C=TW/ST=Taiwan/L=Taoyuan/O=Phihong Technology/OU=IT/CN=phihong.com\" &");
		}
	}
	else if(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_TransactionEvent]) == 0 )
	{
		if(connectorIdIsNULL == FALSE)
		{
			if((connectorIdInt > 0) && ((connectorIdInt -1) < gunTotalNumber))
			{
				ShmOCPP20Data->CpMsg.bits[connectorIdInt -1].TransactionEventReq = ON;
			}
		}
		else
		{
			for(int idx=0;idx< gunTotalNumber;idx++)
				ShmOCPP20Data->CpMsg.bits[idx].TransactionEventReq = ON;
		}
	}
	else if(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_SignCombinedCertificate]) == 0 )
	{
		ShmOCPP20Data->SpMsg.bits.SignCertificateReq = ON;

		if(access("/Storage/OCPP/certCP.csr",F_OK) == -1)
		{
			system("openssl req -newkey rsa:2048 -out /Storage/OCPP/certCP.csr -nodes -keyout /Storage/OCPP/certCP.key -subj \"/C=TW/ST=Taiwan/L=Taoyuan/O=Phihong Technology/OU=IT/CN=phihong.com\" &");
		}

		if(access("/Storage/OCPP/certV2G.csr",F_OK) == -1)
		{
			system("openssl req -newkey rsa:2048 -out /Storage/OCPP/certV2G.csr -nodes -keyout /Storage/OCPP/certV2G.key -subj \"/C=TW/ST=Taiwan/L=Taoyuan/O=Phihong Technology/OU=IT/CN=phihong.com\" &");
		}
	}
	else if(strcmp((char*)ShmOCPP20Data->TriggerMessage.requestedMessage, MessageTriggerEnumTypeStr[MessageTriggerEnumType_PublishFirmwareStatusNotification]) == 0 )
	{
		ShmOCPP20Data->MsMsg.bits.PublishFirmwareReq = ON;
	}

	return result;
}

int handleUnlockConnectorRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	int connectorIdInt =0;
	int tempIndex = 0;
	json_object *UnlockConnector;

	DEBUG_INFO("handleUnlockConnectorRequest ...\n");
	UnlockConnector = json_tokener_parse(payload);
	if(!is_error(UnlockConnector))
	{
		if(json_object_object_get(UnlockConnector, "connectorId") != NULL)
		{
			connectorIdInt = json_object_get_int(json_object_object_get(UnlockConnector, "connectorId"));
		}

		if(json_object_object_get(UnlockConnector, "evseId") != NULL)
		{
			ShmOCPP20Data->UnlockConnector[(connectorIdInt>0?connectorIdInt-1:0)].evseId = json_object_get_int(json_object_object_get(UnlockConnector, "evseId"));
		}
	}
	json_object_put(UnlockConnector);

	DEBUG_INFO("Unlock connectorIdInt = %d\n",connectorIdInt);

	if(gunTotalNumber == 0)
	{
		sprintf((char*)ShmOCPP20Data->UnlockConnector[connectorIdInt-1].Response_status, "%s", UnlockStatusEnumTypeStr[UnlockStatusEnumType_UnknownConnector] );
		goto end;
	}
	else if((connectorIdInt > gunTotalNumber/*CHAdeMO_QUANTITY+ CCS_QUANTITY + GB_QUANTITY*/) || (connectorIdInt <= 0))
	{
		sprintf((char*)ShmOCPP20Data->UnlockConnector[connectorIdInt-1].Response_status, "%s", UnlockStatusEnumTypeStr[UnlockStatusEnumType_UnknownConnector] );
		goto end;
	}
	else
	{
		memset(&ShmOCPP20Data->UnlockConnector[connectorIdInt-1], 0, sizeof(struct UnlockConnector_20));
		memcpy(&ShmOCPP20Data->UnlockConnector[connectorIdInt-1].guid, uuid, ARRAY_SIZE(ShmOCPP20Data->UnlockConnector[connectorIdInt-1].guid));
		//check Transaction active
		if(gunType[connectorIdInt-1] == GUN_TYPE_CHAdeMO)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = (((connectorIdInt -1)==2) ? 1: 0);
			}
			else
			{
				tempIndex = connectorIdInt -1;
			}

			for (int index = 0; index < CHAdeMO_QUANTITY; index++)
			{
				if ((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex ))
				{
					//stop Transaction
					ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].UnlockConnectorReq = ON;
				}
			}
		}
		else if(gunType[connectorIdInt-1] == GUN_TYPE_CCS)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = (((connectorIdInt -1)==2) ? 1: 0);
			}
			else
			{
				tempIndex = connectorIdInt -1;
			}

			for (int index = 0; index < CCS_QUANTITY; index++)
			{
				if ((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex ))
				{
					//stop Transaction
					ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].UnlockConnectorReq = ON;
				}
			}
		}
		else if(gunType[connectorIdInt-1] == GUN_TYPE_GBT)
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
			{
				tempIndex = (((connectorIdInt -1)==2) ? 1: 0);
			}
			else
			{
				tempIndex = connectorIdInt -1;
			}

			for (int index = 0; index < GB_QUANTITY; index++)
			{
				if ((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex ))
				{
					//stop Transaction
					ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].UnlockConnectorReq = ON;
				}
			}
		}
		else if(gunType[connectorIdInt-1] == GUN_TYPE_DO)
		{
			tempIndex = connectorIdInt -1;

			for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
			{
				if ((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex ))
				{
					//stop Transaction
					ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].UnlockConnectorReq = ON;
				}
			}
		}
		else
		{
			if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
			{
				tempIndex = 2;
			}
			else
			{
				tempIndex = connectorIdInt-1;
			}

			for (int index = 0; index < AC_QUANTITY; index++)
			{
				if ((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex ))
				{
					ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].UnlockConnectorReq = ON;
				}
			}
		}
		ShmOCPP20Data->UnlockConnector[connectorIdInt-1].connectorId = connectorIdInt;
		strcpy((char *)ShmOCPP20Data->UnlockConnector[connectorIdInt-1].guid, uuid);
		result = TRUE;
		return result;
	}

end:
	ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].UnlockConnectorConf = ON;
	return result;
}

int handleUnpublishFirmwareRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	json_object *UnpublishFirmware;

	DEBUG_INFO("handleUnpublishFirmwareRequest...\n");
	UnpublishFirmware = json_tokener_parse(payload);
	if(!is_error(UnpublishFirmware))
	{
		memset(&ShmOCPP20Data->UnpublishFirmware, 0, sizeof(struct UnpublishFirmware_20));
		memcpy(&ShmOCPP20Data->UnpublishFirmware.guid, uuid, ARRAY_SIZE(ShmOCPP20Data->UnpublishFirmware.guid));
		// Required data
		if(json_object_object_get(UnpublishFirmware, "checksum") != NULL)
			sprintf((char*)ShmOCPP20Data->UnpublishFirmware.checksum, json_object_get_string(json_object_object_get(UnpublishFirmware, "checksum")));
	}
	json_object_put(UnpublishFirmware);

	ShmOCPP20Data->MsMsg.bits.UnpublishFirmwareReq = ON;

	/*
	 * TODO:
	 * 	1. Check unpublished status
	 */
	sprintf((char*)ShmOCPP20Data->UnpublishFirmware.Response_status, UnpublishFirmwareStatusEnumTypeStr[Unpublished_NoFirmware]);
	sendUnpublishFirmwareConfirmation(uuid);

	return result;
}

static char UpdateFirmwarepayloadData[512]={0};
void *UpdateFirmwareProcess(void *data)
{
	pthread_detach(pthread_self());
	mtrace();
	char protocol[10], user[64],password[64],host[128], path[512], ftppath[512],host1[128],path1[512];
	int port=0;
	int isSuccess = 0;
	char ftpbuf[1024];
	char temp[1024];
	char * pch;


	DEBUG_INFO("handleUpdateFirmwareRequest...\n");
	json_object *UpdateFirmware;
	UpdateFirmware = json_tokener_parse(UpdateFirmwarepayloadData);
	if(!is_error(UpdateFirmware))
	{
		// Required data
		if(json_object_object_get(UpdateFirmware, "requestId"))
		{
			ShmOCPP20Data->UpdateFirmware.requestId = json_object_get_int(json_object_object_get(UpdateFirmware, "requestId"));
		}

		if(json_object_object_get(UpdateFirmware, "firmware"))
		{
			if(json_object_object_get(json_object_object_get(UpdateFirmware, "firmware"), "location") != NULL)
				sprintf((char*)ShmOCPP20Data->UpdateFirmware.firmware.location, "%s", json_object_get_string(json_object_object_get(json_object_object_get(UpdateFirmware, "firmware"), "location")));

			if(json_object_object_get(json_object_object_get(UpdateFirmware, "firmware"), "retrieveDate") != NULL)
				sprintf((char*)ShmOCPP20Data->UpdateFirmware.firmware.retrieveDateTime, "%s", json_object_get_string(json_object_object_get(json_object_object_get(UpdateFirmware, "firmware"), "retrieveDate")));

			if(json_object_object_get(json_object_object_get(UpdateFirmware, "firmware"), "installDateTime") != NULL)
				sprintf((char*)ShmOCPP20Data->UpdateFirmware.firmware.location, "%s", json_object_get_string(json_object_object_get(json_object_object_get(UpdateFirmware, "firmware"), "installDateTime")));

			if(json_object_object_get(json_object_object_get(UpdateFirmware, "firmware"), "signingCertificate") != NULL)
				sprintf((char*)ShmOCPP20Data->UpdateFirmware.firmware.location, "%s", json_object_get_string(json_object_object_get(json_object_object_get(UpdateFirmware, "firmware"), "signingCertificate")));

			if(json_object_object_get(json_object_object_get(UpdateFirmware, "firmware"), "signature") != NULL)
				sprintf((char*)ShmOCPP20Data->UpdateFirmware.firmware.location, "%s", json_object_get_string(json_object_object_get(json_object_object_get(UpdateFirmware, "firmware"), "signature")));
		}

		// Optional data
		if(json_object_object_get(UpdateFirmware, "retries"))
		{
			ShmOCPP20Data->UpdateFirmware.retries = json_object_get_int(json_object_object_get(UpdateFirmware, "retries"));
		}

		if(json_object_object_get(UpdateFirmware, "retryInterval"))
		{
			ShmOCPP20Data->UpdateFirmware.retryInterval = json_object_get_int(json_object_object_get(UpdateFirmware, "retryInterval"));
		}
	}
	json_object_put(UpdateFirmware);

	memset(ftppath, 0, ARRAY_SIZE(ftppath));
	memset(path, 0, ARRAY_SIZE(path));

	// Wait retrieveData
	if(strlen((char*)ShmOCPP20Data->UpdateFirmware.firmware.retrieveDateTime) > 10)
	{
		ShmOCPP20Data->FirmwareStatusNotification.requestId = ShmOCPP20Data->UpdateFirmware.requestId;
		sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s", FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_DownloadScheduled]);
		ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
		do
		{
			sleep(1);
		}while(!isOvertNow(ShmOCPP20Data->UpdateFirmware.firmware.retrieveDateTime));
	}

	system("rm -f /mnt/*");
	if(strncmp((char*)ShmOCPP20Data->UpdateFirmware.firmware.location,"http", 4) == 0)
	{
		sscanf((char*)ShmOCPP20Data->UpdateFirmware.firmware.location,"%[^:]:%*2[/]%[^/]/%199[^\n]", protocol, host, path);

		sprintf(ftppath,"/%s", path);
		DEBUG_INFO("locationstr: %s\n", ShmOCPP20Data->UpdateFirmware.firmware.location);
		DEBUG_INFO("protocol: %s\n",protocol);
		DEBUG_INFO("host: %s\n",host);
		DEBUG_INFO("path: %s\n",path);
		DEBUG_INFO("ftppath: %s\n",ftppath);

		int ftppathlen=strlen(ftppath);
		int i=1;
		char filenametemp[50];
		while(i < ftppathlen)
		{
		   int len=ftppathlen-i;
		   if(ftppath[len]== 47) // '/' ascll code: 47
		    {
			   DEBUG_INFO("compare '/' all right\n");
		       break;
		    }
		    i=i+1;
		}

		memset(filenametemp, 0, ARRAY_SIZE(filenametemp));
		strncpy(filenametemp, ftppath+(ftppathlen-i+1), i+1);
		filenametemp[i+1] = 0;

		do
		{
			ShmOCPP20Data->FirmwareStatusNotification.requestId = ShmOCPP20Data->UpdateFirmware.requestId;
			sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s", FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Downloading]);
			ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
			sleep(3);

			isSuccess = httpDownLoadFile(host, ftppath, filenametemp, (char*)ShmOCPP20Data->UpdateFirmware.firmware.location);
			if(!isSuccess)
			{
				ShmOCPP20Data->FirmwareStatusNotification.requestId = ShmOCPP20Data->UpdateFirmware.requestId;
				sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s", FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_DownloadFailed]);
				ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
				if(ShmOCPP20Data->UpdateFirmware.retries>0)sleep(ShmOCPP20Data->UpdateFirmware.retryInterval);else sleep(1);
				ShmOCPP20Data->FirmwareStatusNotification.requestId = ShmOCPP20Data->UpdateFirmware.requestId;
				sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s",FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Idle]);
				ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
			}
			else
			{
				ShmOCPP20Data->FirmwareStatusNotification.requestId = ShmOCPP20Data->UpdateFirmware.requestId;
				sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s", FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Downloaded]);
				ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
			}
			ShmOCPP20Data->UpdateFirmware.retries--;
		}while((isSuccess == 0)&&(ShmOCPP20Data->UpdateFirmware.retries >= 0));
	}
    else if(strncmp((char*)ShmOCPP20Data->UpdateFirmware.firmware.location,"ftp", 3) == 0)
	{
    	memset(ftpbuf, 0, ARRAY_SIZE(ftpbuf));
    	memset(temp, 0, ARRAY_SIZE(temp));

    	strcpy(ftpbuf, (char*)ShmOCPP20Data->UpdateFirmware.firmware.location);
    	int ftppathlen=strlen(ftpbuf);
    	int i=1;
    	char filenametemp[50];
    	while(i < ftppathlen)
    	{
    		int len=ftppathlen-i;
    		if(ftpbuf[len]== 47) // '/' ascll code: 47
    		{
    			DEBUG_INFO(" compare '/' all right\n");
    			break;
    		}

    		i=i+1;
    	}

    	memset(filenametemp, 0, ARRAY_SIZE(filenametemp));
    	strncpy(filenametemp, ftpbuf+(ftppathlen-i+1), i+1);
    	filenametemp[i+1] = 0;
    	strncpy(temp, ftpbuf, ftppathlen-i+1);

    	pch=strchr(temp,'@');
    	if(pch==NULL)
    	{
    		sscanf(temp,"%[^:]:%*2[/]%[^:]:%i/%[a-zA-Z0-9._/-]",
    				         protocol, host, &port, path);
    		strcpy(user,"anonymous");
    		strcpy(password,"");
    	}
    	else
    	{
    		sscanf(temp,"%[^:]:%*2[/]%[^:]:%[^@]@%[^:]:%i/%199[^\n]",
    				protocol, user, password, host, &port, path);
    	}

    	sscanf(host,"%[^/]%s",host1, path1);
    	sprintf(ftppath,"%s", path1);

    	if(port == 0)
    	{
    		port = 21;
    	}

		do
		{
			ShmOCPP20Data->FirmwareStatusNotification.requestId = ShmOCPP20Data->UpdateFirmware.requestId;
			sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s", FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Downloading]);
			ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
			sleep(3);

			isSuccess = ftpDownLoadFile(host1, user, password, port, ftppath, filenametemp, (char*)ShmOCPP20Data->UpdateFirmware.firmware.location);
			if(!isSuccess)
			{
				//BulldogUtil.sleepMs(interval*1000);
				DEBUG_INFO("Update firmware request and download file fail.\n");
				ShmOCPP20Data->FirmwareStatusNotification.requestId = ShmOCPP20Data->UpdateFirmware.requestId;
				sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s", FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_DownloadFailed]);
				ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
				if(ShmOCPP20Data->UpdateFirmware.retries>0)sleep(ShmOCPP20Data->UpdateFirmware.retryInterval);else sleep(1);
				ShmOCPP20Data->FirmwareStatusNotification.requestId = ShmOCPP20Data->UpdateFirmware.requestId;
				sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s",FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Idle]);
				ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
			}
			else
			{
				ShmOCPP20Data->FirmwareStatusNotification.requestId = ShmOCPP20Data->UpdateFirmware.requestId;
				sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s", FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Downloaded]);
				ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;

			}
			ShmOCPP20Data->UpdateFirmware.retries--;
		}while((!isSuccess)&&(ShmOCPP20Data->UpdateFirmware.retries >= 0));
	}
    else
    {
    	ShmOCPP20Data->FirmwareStatusNotification.requestId = ShmOCPP20Data->UpdateFirmware.requestId;
		sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s", FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_DownloadFailed]);
		ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
		sleep(1);
		ShmOCPP20Data->FirmwareStatusNotification.requestId = ShmOCPP20Data->UpdateFirmware.requestId;
		sprintf((char*)ShmOCPP20Data->FirmwareStatusNotification.status, "%s",FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Idle]);
		ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
    }

	if(strstr((char*)ShmOCPP20Data->FirmwareStatusNotification.status, FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Downloaded]) != NULL)ShmOCPP20Data->MsMsg.bits.UpdateFirmwareReq = ON;

	interLock.isUpdateFirmwareGoing = OFF;
	pthread_exit(NULL);

}
int handleUpdateFirmwareRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	pthread_t t;

	sendUpdateFirmwareConfirmation(uuid);
	memset(UpdateFirmwarepayloadData, 0, ARRAY_SIZE(UpdateFirmwarepayloadData));
	strcpy(UpdateFirmwarepayloadData, stringtrimspace(payload));
	memset(&ShmOCPP20Data->UpdateFirmware, 0, sizeof(struct UpdateFirmware_20));

	if(!interLock.isUpdateFirmwareGoing)
	{
		interLock.isUpdateFirmwareGoing = ON;
		pthread_create(&t, NULL, UpdateFirmwareProcess, stringtrimspace(payload));
		sleep(1);
	}
	else
		DEBUG_WARN("Other UpdateFirmware request on going.\n");

	ShmOCPP20Data->MsMsg.bits.UpdateFirmwareConf = ON;
	return result;
}

int handleUnknownRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	DEBUG_INFO("handleUnknownRequest...\n");

	sendUnknownConfirmation(uuid);
	result = PASS;

	return result;
}

//==========================================
// Handle server response routine
//==========================================
void handleAuthorizeResponse(char *payload, int gun_index)
{
	mtrace();
	DEBUG_INFO("handleAuthorizeResponse...\n");
	json_object *Authorize;
	Authorize = json_tokener_parse(payload);

	if(!is_error(Authorize))
	{
		if(json_object_object_get(Authorize, "idTokenInfo") != NULL)
		{
			// Required data
			sprintf((char *)(char *)ShmOCPP20Data->Authorize.Response_idTokenInfo.status, "%s", json_object_get_string(json_object_object_get(json_object_object_get(Authorize,"idTokenInfo"), "status")));

			// Optional data
			if(json_object_object_get(json_object_object_get(Authorize,"idTagInfo"), "cacheExpiryDateTime") != NULL)
				sprintf((char *)ShmOCPP20Data->Authorize.Response_idTokenInfo.cacheExpiryDateTime, "%s", json_object_get_string(json_object_object_get(json_object_object_get(Authorize,"idTokenInfo"), "cacheExpiryDateTime")));
			else
				memset(ShmOCPP20Data->Authorize.Response_idTokenInfo.cacheExpiryDateTime, 0x00, ARRAY_SIZE(ShmOCPP20Data->Authorize.Response_idTokenInfo.cacheExpiryDateTime));

			if(json_object_object_get(json_object_object_get(Authorize,"idTagInfo"), "chargingPriority") != NULL)
				ShmOCPP20Data->Authorize.Response_idTokenInfo.chargingPriority = json_object_get_int(json_object_object_get(json_object_object_get(Authorize,"idTokenInfo"), "chargingPriority"));

			if(json_object_object_get(json_object_object_get(Authorize,"idTagInfo"), "language1") != NULL)
				sprintf((char *)ShmOCPP20Data->Authorize.Response_idTokenInfo.language1, "%s", json_object_get_string(json_object_object_get(json_object_object_get(Authorize,"idTokenInfo"), "language1")));

			if(json_object_object_get(json_object_object_get(Authorize,"idTagInfo"), "evseId") != NULL)
			{
				for(int idx=0;idx<json_object_array_length(json_object_object_get(json_object_object_get(Authorize, "idTagInfo"), "evseId"));idx++)
				{
					ShmOCPP20Data->Authorize.Response_idTokenInfo.evseId[idx] = json_object_get_int(json_object_array_get_idx(json_object_object_get(json_object_object_get(Authorize,"idTokenInfo"), "evseId"), idx));
				}
			}

			if(json_object_object_get(json_object_object_get(Authorize,"idTagInfo"), "language2") != NULL)
				sprintf((char *)ShmOCPP20Data->Authorize.Response_idTokenInfo.language2, "%s", json_object_get_string(json_object_object_get(json_object_object_get(Authorize,"idTokenInfo"), "language2")));

			if(json_object_object_get(json_object_object_get(Authorize,"idTagInfo"), "groupIdToken") != NULL)
			{
				if(json_object_object_get(json_object_object_get(json_object_object_get(Authorize,"idTokenInfo"), "groupIdToken"), "idToken") != NULL)
					sprintf((char *)ShmOCPP20Data->Authorize.Response_idTokenInfo.groupIdToken.idToken, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(Authorize,"idTokenInfo"), "groupIdToken"), "idToken")));
				else
					memset(ShmOCPP20Data->Authorize.Response_idTokenInfo.groupIdToken.idToken, 0x00, ARRAY_SIZE(ShmOCPP20Data->Authorize.Response_idTokenInfo.groupIdToken.idToken));

				if(json_object_object_get(json_object_object_get(json_object_object_get(Authorize,"idTokenInfo"), "groupIdToken"), "type") != NULL)
					sprintf((char *)ShmOCPP20Data->Authorize.Response_idTokenInfo.groupIdToken.type, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(Authorize,"idTokenInfo"), "groupIdToken"), "type")));
			}

			if(json_object_object_get(json_object_object_get(Authorize,"idTagInfo"), "personalMessage") != NULL)
			{
				if(json_object_object_get(json_object_object_get(json_object_object_get(Authorize,"idTokenInfo"), "personalMessage"), "format") != NULL)
					sprintf((char *)ShmOCPP20Data->Authorize.Response_idTokenInfo.personalMessage.format, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(Authorize,"idTokenInfo"), "personalMessage"), "format")));

				if(json_object_object_get(json_object_object_get(json_object_object_get(Authorize,"idTokenInfo"), "personalMessage"), "language") != NULL)
					sprintf((char *)ShmOCPP20Data->Authorize.Response_idTokenInfo.personalMessage.language, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(Authorize,"idTokenInfo"), "personalMessage"), "language")));

				if(json_object_object_get(json_object_object_get(json_object_object_get(Authorize,"idTokenInfo"), "personalMessage"), "content") != NULL)
					sprintf((char *)ShmOCPP20Data->Authorize.Response_idTokenInfo.personalMessage.content, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(Authorize,"idTokenInfo"), "personalMessage"), "content")));
			}
		}

		if(json_object_object_get(Authorize, "certificateStatus") != NULL)
		{
			strcpy((char *)ShmOCPP20Data->Authorize.Response_certificateStatus, json_object_get_string(json_object_object_get(Authorize, "certificateStatus")));
		}
	}
	json_object_put(Authorize);

	//Update idTag information to authorization cache if supported
	if((strcmp((const char *)ShmOCPP20Data->ControllerComponentVariable[AuthCacheCtrlr_Enabled].variableAttribute[0].value, "TRUE") == 0) &&
	   (strlen((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.groupIdToken.idToken) > 0) &&
	   (strlen((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.cacheExpiryDateTime) >0) &&
	   strstr((char*)ShmOCPP20Data->Authorize.Response_idTokenInfo.status, AuthorizationStatusEnumTypeStr[AuthorizationStatusEnumType_Accepted]) != NULL)
	{
		DB_addLocalCache(&ShmOCPP20Data->Authorize.idToken, &ShmOCPP20Data->Authorize.Response_idTokenInfo);
	}

	ShmOCPP20Data->SpMsg.bits.AuthorizeReq = OFF;
	ShmOCPP20Data->SpMsg.bits.AuthorizeConf = ON; // inform csu
	authorizeRetryTimes = 0;
}

void handleBootNotificationResponse(char *payload, int gun_index)
{
	mtrace();
	char statusStr[12]={0};
	char currentTimeStr[30]={0};
	int intervalInt = 0;

	DEBUG_INFO("handleBootNotificationResponse...\n");

	json_object *BootNotification;
	BootNotification = json_tokener_parse(payload);
	if(!is_error(BootNotification))
	{
		// Required data
		sprintf((char *)currentTimeStr, "%s", json_object_get_string(json_object_object_get(BootNotification,"currentTime")));
		intervalInt = json_object_get_int(json_object_object_get(BootNotification,"interval"));
		sprintf((char *)statusStr, "%s", json_object_get_string(json_object_object_get(BootNotification,"status")));
	}
	json_object_put(BootNotification);

	DEBUG_INFO("statusStr: %s\n", statusStr);

	ShmOCPP20Data->BootNotification.Response_interval = intervalInt;
	BootNotificationInterval = intervalInt;

	//write back to ShmOCPP20Data->BootNotification
	strcpy((char *)ShmOCPP20Data->BootNotification.Response_currentTime, currentTimeStr);
	strcpy((char *)ShmOCPP20Data->BootNotification.Response_status, statusStr);

	if((strcmp(statusStr, RegistrationStatusEnumTypeStr[RegistrationStatusEnumType_Accepted]) == 0 ))
	{
		if(intervalInt < (int)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_HeartbeatInterval].variableCharacteristics.minLimit)
		{
			//Do nothing because the value is out of range.
		}
		else
		{
			sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_HeartbeatInterval].variableAttribute[0].value,"%d", HeartBeatWaitTime);
			HeartBeatWaitTime = intervalInt;
			DEBUG_INFO("BootNotificationResponse setting interval to %d...\n",intervalInt);
		}

		server_sign = TRUE;
		server_pending =FALSE;
		DB_updateBootType(BootReasonEnumType_PowerUp);
		ShmOCPP20Data->SpMsg.bits.SecurityEventNotificationReq = ON;
	}
	else if(strcmp(statusStr, RegistrationStatusEnumTypeStr[RegistrationStatusEnumType_Pending]) == 0)
	{
		server_pending = TRUE;
	}

	syncDateTimeRTC(ShmOCPP20Data->BootNotification.Response_currentTime);

	srand(time(NULL));
	refreshStartTimer(&clientTime.Heartbeat);
	clientTime.Heartbeat.tv_sec -= (ShmOCPP20Data->BootNotification.Response_interval-((rand()%8)+3));

	SetOcppConnStatus(TRUE);
	ShmOCPP20Data->SpMsg.bits.BootNotificationConf = ON;
}

void handleClearedChargingLimitResponse(char *payload, int gun_index)
{
	mtrace();
	json_object *ClearedChargingLimit;

	DEBUG_INFO("handleClearedChargingLimitResponse...\n");
	ClearedChargingLimit = json_tokener_parse(payload);
	if(!is_error(ClearedChargingLimit))
	{
		// Required data
		if(json_object_object_get(ClearedChargingLimit,"status") != NULL)
			sprintf((char*)ShmOCPP20Data->ClearChargingProfile[gun_index].Response_status, json_object_get_string(json_object_object_get(ClearedChargingLimit,"status")));
	}
	json_object_put(ClearedChargingLimit);

	ShmOCPP20Data->CSUMsg.bits[gun_index].ClearedChargingLimitReq = OFF;
	ShmOCPP20Data->CSUMsg.bits[gun_index].ClearedChargingLimitConf = ON;
}

void handleDataTransferResponse(char *payload, int gun_index)
{
	mtrace();
	json_object *DataTrans;

	DEBUG_INFO("handleDataTransferResponse...\n");
	DataTrans = json_tokener_parse(payload);
	if(!is_error(DataTrans))
	{
		// Required data
		if(json_object_object_get(DataTrans,"status") != NULL)
			sprintf((char*)ShmOCPP20Data->DataTransfer[gun_index].Response_status, json_object_get_string(json_object_object_get(DataTrans,"status")));

		// Optional data
		if(json_object_object_get(DataTrans,"data") != NULL)
			sprintf((char*)ShmOCPP20Data->DataTransfer[gun_index].Response_data, json_object_get_string(json_object_object_get(DataTrans,"data")));
	}
	json_object_put(DataTrans);


	ShmOCPP20Data->CpMsg.bits[gun_index].DataTransferReq = OFF;
	ShmOCPP20Data->CpMsg.bits[gun_index].DataTransferConf = ON;
}

void handleFirmwareStatusNotificationResponse(char *payload, int gun_index)
{
	mtrace();
	DEBUG_INFO("handleFirmwareStatusNotificationResponse ...\n");

	ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationReq = OFF;
	ShmOCPP20Data->SpMsg.bits.FirmwareStatusNotificationConf = ON;
}

void handleGet15118EVCertificateResponse(char *payload, int gun_index)
{
	mtrace();
	json_object *Get15118EVCertificate;

	DEBUG_INFO("handleGet15118EVCertificateResponse...\n");
	Get15118EVCertificate = json_tokener_parse(payload);
	if(!is_error(Get15118EVCertificate))
	{
		// Required data
		if(json_object_object_get(Get15118EVCertificate,"status") != NULL)
			sprintf((char*)ShmOCPP20Data->Get15118EVCertificate.Response_status, json_object_get_string(json_object_object_get(Get15118EVCertificate,"status")));

		// Optional data
		if(json_object_object_get(Get15118EVCertificate,"exiResponse") != NULL)
			sprintf((char*)ShmOCPP20Data->Get15118EVCertificate.Response_exiResponse, json_object_get_string(json_object_object_get(Get15118EVCertificate,"exiResponse")));
	}
	json_object_put(Get15118EVCertificate);

	ShmOCPP20Data->SpMsg.bits.Get15118EVCertificateReq = OFF;
	ShmOCPP20Data->SpMsg.bits.Get15118EVCertificateConf = ON;
}

void handleGetCertificateStatusResponse(char *payload, int gun_index)
{
	mtrace();
	json_object *GetCertificateStatus;

	DEBUG_INFO("handleGetCertificateStatusResponse...\n");
	GetCertificateStatus = json_tokener_parse(payload);
	if(!is_error(GetCertificateStatus))
	{
		// Required data
		if(json_object_object_get(GetCertificateStatus,"status") != NULL)
			sprintf((char*)ShmOCPP20Data->GetCertificateStatus.Response_status, json_object_get_string(json_object_object_get(GetCertificateStatus,"status")));

		// Optional data
		if(json_object_object_get(GetCertificateStatus,"ocspResult") != NULL)
			sprintf((char*)ShmOCPP20Data->GetCertificateStatus.Response_ocspResult, json_object_get_string(json_object_object_get(GetCertificateStatus,"ocspResult")));

		if(json_object_object_get(GetCertificateStatus,"statusInfo") != NULL)
		{
			if(json_object_object_get(json_object_object_get(GetCertificateStatus,"statusInfo"), "reasonCode") != NULL)
				sprintf((char*)ShmOCPP20Data->GetCertificateStatus.Response_statusInfo.reasonCode, json_object_get_string(json_object_object_get(json_object_object_get(GetCertificateStatus,"ocspResult"), "reasonCode")));

			if(json_object_object_get(json_object_object_get(GetCertificateStatus,"statusInfo"), "additionalInfo") != NULL)
				sprintf((char*)ShmOCPP20Data->GetCertificateStatus.Response_statusInfo.additionalInfo, json_object_get_string(json_object_object_get(json_object_object_get(GetCertificateStatus,"ocspResult"), "additionalInfo")));
		}
	}
	json_object_put(GetCertificateStatus);


	if(strstr((char*)ShmOCPP20Data->GetCertificateStatus.Response_status, GetCertificateStatusEnumTypeStr[GetCertificateStatusEnumType_Accepted]) != NULL)
	{
		/*
		 * TODO:
		 * 	1. If get certificate response accepted process something here
		 */
	}


	ShmOCPP20Data->SpMsg.bits.GetCertificateStatusReq = OFF;
	ShmOCPP20Data->SpMsg.bits.GetCertificateStatusConf = ON;
}

void handleHeartbeatResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("handleHeartbeatResponse...\n");
	json_object *Heartbeat;
	Heartbeat = json_tokener_parse(payload);
	if(!is_error(Heartbeat))
	{
		// Required data
		if(json_object_object_get(Heartbeat,"currentTime") != NULL)
			sprintf((char *)ShmOCPP20Data->Heartbeat.Response_currentTime, "%s", json_object_get_string(json_object_object_get(Heartbeat,"currentTime")));
	}
	json_object_put(Heartbeat);

	if(FirstHeartBeat == OFF)
	{
		FirstHeartBeat = ON;
		DEBUG_INFO("FirstHeartBeat \n");
	}
	HeartBeatWithNOResponse = 0;
	refreshStartTimer(&clientTime.Heartbeat);

	syncDateTimeRTC(ShmOCPP20Data->Heartbeat.Response_currentTime);
}

void handleLogStatusNotificationResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("handleLogStatusNotificationResponse...\n");

	ShmOCPP20Data->SpMsg.bits.LogStatusNotificationReq = OFF;
	ShmOCPP20Data->SpMsg.bits.LogStatusNotificationConf = ON;
}

void handleMeterValuesResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("handleMeterValuesResponse...\n");
	isQueueSendable = ON;
}

void handleNotifyChargingLimitResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("handleNotifyChargingLimitResponse...\n");

	ShmOCPP20Data->SpMsg.bits.NotifyChargingLimitReq = OFF;
	ShmOCPP20Data->SpMsg.bits.NotifyChargingLimitConf = ON;
}

void handleNotifyCustomerInformationResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("handleNotifyCustomerInformationResponse...\n");
}

void handleNotifyDisplayMessagesResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("handleNotifyDisplayMessagesResponse...\n");

	ShmOCPP20Data->SpMsg.bits.NotifyDisplayMessagesReq = OFF;
	ShmOCPP20Data->SpMsg.bits.NotifyDisplayMessagesConf = ON;
}

void handleNotifyEVChargingNeedsResponse(char *payload, int gun_index)
{
	mtrace();
	json_object *NotifyEVChargingNeeds;

	DEBUG_INFO("handleNotifyEVChargingNeedsResponse...\n");
	NotifyEVChargingNeeds = json_tokener_parse(payload);
	if(!is_error(NotifyEVChargingNeeds))
	{
		// Required data
		if(json_object_object_get(NotifyEVChargingNeeds,"status") != NULL)
			sprintf((char*)ShmOCPP20Data->NotifyEVChargingNeeds[gun_index].Response_status, json_object_get_string(json_object_object_get(NotifyEVChargingNeeds,"status")));
	}
	json_object_put(NotifyEVChargingNeeds);

	ShmOCPP20Data->SpMsg.bits.NotifyChargingLimitReq = OFF;
	ShmOCPP20Data->SpMsg.bits.NotifyChargingLimitConf = ON;
}

void handleNotifyEVChargingScheduleResponse(char *payload, int gun_index)
{
	mtrace();
	json_object *NotifyEVChargingSchedule;

	DEBUG_INFO("handleNotifyEVChargingScheduleResponse...\n");
	NotifyEVChargingSchedule = json_tokener_parse(payload);
	if(!is_error(NotifyEVChargingSchedule))
	{
		// Required data
		if(json_object_object_get(NotifyEVChargingSchedule,"status") != NULL)
			sprintf((char*)ShmOCPP20Data->NotifyEVChargingSchedule[gun_index].Response_status, json_object_get_string(json_object_object_get(NotifyEVChargingSchedule,"status")));
	}
	json_object_put(NotifyEVChargingSchedule);

	ShmOCPP20Data->SpMsg.bits.NotifyEVChargingScheduleReq = OFF;
	ShmOCPP20Data->SpMsg.bits.NotifyEVChargingScheduleConf = ON;
}

void handleNotifyEventResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("handleNotifyEventResponse...\n");

	ShmOCPP20Data->SpMsg.bits.NotifyEventReq = OFF;
	ShmOCPP20Data->SpMsg.bits.NotifyEventConf = ON;
}

void handleNotifyMonitoringReportResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("handleNotifyMonitoringReportResponse...\n");

	ShmOCPP20Data->SpMsg.bits.NotifyMonitoringReportReq = OFF;
	ShmOCPP20Data->SpMsg.bits.NotifyMonitoringReportConf = ON;
}

void handleNotifyReportResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("handleNotifyReportResponse...\n");
	ShmOCPP20Data->SpMsg.bits.NotifyReportReq = OFF;
	ShmOCPP20Data->SpMsg.bits.NotifyReportConf = ON;
}

void handlePublishFirmwareStatusNotificationResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("handlePublishFirmwareStatusNotificationResponse...\n");

	ShmOCPP20Data->CsMsg.bits[gun_index].PublishFirmwareStatusNotificationReq = OFF;
	ShmOCPP20Data->CsMsg.bits[gun_index].PublishFirmwareStatusNotificationConf = ON;
}

void handleReportChargingProfilesResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("handleReportChargingProfilesResponse...gun_index: %d\n", gun_index);

	ShmOCPP20Data->SpMsg.bits.ReportChargingProfilesReq = OFF;
	ShmOCPP20Data->SpMsg.bits.ReportChargingProfilesConf = ON;
}

void handleReservationStatusUpdateResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("handleReservationStatusUpdateResponse...gun_index: %d\n", gun_index);

	ShmOCPP20Data->CpMsg.bits[gun_index].ReservationStatusUpdateReq = OFF;
	ShmOCPP20Data->CpMsg.bits[gun_index].ReservationStatusUpdateConf = ON;
}

void handleSecurityEventNotificationResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("handleSecurityEventNotificationResponse...\n");
	ShmOCPP20Data->SpMsg.bits.SecurityEventNotificationReq = OFF;
	ShmOCPP20Data->SpMsg.bits.SecurityEventNotificationConf = ON;
	DB_updateSecurityEventType(SecurityEventEnumType_ResetOrReboot);
}

void handleSignCertificateResponse(char *payload, int gun_index)
{
	mtrace();
	json_object *SignCertificate;

	DEBUG_INFO("handleSignCertificateResponse...\n");
	SignCertificate = json_tokener_parse(payload);
	if(!is_error(SignCertificate))
	{
		// Required data
		if(json_object_object_get(SignCertificate,"status") != NULL)
			sprintf((char*)ShmOCPP20Data->SignCertificate.Response_status, json_object_get_string(json_object_object_get(SignCertificate,"status")));

		// Optional data
		if(json_object_object_get(json_object_object_get(SignCertificate,"statusInfo"), "reasonCode") != NULL)
		{
			sprintf((char*)ShmOCPP20Data->SignCertificate.Response_statusInfo.reasonCode, json_object_get_string(json_object_object_get(json_object_object_get(SignCertificate,"statusInfo"), "reasonCode")));

			if(json_object_object_get(json_object_object_get(SignCertificate,"statusInfo"), "additionalInfo") != NULL)
				sprintf((char*)ShmOCPP20Data->SignCertificate.Response_statusInfo.additionalInfo, json_object_get_string(json_object_object_get(json_object_object_get(SignCertificate,"statusInfo"), "additionalInfo")));
		}
	}
	json_object_put(SignCertificate);

	ShmOCPP20Data->SpMsg.bits.SignCertificateReq = OFF;
	ShmOCPP20Data->SpMsg.bits.SignCertificateConf = ON;
}

void handleStatusNotificationResponse(char *payload, int gun_index)
{
	mtrace();
	DEBUG_INFO("handleStatusNotificationResponse...gun_index: %d\n", gun_index);

	//cpinitateMsg.bits[gun_index].StatusNotificationReq = OFF;
	//cpinitateMsg.bits[gun_index].TriggerStatusNotificationReq = OFF;
	cpinitateMsg.bits[gun_index].StatusNotificationConf = ON;
}

void handleTransactionEventResponse(char *payload, int gun_index)
{
	mtrace();
	json_object *TransactionEven;

	DEBUG_INFO("handleTransactionEventResponse...\n");
	TransactionEven = json_tokener_parse(payload);
	if(!is_error(TransactionEven))
	{
		// Required data

		// Optional data
		if(json_object_object_get(TransactionEven,"totalCost") != NULL)
			ShmOCPP20Data->TransactionEvent[gun_index].Response_totalCost = json_object_get_double(json_object_object_get(TransactionEven,"totalCost"));

		if(json_object_object_get(TransactionEven,"chargingPriority") != NULL)
			ShmOCPP20Data->TransactionEvent[gun_index].Response_chargingPriority = json_object_get_int(json_object_object_get(TransactionEven,"chargingPriority"));

		if(json_object_object_get(TransactionEven,"idTokenInfo") != NULL)
		{
			if(json_object_object_get(json_object_object_get(TransactionEven,"idTokenInfo"), "status") != NULL)
				sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, json_object_get_string(json_object_object_get(json_object_object_get(TransactionEven,"idTokenInfo"), "status")));

			if(json_object_object_get(json_object_object_get(TransactionEven,"idTokenInfo"), "cacheExpiryDateTime") != NULL)
				sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.cacheExpiryDateTime, json_object_get_string(json_object_object_get(json_object_object_get(TransactionEven,"idTokenInfo"), "cacheExpiryDateTime")));

			if(json_object_object_get(json_object_object_get(TransactionEven,"idTokenInfo"), "chargingPriority") != NULL)
				ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.chargingPriority = json_object_get_int(json_object_object_get(json_object_object_get(TransactionEven,"idTokenInfo"), "chargingPriority"));

			if(json_object_object_get(json_object_object_get(TransactionEven,"idTokenInfo"), "language1") != NULL)
				sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.language1, json_object_get_string(json_object_object_get(json_object_object_get(TransactionEven,"idTokenInfo"), "language1")));

			if(json_object_object_get(json_object_object_get(TransactionEven,"idTokenInfo"), "groupIdToken") != NULL)
			{
				if(json_object_object_get(json_object_object_get(json_object_object_get(TransactionEven,"idTokenInfo"), "groupIdToken"), "idToken") != NULL)
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.groupIdToken.idToken, json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(TransactionEven,"idTokenInfo"), "groupIdToken"), "idToken")));

				if(json_object_object_get(json_object_object_get(json_object_object_get(TransactionEven,"idTokenInfo"), "groupIdToken"), "type") != NULL)
					sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.groupIdToken.type, json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(TransactionEven,"idTokenInfo"), "groupIdToken"), "type")));
			}
		}

		if(json_object_object_get(TransactionEven,"updatedPersonalMessage") != NULL)
		{
			if(json_object_object_get(json_object_object_get(TransactionEven,"updatedPersonalMessage"), "format") != NULL)
				sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_updatedPersonalMessage.format, json_object_get_string(json_object_object_get(json_object_object_get(TransactionEven,"updatedPersonalMessage"), "format")));

			if(json_object_object_get(json_object_object_get(TransactionEven,"updatedPersonalMessage"), "language") != NULL)
				sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_updatedPersonalMessage.language, json_object_get_string(json_object_object_get(json_object_object_get(TransactionEven,"updatedPersonalMessage"), "language")));

			if(json_object_object_get(json_object_object_get(TransactionEven,"updatedPersonalMessage"), "content") != NULL)
				sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_updatedPersonalMessage.content, json_object_get_string(json_object_object_get(json_object_object_get(TransactionEven,"updatedPersonalMessage"), "content")));
		}
	}
	json_object_put(TransactionEven);

	isQueueSendable = ON;
	ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventConf = ON;
}

//==========================================
// Handle Error routine
//==========================================
void handleError(char *id, char *errorCode, char *errorDescription,char *payload)
{
	mtrace();
	#ifdef SystemLogMessage
	DEBUG_INFO("errorCode: %s\n", errorCode);

	DEBUG_INFO("errorDescription: %s\n", errorDescription);

	DEBUG_INFO("errorDetails: %s\n", payload);
	#endif

}

//===============================================
// Common routine
//===============================================
int initialConfigurationTable(void)
{
	DEBUG_INFO("initialConfigurationTable...\n");
	memset(&ShmOCPP20Data->ControllerComponentVariable[0], 0, ARRAY_SIZE(ShmOCPP20Data->ControllerComponentVariable));
	DB_variableIsCreate();
	DB_variableLoadFromDb();

	if(atoi((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_VariableVersion].variableAttribute[0].value) != variableVersion)
	{
		DEBUG_WARN("EVSE variable version in local db older than firmware.\n");

		DB_variableClear();
		DB_variableIsCreate();
		DB_variableLoadFromDb();
	}

	DB_getNetworkProfileFromDb();

	return 0;
}

int TransactionMessageAttemptsGet(void)
{
	return TransactionMessageAttemptsValue;
}

int FirstHeartBeatResponse(void)
{
	return FirstHeartBeat;
}

int TransactionMessageRetryIntervalGet(void)
{
	return TransactionMessageRetryIntervalValue;//atoi((const char *)ShmOCPP20Data->ConfigurationTable.CoreProfile[TransactionMessageRetryInterval].ItemData);
}

int httpDownLoadFile(char *location, char *path, char *filename,char *url)
{
	int result = TRUE;
	char rmFileCmd[100]={0};
    char FilePath[100]={0};
	char ftpbuf[200];
	int systemresult;

	sprintf(FilePath,"/mnt/%s",filename);
	system("ping 8.8.8.8 &");

	if((access(FilePath,F_OK))!=-1)
	{
		DEBUG_INFO("filename=%s exist.\n",FilePath);
		sprintf(rmFileCmd,"rm -f %s",FilePath);
		system(rmFileCmd);
	}
	memset(ftpbuf, 0, ARRAY_SIZE(ftpbuf));
	sprintf(ftpbuf, "wget --tries=1 -O /mnt/%s -c %s -T 120 --no-check-certificate",filename, url);
	DEBUG_INFO("Download command: %s\n",ftpbuf);

	systemresult = system(ftpbuf);
	if(systemresult != 0)
	{
		DEBUG_INFO("HTTP/HTTPS download fail!\n");
		result = FALSE;
	}
	system("pkill ping");

	return result;
}

int ftpDownLoadFile(char *location, char *user, char *password, int port, char *path, char *filename,char *url)
{
	int result = TRUE;
	char rmFileCmd[100]={0};
	char FilePath[100]={0};
	char ftpbuf[200];
	int systemresult;

	sprintf(FilePath,"/mnt/%s",filename);
	system("ping 8.8.8.8 &");

	if((access(FilePath,F_OK))!=-1)
	{
		DEBUG_INFO("filename=%s exist.\n",FilePath);
		sprintf(rmFileCmd,"rm -f %s",FilePath);
		system(rmFileCmd);
	}

	memset(ftpbuf, 0, ARRAY_SIZE(ftpbuf));

	sprintf(ftpbuf, "wget --tries=1 -O /mnt/%s -c %s -T 120",filename, url);
	DEBUG_INFO("Download command: %s\n",ftpbuf);

	systemresult = system(ftpbuf);
	if(systemresult != 0)
	{
		sprintf(ftpbuf, "wget --tries=1 -O /mnt/%s -c %s -T 120 --no-passive-ftp",filename, url);
		DEBUG_INFO("Download command: %s\n",ftpbuf);

		systemresult = system(ftpbuf);
		if(systemresult != 0)
		{
			DEBUG_WARN("FTP download fail!\n");
			result = FALSE;
		}
	}
	system("pkill ping");

	return result;
}

int httpUploadFile(char *location, char *path, char *filename,char *url)
{
	char rmFileCmd[100]={0};
    char FilePath[100]={0};
	char buf[512];
	int systemresult = 0;

	//DEBUG_INFO("filename=%s\n",filename);
	//DEBUG_INFO("url=%s\n",url);
	sprintf(FilePath,"%s","/mnt/upload_file.txt");

	if((access(FilePath,F_OK))!=-1)
	{
		DEBUG_INFO("filename=%s exist.\n",FilePath);
		sprintf(rmFileCmd,"rm -f %s",FilePath);
		system(rmFileCmd);
	}

	FILE *fp = fopen("/mnt/upload_file.txt", "w+");
	if(fp == NULL)
	{
		DEBUG_INFO("log is NULL\n");
		return FALSE;
	}
	else
	{
		fprintf(fp, "%s\n", url);
		fprintf(fp, "%s\n", filename);
		fclose(fp);
	}

	FILE *phpFP = popen("/bin/php-cgi /var/www/ocpp_upload.php", "r");
	if(phpFP == NULL)
	{
		DEBUG_INFO("PHP upload fail.\n");
		return FALSE;
	}
	else
	{
		while(fgets(buf, sizeof(buf), phpFP) != NULL)
		{
			if(strstr(buf, "result") != NULL)
			{
				sscanf(buf, "result: %d", &systemresult);
				DEBUG_INFO("PHP HTTP upload result: %d\n", systemresult);
			}
		}
		pclose(phpFP);
	}

	if(systemresult != 1)
	{
		DEBUG_WARN("HTTP POST upload error, change to PUT method\n");
		FILE *phpFP = popen("/bin/php-cgi /var/www/ocpp_upload_put.php", "r");
		if(phpFP == NULL)
		{
			DEBUG_WARN("PHP PUT upload fail.\n");
			return FALSE;
		}
		else
		{
			while(fgets(buf, sizeof(buf), phpFP) != NULL)
			{
				if(strstr(buf, "result") != NULL)
				{
					sscanf(buf, "result: %d", &systemresult);
					DEBUG_INFO("PHP HTTP PUT upload result: %d\n", systemresult);
				}
			}
			pclose(phpFP);
		}
	}

	if(systemresult != 1)
	{
		DEBUG_WARN("PHP PUT upload fail.\n");
		return FALSE;
	}

	return TRUE;
}

int ftpUploadFile(char *location, char *user, char *password, int port, char *path, char *fnamePlusPath,char *filename)
{
	int result = FALSE;
	char ftpbuf[200];
	int systemresult;

	/*
	// Domaind name transfer to IP address
	struct hostent* server;
 	char *IPbuffer;
	server = gethostbyname(location);
	IPbuffer = inet_ntoa(*((struct in_addr*)server->h_addr_list[0]));*/

	memset(ftpbuf, 0, ARRAY_SIZE(ftpbuf));

	sprintf(ftpbuf, "ftpput -u %s -p %s %s -P %d %s%s %s", user, password, location, port/*21*/, path, filename, fnamePlusPath);
	DEBUG_INFO("ftp command: %s\n",ftpbuf);
	systemresult = system(ftpbuf);

	if(systemresult != 0)
	{
		DEBUG_INFO("ftpput error!\n");
	}
	else
	{
		result = TRUE;
		DEBUG_INFO("ftpput OK!\n");
	}

	return result;
}

//=========================================
// Routine
//=========================================
int GetOcppServerURL()
{
    int result = FALSE;
    struct yuarel url;
    char urlStr[512];

	memset(OcppProtocol, 0, ARRAY_SIZE(OcppProtocol));
	memset(OcppHost, 0, ARRAY_SIZE(OcppHost));
	memset(OcppTempPath, 0, ARRAY_SIZE(OcppTempPath));

	if((ShmOCPP20Data->OcppServerURL != NULL) && (strcmp((const char *)ShmOCPP20Data->OcppServerURL,"") != 0))
	{
		memcpy(urlStr, ShmOCPP20Data->OcppServerURL, ARRAY_SIZE(ShmOCPP20Data->OcppServerURL));
		if(yuarel_parse(&url, urlStr) != -1)
		{
			sprintf(OcppProtocol, "%s", url.scheme);
			sprintf(OcppHost, "%s", url.host);

			if(url.path == NULL)
				OcppTempPath[0] = '\0';
	        else
			   sprintf(OcppTempPath, "%s", url.path);

			if(url.port == 0)
			{
				if(strcmp(OcppProtocol, "wss") == 0)
					OcppPort = 443;
				else
					OcppPort = 80;
			}
			else
				OcppPort = url.port;

		   result = TRUE;
		}
	}
	else
	{
		strcpy(OcppHost,"");
	}

	return result;
}

int GetOcppPath()
{
	int result = FALSE;
	if((ShmSysConfigAndInfo->SysConfig.ChargeBoxId != NULL) && (strcmp((const char *)ShmSysConfigAndInfo->SysConfig.ChargeBoxId,"") != 0) )
	{
		if(OcppTempPath == NULL)
		{
			sprintf(OcppPath,"/%s",ShmSysConfigAndInfo->SysConfig.ChargeBoxId);
		}
		else
		{
			sprintf(OcppPath,"/%s%s",OcppTempPath,ShmSysConfigAndInfo->SysConfig.ChargeBoxId);
		}
		result = TRUE;
	}
	else if((ShmOCPP20Data->ChargeBoxId != NULL) && (strcmp((const char *)ShmOCPP20Data->ChargeBoxId,"") != 0))
	{
		if(OcppTempPath == NULL)
		{
			sprintf(OcppPath,"/%s",ShmOCPP20Data->ChargeBoxId);
		}
		else
		{
			sprintf(OcppPath,"/%s%s",OcppTempPath,ShmOCPP20Data->ChargeBoxId);
		}
		result = TRUE;
	}
	else
	{
		strcpy(OcppPath,"");
	}

	return result;
}

int GetOcppPort()
{
	return OcppPort;
}

int GetOcppConnStatus(void)
{
	return ShmOCPP20Data->OcppConnStatus;
}

void SetOcppConnStatus(uint8_t status)
{
	ShmOCPP20Data->OcppConnStatus = status;
	ShmSysConfigAndInfo->SysInfo.OcppConnStatus = status;
}

int GetHeartBeatWithNOResponse(void)
{
	return HeartBeatWithNOResponse;
}

void SetHeartBeatWithNOResponse(void)
{
	HeartBeatWithNOResponse = 0;
}

//Note: It is not real StopTransaction. It is temporary StopTransaction.
void storeTempStopTransaction(int gun_index)
{
	char TempStopTransaction[256];
	char message[1024*20]={0};
	char guid[37]={0};
	json_object *TransactionEvent = json_object_new_object();
	json_object *transactionInfo = json_object_new_object();
	json_object *idToken = json_object_new_object();
	json_object *evse = json_object_new_object();
	json_object *meterValues = json_object_new_array();
	sprintf(TempStopTransaction, "/Storage/OCPP/TempStopTransaction20_%d", (gun_index+1));

	DEBUG_INFO("storeTempStopTransaction...\n");

	getNowDatetime(ShmOCPP20Data->TransactionEvent[gun_index].timestamp);
	ShmOCPP20Data->TransactionEvent[gun_index].offline = (!ShmOCPP20Data->OcppConnStatus?TRUE:FALSE);
	ShmOCPP20Data->TransactionEvent[gun_index].evse.id = (gun_index + 1);
	ShmOCPP20Data->TransactionEvent[gun_index].evse.connectorId = (gun_index + 1);

	sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Ended]);
	sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
	sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);

	// Message
	json_object_object_add(TransactionEvent, "eventType", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].eventType));
	json_object_object_add(TransactionEvent, "timestamp", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].timestamp));
	json_object_object_add(TransactionEvent, "triggerReason", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].triggerReason));
	json_object_object_add(TransactionEvent, "seqNo", json_object_new_int(ShmOCPP20Data->TransactionEvent[gun_index].seqNo+1));
	json_object_object_add(TransactionEvent, "offline", json_object_new_boolean(ShmOCPP20Data->TransactionEvent[gun_index].offline));

	if(ShmOCPP20Data->TransactionEvent[gun_index].numberOfPhasesUsed > 0)
		json_object_object_add(TransactionEvent, "numberOfPhasesUsed", json_object_new_int(ShmOCPP20Data->TransactionEvent[gun_index].numberOfPhasesUsed));

	if(ShmOCPP20Data->TransactionEvent[gun_index].cableMaxCurrent > 0)
		json_object_object_add(TransactionEvent, "cableMaxCurrent", json_object_new_double(ShmOCPP20Data->TransactionEvent[gun_index].cableMaxCurrent));

	if(ShmOCPP20Data->TransactionEvent[gun_index].reservationId > 0)
		json_object_object_add(TransactionEvent, "reservationId", json_object_new_int(ShmOCPP20Data->TransactionEvent[gun_index].reservationId));


	json_object_object_add(transactionInfo, "transactionId", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId));
	json_object_object_add(transactionInfo, "chargingState", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.chargingState));

	if(ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.timeSpentCharging > 0)
		json_object_object_add(transactionInfo, "timeSpentCharging", json_object_new_int(ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.timeSpentCharging));

	if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason) > 0)
		json_object_object_add(transactionInfo, "stoppedReason", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason));

	if(ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.remoteStartId > 0)
		json_object_object_add(transactionInfo, "remoteStartId", json_object_new_int(ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.remoteStartId));

	json_object_object_add(TransactionEvent, "transactionInfo", transactionInfo);


	if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken) > 0)
	{
		json_object_object_add(idToken, "idToken", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken));
		json_object_object_add(idToken, "type", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].idToken.type));
		json_object_object_add(TransactionEvent, "idToken", idToken);
	}

	json_object_object_add(evse, "id", json_object_new_int(ShmOCPP20Data->TransactionEvent[gun_index].evse.id));
	json_object_object_add(evse, "connectorId", json_object_new_int(ShmOCPP20Data->TransactionEvent[gun_index].evse.connectorId));
	json_object_object_add(TransactionEvent, "evse", evse);


	if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[0].timestamp) > 0)
	{
		for(int idxMeter=0;idxMeter<ARRAY_SIZE(ShmOCPP20Data->TransactionEvent[gun_index].meterValue);idxMeter++)
		{
			json_object *meterValue = json_object_new_object();
			json_object *sampledValues = json_object_new_array();

			json_object_object_add(meterValue, "timestamp", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].timestamp));

			for(int idxSample=0;idxSample<ARRAY_SIZE(ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue);idxSample++)
			{
				if((strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].context) > 0) &&
				   ((strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].phase) > 0) || (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].measurand, MeasurandEnumTypeStr[MeasurandEnumType_SoC]) == 0) || (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].measurand, MeasurandEnumTypeStr[MeasurandEnumType_Current_Offered]) == 0) || (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].measurand, MeasurandEnumTypeStr[MeasurandEnumType_Power_Offered]) == 0)))
				{
					if(strstr((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].variableAttribute[0].value, (char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].measurand) != NULL)
					{
						json_object *sampledValue = json_object_new_object();

						json_object_object_add(sampledValue, "value", json_object_new_double(ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].value));

						if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].context) > 0)
							json_object_object_add(sampledValue, "context", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].context));

						if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].measurand) > 0)
							json_object_object_add(sampledValue, "measurand", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].measurand));

						if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].phase) > 0)
							json_object_object_add(sampledValue, "phase", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].phase));

						if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].location) > 0)
							json_object_object_add(sampledValue, "location", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].location));

						if(strlen((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].unitOfMeasure.uint) > 0)
						{
							json_object *unitOfMeasure = json_object_new_object();

							json_object_object_add(unitOfMeasure, "unit", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].unitOfMeasure.uint));
							json_object_object_add(unitOfMeasure, "multiplier", json_object_new_int(ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].unitOfMeasure.multiplier));
							json_object_object_add(sampledValue, "unitOfMeasure", unitOfMeasure);
						}

						json_object_array_add(sampledValues, sampledValue);
					}
				}
			}
			json_object_object_add(meterValue, "sampledValue", sampledValues);

			json_object_array_add(meterValues, meterValue);
		}
		json_object_object_add(TransactionEvent, "meterValue", meterValues);
	}

	random_uuid(guid);
	sprintf(message,"[%d,\"%s\",\"%s\",%s]",MESSAGE_TYPE_CALL
										   , guid
										   , "TransactionEvent"
										   , json_object_to_json_string_ext(TransactionEvent, JSON_C_TO_STRING_PLAIN));
	json_object_put(TransactionEvent);


	// open file for writing
	FILE *outfile;
	outfile = fopen (TempStopTransaction, "w+");
	//DEBUG_INFO("data = %s\n", queuedata);
	fputs(message, outfile);
	fputs("\n", outfile);
	fclose (outfile);
}

void checkTempStopTransaction(int gun_index)
{
	FILE *fptr1;
	char ch;
	char str[QUEUE_MESSAGE_LENGTH]={0};
	char guid[37]={0};
	char tempdata[65]={0};
	char TempStopTransaction[256];
	sprintf(TempStopTransaction, "/Storage/OCPP/TempStopTransaction20_%d", (gun_index+1));

	fptr1 = fopen(TempStopTransaction, "r");
	if (!fptr1)
	{
		//DEBUG_INFO("TempStopTransaction20_%d not found or unable to open the input file!\n", (gun_index+1));
	    return ;
	}

	ch=fgetc(fptr1);
	rewind(fptr1);
	if(ch!=EOF)
	{
		// copy all contents to the temporary file except the specific line
		while (fgets(str, QUEUE_MESSAGE_LENGTH, fptr1) != NULL)
		{
			str[strlen(str) - 1] = '\0'; // eat the newline fgets() stores

			if(str[0]=='\0')
			{
				break;
			}

			strncpy(guid, str+4, 36); //copy guid
			sprintf(tempdata, "TransactionEvent,%d", (gun_index));
			if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == 1)
			{
				//DEBUG_INFO("StopTransaction mapitem pass\n");
			}
			queue_operation(QUEUE_OPERATION_ADD, guid, str);//addq(guid, queuedata); ---> remove temporally

			memset(str,0,ARRAY_SIZE(str));
		}
	}

	// fptr1=freopen(NULL,"w",fptr1); // reset the fptr1 again
	fclose(fptr1);
	remove(TempStopTransaction);  		// remove the original file
}

int GetWebSocketPingInterval(void)
{
	return atoi((char *)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_WebSocketPingInterval].variableAttribute[0].value);
}

int GetServerSign(void)
{
	return server_sign;
}

uint8_t GetOcppSecurityProfile()
{
	return atoi((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_SecurityProfile].variableAttribute[0].value);
}

void GetOcppChargerBoxId(uint8_t *data)
{
	sprintf((char*)data, "%s", ShmSysConfigAndInfo->SysConfig.ChargeBoxId);
}

void GetOcppSecurityPassword(uint8_t *data)
{
	sprintf((char*)data, "%s", ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variableAttribute[0].value);
}

void SetServerSign(int value)
{
	server_sign = value;
}

int GetBootNotificationInterval(void)
{
	return BootNotificationInterval;
}

int GetInternetConn(void)
{
	return ShmSysConfigAndInfo->SysInfo.InternetConn;
}

int GetBackendConnectionTimeout(void)
{
	return ShmSysConfigAndInfo->SysConfig.BackendConnTimeout>=0?ShmSysConfigAndInfo->SysConfig.BackendConnTimeout:300;
}

int isConnectorInitMode(int gun_index)
{
	int tempIndex = 0;
	int result = TRUE;

	//J: CHAdeMO  U: CCS1 combo  E: CCS2 combo  G: GBT DCcc
	if(gunType[gun_index] == GUN_TYPE_CHAdeMO)
	{
		if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
		{
			tempIndex = ((gun_index==2) ? 1: 0);
		}
		else
		{
			tempIndex = gun_index;
		}

		for (int index = 0; index < CHAdeMO_QUANTITY; index++)
		{
			if ((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex))
			{
				result = (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus==SYS_MODE_BOOTING)?TRUE:FALSE;
			} //end of the same index
		}//end of for CHAdeMO_QUANTITY

	}
	else if(gunType[gun_index] == GUN_TYPE_CCS)
	{
		if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
		{
			tempIndex = ((gun_index==2) ? 1: 0);
		}
		else
		{
			tempIndex = gun_index;
		}

		for (int index = 0; index < CCS_QUANTITY; index++)
		{
			if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
			{
				result = (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus==SYS_MODE_BOOTING)?TRUE:FALSE;
			} //end of the same index
		} // end of for CCS_QUANTITY
	}
	else if(gunType[gun_index] == GUN_TYPE_GBT)
	{
		if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
		{
			tempIndex = ((gun_index==2) ? 1: 0);
		}
		else
		{
			tempIndex = gun_index;
		}

		for (int index = 0; index < GB_QUANTITY; index++)
		{
			if(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex)
			{
				result = (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus==SYS_MODE_BOOTING)?TRUE:FALSE;
			} //end of the same index
		} // end of for GB_QUANTITY
	}
	else if(gunType[gun_index] == GUN_TYPE_DO)
	{
		tempIndex = gun_index;

		for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
		{
			if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
			{
				result = (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus==SYS_MODE_BOOTING)?TRUE:FALSE;
			} //end of the same index
		}
	}
	else
	{
		if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D')
		{
			tempIndex = 2;
		}
		else
		{
			tempIndex = gun_index;
		}

		for (int index = 0; index < AC_QUANTITY; index++)
		{
			if(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
			{
				result = (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus==SYS_MODE_BOOTING)?TRUE:FALSE;
			}//end of the same index

		}//end of for AC_QUANTITY
	}

	return result;
}

void refreshProcDogTimer()
{
	ShmOCPP20Data->procDogTime = time((time_t*)NULL);
}

void InitialSystemValue(void)
{
	localversion=0;
	BootNotificationInterval = 10;
	authorizeRetryTimes = 0;
	GunStatusInterval = 10;
	TransactionMessageAttemptsValue = atoi((char *)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttempts].variableAttribute[0].value);
	TransactionMessageRetryIntervalValue = atoi((char *)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_MessageAttemptInterval].variableAttribute[0].value);

	//Hear Beat
	HeartBeatWithNOResponse = 0;
	HeartBeatCountPerHour = 0;
	HeartBeatWaitTime = atoi((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_HeartbeatInterval].variableAttribute[0].value);;
	FirstHeartBeat = 0;

	FirmwareStatusNotificationStatus = FirmwareStatusEnumType_Idle;  // Idle
	LogStatusNotificationStatus 	 = UploadLogStatusEnumType_Idle; // Idle

	memset(CurrentChargingProfileScheduleStr, 0, ARRAY_SIZE(CurrentChargingProfileScheduleStr));
	memset(ChademoPreviousSystemStatus, 0, ARRAY_SIZE(ChademoPreviousSystemStatus));
	memset(CcsPreviousSystemStatus, 0, ARRAY_SIZE(CcsPreviousSystemStatus));
	memset(GbPreviousSystemStatus, 0, ARRAY_SIZE(GbPreviousSystemStatus));
	memset(AcPreviousSystemStatus, 0, ARRAY_SIZE(AcPreviousSystemStatus));
	memset(ChademoPreviousConnectorPlugIn, 0, ARRAY_SIZE(ChademoPreviousConnectorPlugIn));
	memset(CcsPreviousConnectorPlugIn, 0, ARRAY_SIZE(CcsPreviousConnectorPlugIn));
	memset(GbPreviousConnectorPlugIn, 0, ARRAY_SIZE(GbPreviousConnectorPlugIn));
	memset(AcPreviousConnectorPlugIn, 0, ARRAY_SIZE(AcPreviousConnectorPlugIn));

	//Status &&  ConnectorPlugIn Setting
	for (int index = 0; index < CHAdeMO_QUANTITY; index++)
	{
		ChademoPreviousSystemStatus[index] = 99; //ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PreviousSystemStatus;
		ChademoPreviousConnectorPlugIn[index] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ConnectorPlugIn;
	}

	for (int index = 0; index < CCS_QUANTITY; index++)
	{
		CcsPreviousSystemStatus[index] = 99; //ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PreviousSystemStatus;
		CcsPreviousConnectorPlugIn[index] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ConnectorPlugIn;
	}

	for (int index = 0; index < GB_QUANTITY; index++)
	{
		GbPreviousSystemStatus[index] = 99; //ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PreviousSystemStatus;
		GbPreviousConnectorPlugIn[index] = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ConnectorPlugIn;
	}

	for (int index = 0; index < AC_QUANTITY; index++)
	{
		AcPreviousSystemStatus[index] = 99; //ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PreviousSystemStatus;
		AcPreviousConnectorPlugIn[index] = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState;
	}

	for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
	{
		DoPreviousSystemStatus[index] = 99; //ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PreviousSystemStatus;
		DoPreviousConnectorPlugIn[index] = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PilotState;
	}

	for(int gun_index=0; gun_index < gunTotalNumber; gun_index++ )
	{
		cpinitateMsg.bits[gun_index].TriggerStatusNotificationReq = OFF;
		cpinitateMsg.bits[gun_index].StatusNotificationReq = OFF;
		cpinitateMsg.bits[gun_index].StatusNotificationConf = OFF;
		//clientTime.MeterValues[gun_index] = time((time_t*)NULL);
		refreshStartTimer(&clientTime.StatusNotification[gun_index]);
		//memset(&ShmOCPP20Data->StatusNotification[gun_index], 0x00, sizeof(struct StatusNotification_20));
		memset(&ShmOCPP20Data->StatusNotification[gun_index].connectorStatus, 0x00, sizeof(ShmOCPP20Data->StatusNotification[gun_index].connectorStatus));
	}

	refreshStartTimer(&clientTime.Heartbeat);

	sleep(1);
}

void LWS_Send(char *str)
{
	//=====================================================
	// Check InternetConn 0: disconnected, 1: connected
	//====================================================
	if(GetOcppConnStatus() == 0)
	{
		DEBUG_INFO("offline  now !!!\n");
		return;
	}

    // Only disable isWebsocketSendable operation initiated by charger
    if((strstr((char*)str, "\"Authorize\"") != NULL)
    || (strstr((char*)str, "\"BootNotification\"") != NULL)
	|| (strstr((char*)str, "\"ClearedChargingLimit\"") != NULL)
	|| (strstr((char*)str, "\"DataTransfer\"") != NULL)
	|| (strstr((char*)str, "\"FirmwareStatusNotification\"") != NULL)
	|| (strstr((char*)str, "\"Get15118EVCertificate\"") != NULL)
	|| (strstr((char*)str, "\"GetCertificateStatus\"") != NULL)
	|| (strstr((char*)str, "\"Heartbeat\"") != NULL)
	|| (strstr((char*)str, "\"LogStatusNotification\"") != NULL)
	|| (strstr((char*)str, "\"MeterValues\"") != NULL)
	|| (strstr((char*)str, "\"NotifyChargingLimit\"") != NULL)
	|| (strstr((char*)str, "\"NotifyCustomerInformation\"") != NULL)
	|| (strstr((char*)str, "\"NotifyDisplayMessages\"") != NULL)
	|| (strstr((char*)str, "\"NotifyEVChargingNeeds\"") != NULL)
	|| (strstr((char*)str, "\"NotifyEVChargingSchedule\"") != NULL)
	|| (strstr((char*)str, "\"NotifyEvent\"") != NULL)
	|| (strstr((char*)str, "\"NotifyMonitoringReport\"") != NULL)
	|| (strstr((char*)str, "\"NotifyReport\"") != NULL)
	|| (strstr((char*)str, "\"PublishFirmwareStatusNotification\"") != NULL)
	|| (strstr((char*)str, "\"ReportChargingProfiles\"") != NULL)
	|| (strstr((char*)str, "\"ReservationStatusUpdate\"") != NULL)
	|| (strstr((char*)str, "\"SecurityEventNotification\"") != NULL)
	|| (strstr((char*)str, "\"SignCertificate\"") != NULL)
	|| (strstr((char*)str, "\"StatusNotification\"") != NULL)
	|| (strstr((char*)str, "\"TransactionEvent\"") != NULL))
    {
    	isWebsocketSendable = OFF;
    }

	pthread_mutex_lock(&lock_send);
	memset(SendBuffer, 0, ARRAY_SIZE(SendBuffer));
	sprintf((char *)SendBuffer, "%s", str);
	SendBufLen = strlen(str);
	pthread_mutex_unlock(&lock_send);

	lws_callback_on_writable(wsi_client);
	//lws_service(context, 0);
	//sleep(1);
}

void LWS_SendNow(char *str)
{
	//=====================================================
	// Check InternetConn 0: disconnected, 1: connected
	//====================================================
	if(GetOcppConnStatus() == 0)
	{
		DEBUG_INFO("offline  now !!!\n");
		return;
	}

    // Only disable isWebsocketSendable operation initiated by charger
    if((strstr((char*)str, "\"Authorize\"") != NULL)
    || (strstr((char*)str, "\"BootNotification\"") != NULL)
	|| (strstr((char*)str, "\"ClearedChargingLimit\"") != NULL)
	|| (strstr((char*)str, "\"DataTransfer\"") != NULL)
	|| (strstr((char*)str, "\"FirmwareStatusNotification\"") != NULL)
	|| (strstr((char*)str, "\"Get15118EVCertificate\"") != NULL)
	|| (strstr((char*)str, "\"GetCertificateStatus\"") != NULL)
	|| (strstr((char*)str, "\"Heartbeat\"") != NULL)
	|| (strstr((char*)str, "\"LogStatusNotification\"") != NULL)
	|| (strstr((char*)str, "\"MeterValues\"") != NULL)
	|| (strstr((char*)str, "\"NotifyChargingLimit\"") != NULL)
	|| (strstr((char*)str, "\"NotifyCustomerInformation\"") != NULL)
	|| (strstr((char*)str, "\"NotifyDisplayMessages\"") != NULL)
	|| (strstr((char*)str, "\"NotifyEVChargingNeeds\"") != NULL)
	|| (strstr((char*)str, "\"NotifyEVChargingSchedule\"") != NULL)
	|| (strstr((char*)str, "\"NotifyEvent\"") != NULL)
	|| (strstr((char*)str, "\"NotifyMonitoringReport\"") != NULL)
	|| (strstr((char*)str, "\"NotifyReport\"") != NULL)
	|| (strstr((char*)str, "\"PublishFirmwareStatusNotification\"") != NULL)
	|| (strstr((char*)str, "\"ReportChargingProfiles\"") != NULL)
	|| (strstr((char*)str, "\"ReservationStatusUpdate\"") != NULL)
	|| (strstr((char*)str, "\"SecurityEventNotification\"") != NULL)
	|| (strstr((char*)str, "\"SignCertificate\"") != NULL)
	|| (strstr((char*)str, "\"StatusNotification\"") != NULL)
	|| (strstr((char*)str, "\"TransactionEvent\"") != NULL))
    {
    	isWebsocketSendable = OFF;
    }

	pthread_mutex_lock(&lock_send);
	memset(SendBuffer, 0, ARRAY_SIZE(SendBuffer));
	sprintf((char *)SendBuffer, "%s", str);
	SendBufLen = strlen(str);
	pthread_mutex_unlock(&lock_send);

	lws_callback_on_writable(wsi_client);
	lws_service(context, 0);
	//sleep(1);
}