#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)
};

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

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

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)
};

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

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)
};

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)
};

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

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

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)
};

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

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)
};

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)
};

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)

};

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

#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 ChargePointMaxProfile_JSON     	"/Storage/OCPP/ChargePointMaxProfile_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 int gunTotalNumber				= 0;
static uint8_t gunType[4] 				= {0};

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

//===============================
// OCPP sign variable
//===============================
static int server_sign					= FALSE;
int server_pending 						= FALSE;
static int BootNotificationInterval 	= 10;
static int SystemInitial 				= 0;//= CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY;	// System Boot UP

//===============================
// 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 int TempMeterValueInterval 															= 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 StructOCPPMeterValue
{
	unsigned char 				TimeStamp[28];
	struct StructSampledValue	SampledValue[10];
};

struct ClientTime
{
	unsigned int Heartbeat;
	unsigned int StatusNotification[CONNECTOR_QUANTITY];
	unsigned int StartTransaction;
	unsigned int StopTransaction;
	unsigned int MeterValues[CONNECTOR_QUANTITY];

}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 TransactionEventReq:1;		//bit 3,
		unsigned char SampleMeterReq:1;				//bit 4,
		unsigned char ClockAlignMeterReq:1;			//bit 5,
		unsigned char :2;
	}bits[CONNECTOR_QUANTITY];
}CpinitiateMsg;

CpinitiateMsg cpinitateMsg;
//=========================================
// 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, "
							 "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 *sqlNetworkProfile	= "create table if not exists ocpp20_networkprofile (idx integer primary key,"
								 "slot integer UNIQUE, connectionData 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, 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");
		}

		//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_cache";
	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_local";
	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 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) VALUES('%s', '%s', '%s', '%s', '%s', '%s', %f, '%s', '%s', '%s');  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);

	//* 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]);
		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");
		else
			sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Measurands].variableAttribute[0].value, "Current.Import,Energy.Active.Import.Register,Energy.Active.Import.Interval,Power.Active.Import,Voltage");
		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]);
		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]);
		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_Target]);
		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_Target]);
		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_Target]);
		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_Target]);
		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_Target]);
		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_Target]);
		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_Target]);
		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_Target]);
		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*100);
		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]);

		/* 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]);
		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", "0");
		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_Target]);
		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]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_Entries].variableAttribute[0].type, "%s", AttributeEnumTypeStr[AttributeEnumType_Target]);
		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_Target]);
		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_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_ItemsPerMessage].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[LocalAuthListCtrlr_ItemsPerMessage].variableAttribute[0].value, "50");
		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, "2048");
		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*1024;
		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, "5000");
		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");
		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_Target]);
		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, "3");
		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");
		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]);

		/* 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]);
		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]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxEndedMeasurands].variableAttribute[0].value, " ");
		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]);
		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]);
		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]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedMeasurands].variableAttribute[0].value, " ");
		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]);
		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, "0");
		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_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[SecurityCtrlr_BasicAuthPassword].variableAttribute[0].value, " ");
		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, "Phihong Technology");
		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, "Phihong");
		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]);
		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_ReadWrite]);
		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, "0");
		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]);

		/* 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, "0");
		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]);
		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, "3");
		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_Target]);
		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_Target]);
		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_Target]);
		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_Target]);
		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_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStartPoint].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStartPoint].variableAttribute[0].value, "EVConnected,Authorized,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_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStopPoint].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadOnly]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_TxStopPoint].variableAttribute[0].value, "EVConnected,Authorized,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_Target]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_MaxEnergyOnInvalidId].variableAttribute[0].mutability, "%s", MutabilityEnumTypeStr[MutabilityEnumType_ReadWrite]);
		sprintf((char*)ShmOCPP20Data->ControllerComponentVariable[TxCtrlr_MaxEnergyOnInvalidId].variableAttribute[0].value, "60000");
		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_Target]);
		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");

		/* 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");

		/* 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");

		/* 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");

		/* 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((strstr((char*)ShmOCPP20Data->ControllerComponentVariable[idx].component.name, columnValue[1]) != NULL) &&
		   (strlen(columnValue[2])>0?(strstr((char*)ShmOCPP20Data->ControllerComponentVariable[idx].component.instance, columnValue[2]) != NULL):TRUE) &&
		   (strstr((char*)ShmOCPP20Data->ControllerComponentVariable[idx].variable.name, columnValue[3]) != NULL) &&
		   (strlen(columnValue[4])>0?(strstr((char*)ShmOCPP20Data->ControllerComponentVariable[idx].variable.instance, columnValue[4]) != NULL):TRUE))
		{
			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]);
		}
	}

	return 0;
}

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

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

	/* 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;
}

//==========================================
// 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()
{
	int result = -1;
	time_t t;
	struct tm *tmStartToday;
	struct timeb tbStartToday;

	t=time(NULL);
	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;

	return 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)
{
	int result = -1;
	struct tm tmStart;
	struct timeb tbStart;
	struct tm tmStop;
	struct timeb tbStop;


	if((sscanf((char*)start, "%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*)stop, "%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))
	{
		//DEBUG_INFO("Start: %d-%d-%d %d:%d:%d\n", tmStart.tm_year, tmStart.tm_mon, tmStart.tm_mday, tmStart.tm_hour, tmStart.tm_min, tmStart.tm_sec);
		//DEBUG_INFO("Stop: %d-%d-%d %d:%d:%d\n", tmStop.tm_year, tmStop.tm_mon, tmStop.tm_mday, tmStop.tm_hour, tmStop.tm_min, tmStop.tm_sec);

		tmStart.tm_year -= 1900;
		tmStart.tm_mon -= 1;
		tbStart.time = mktime(&tmStart);
		tbStart.millitm = 0;

		tmStop.tm_year -= 1900;
		tmStop.tm_mon -= 1;
		tbStop.time = mktime(&tmStop);
		tbStop.millitm = 0;

		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 = YES;
	struct tm tmStart;
	struct timeb tbStart;

	if((sscanf((char*)start, "%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))
	{
		//DEBUG_INFO("Start: %d-%d-%d %d:%d:%d\n", tmStart.tm_year, tmStart.tm_mon, tmStart.tm_mday, tmStart.tm_hour, tmStart.tm_min, tmStart.tm_sec);

		tmStart.tm_year -= 1900;
		tmStart.tm_mon -= 1;
		tbStart.time = mktime(&tmStart);
		tbStart.millitm = 0;

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

	return result;
}

int getStartSinceRecurring(uint8_t *start, uint8_t *stop, uint8_t isDaily)
{
	int result = -1;
	struct tm tmStart;
	struct timeb tbStart;
	struct tm tmStop;
	struct timeb tbStop;

	if((sscanf((char*)start, "%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*)stop, "%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))
	{
		tmStart.tm_year -= 1900;
		tmStart.tm_mon -= 1;
		tbStart.time = mktime(&tmStart);
		tbStart.millitm = 0;

		tmStop.tm_year -= 1900;
		tmStop.tm_mon -= 1;
		tbStop.time = mktime(&tmStop);
		tbStop.millitm = 0;

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

	return result;
}

void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct ChargingProfileType *compositeProfile)
{
	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 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[0].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);
	sprintf((char*)compositeProfile->chargingSchedule[0].chargingRateUnit, "A");
	compositeProfile->chargingSchedule[0].duration = durationReq;
	for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(compositeProfile->chargingSchedule[0].chargingSchedulePeriod);idxPeriod++)
	{
		compositeProfile->chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod = -1;
		compositeProfile->chargingSchedule[0].chargingSchedulePeriod[idxPeriod].limit = -1;
		compositeProfile->chargingSchedule[0].chargingSchedulePeriod[idxPeriod].numberPhases = 3;
		compositeProfile->chargingSchedule[0].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[0].duration = -1;
	defaultTxProfile.chargingSchedule[0].duration = -1;
	txProfile.chargingSchedule[0].duration = -1;

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

		for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(txProfile.chargingSchedule[0].chargingSchedulePeriod);idxPeriod++)
		{
			txProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod = -1;
			txProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].limit = -1;
			txProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].numberPhases = 3;
			txProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].phaseToUse = 0;
		}
		txProfile.id = -1;
		txProfile.stackLevel = -1;

		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, "csChargingProfiles"), "ChargingProfileId")) != txProfile.id) &&
				   (json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "stackLevel")) >= txProfile.stackLevel)
				  )
				{
					if((json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "validFrom") != NULL) &&
					   (json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "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, "csChargingProfiles"), "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, "csChargingProfiles"), "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))
							{
								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, "csChargingProfiles"), "chargingProfileId"));
								txProfile.stackLevel = json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "stackLevel"));
								sprintf((char*)txProfile.chargingProfileKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingProfileKind")));
								sprintf((char*)txProfile.chargingSchedule[0].chargingRateUnit, "A");

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

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

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

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

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

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

								if(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "startSchedule") != NULL)
								{
									sprintf((char*)txProfile.chargingSchedule[0].startSchedule, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "startSchedule")));
								}
								else
								{
									sprintf((char*)txProfile.chargingSchedule[0].startSchedule, "%s", ((strstr((char*)ShmOCPP20Data->StatusNotification[(connectorId==0?0:connectorId-1)].connectorStatus, "Charging")==NULL) ? compositeProfile->chargingSchedule[0].startSchedule : ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp));
								}

								if(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "minChargingRate") != NULL)
								{
									txProfile.chargingSchedule[0].minChargingRate = json_object_get_double(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "minChargingRate"));
								}
								else
								{
									txProfile.chargingSchedule[0].minChargingRate = -1;
								}
							}
						}
					}
					else
					{
						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, "csChargingProfiles"), "chargingProfileId"));
						txProfile.stackLevel = json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "stackLevel"));
						sprintf((char*)txProfile.chargingProfileKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingProfileKind")));
						sprintf((char*)txProfile.chargingSchedule[0].chargingRateUnit, "A");

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

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

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

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

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

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

						if(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "startSchedule") != NULL)
						{
							sprintf((char*)txProfile.chargingSchedule[0].startSchedule, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "startSchedule")));
						}
						else
						{
							sprintf((char*)txProfile.chargingSchedule[0].startSchedule, "%s", ((strstr((char*)ShmOCPP20Data->StatusNotification[(connectorId==0?0:connectorId-1)].connectorStatus, "Charging")==NULL) ? compositeProfile->chargingSchedule[0].startSchedule : ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp));
						}

						if(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "minChargingRate") != NULL)
						{
							txProfile.chargingSchedule[0].minChargingRate = json_object_get_double(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "minChargingRate"));
						}
						else
						{
							txProfile.chargingSchedule[0].minChargingRate = -1;
						}
					}
				}
			}
			json_object_put(obj);
		}
		fclose(fp);
/*
		if(txProfile.ChargingProfileId != -1)
		{
			DEBUG_INFO("Profile ID: %d\n", txProfile.ChargingProfileId);
			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[0].StartSchedule);
			DEBUG_INFO("Profile schedule duration: %d\n", txProfile.chargingSchedule[0].Duration);
			DEBUG_INFO("Profile charging rate unit: %s\n", txProfile.chargingSchedule[0].ChargingRateUnit);
			DEBUG_INFO("Profile charging min rate: %f\n", txProfile.chargingSchedule[0].MinChargingRate);

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

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

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

		for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod);idxPeriod++)
		{
			defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod = -1;
			defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].limit = -1;
			defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].numberPhases = 3;
			defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].phaseToUse = 0;
		}
		defaultTxProfile.id = -1;
		defaultTxProfile.stackLevel = -1;

		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, "csChargingProfiles"), "ChargingProfileId")) != defaultTxProfile.id) &&
				   (json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "stackLevel")) >= defaultTxProfile.stackLevel)
				  )
				{
					if((json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "validFrom") != NULL) &&
					   (json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "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, "csChargingProfiles"), "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, "csChargingProfiles"), "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))
							{
								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, "csChargingProfiles"), "chargingProfileId"));
								defaultTxProfile.stackLevel = json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "stackLevel"));
								sprintf((char*)defaultTxProfile.chargingProfileKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingProfileKind")));
								sprintf((char*)defaultTxProfile.chargingSchedule[0].chargingRateUnit, "A");

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

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

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

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

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

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

								if(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "startSchedule") != NULL)
								{
									sprintf((char*)defaultTxProfile.chargingSchedule[0].startSchedule, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "startSchedule")));
								}
								else
								{
									sprintf((char*)defaultTxProfile.chargingSchedule[0].startSchedule, "%s", ((strstr((char*)ShmOCPP20Data->StatusNotification[(connectorId==0?0:connectorId-1)].connectorStatus, "Charging")==NULL) ? compositeProfile->chargingSchedule[0].startSchedule : ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp));
								}

								if(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "minChargingRate") != NULL)
								{
									defaultTxProfile.chargingSchedule[0].minChargingRate = json_object_get_double(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "minChargingRate"));
								}
								else
								{
									defaultTxProfile.chargingSchedule[0].minChargingRate = -1;
								}
							}
						}
					}
					else
					{
						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, "csChargingProfiles"), "chargingProfileId"));
						defaultTxProfile.stackLevel = json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "stackLevel"));
						sprintf((char*)defaultTxProfile.chargingProfileKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingProfileKind")));
						sprintf((char*)defaultTxProfile.chargingSchedule[0].chargingRateUnit, "A");

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

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

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

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

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

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

						if(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "startSchedule") != NULL)
						{
							sprintf((char*)defaultTxProfile.chargingSchedule[0].startSchedule, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "startSchedule")));
						}
						else
						{
							sprintf((char*)defaultTxProfile.chargingSchedule[0].startSchedule, "%s", ((strstr((char*)ShmOCPP20Data->StatusNotification[(connectorId==0?0:connectorId-1)].connectorStatus, "Charging")==NULL) ? compositeProfile->chargingSchedule[0].startSchedule : ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp));
						}

						if(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "minChargingRate") != NULL)
						{
							defaultTxProfile.chargingSchedule[0].minChargingRate = json_object_get_double(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "minChargingRate"));
						}
						else
						{
							defaultTxProfile.chargingSchedule[0].minChargingRate = -1;
						}
					}
				}
			}
			json_object_put(obj);
		}
		fclose(fp);
/*
		if(defaultTxProfile.ChargingProfileId != -1)
		{
			DEBUG_INFO("Profile ID: %d\n", defaultTxProfile.ChargingProfileId);
			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[0].StartSchedule);
			DEBUG_INFO("Profile schedule duration: %d\n", defaultTxProfile.chargingSchedule[0].Duration);
			DEBUG_INFO("Profile charging rate unit: %s\n", defaultTxProfile.chargingSchedule[0].ChargingRateUnit);
			DEBUG_INFO("Profile charging min rate: %f\n", defaultTxProfile.chargingSchedule[0].MinChargingRate);

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

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

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

		for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.chargingSchedule[0].chargingSchedulePeriod);idxPeriod++)
		{
			maxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod = -1;
			maxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].limit = -1;
			maxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].numberPhases = 3;
		}
		maxProfile.id = -1;
		maxProfile.stackLevel = -1;

		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, "csChargingProfiles"), "ChargingProfileId")) != maxProfile.id) &&
				   (json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "stackLevel")) >= maxProfile.stackLevel)
				  )
				{
					if((json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "validFrom") != NULL) &&
					   (json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "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, "csChargingProfiles"), "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, "csChargingProfiles"), "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))
							{
								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, "csChargingProfiles"), "chargingProfileId"));
								maxProfile.stackLevel = json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "stackLevel"));
								sprintf((char*)maxProfile.chargingProfileKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingProfileKind")));
								sprintf((char*)maxProfile.chargingSchedule[0].chargingRateUnit, "A");

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

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

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

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

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

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

								if(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "startSchedule") != NULL)
								{
									sprintf((char*)maxProfile.chargingSchedule[0].startSchedule, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "startSchedule")));
								}
								else
								{
									sprintf((char*)maxProfile.chargingSchedule[0].startSchedule, "%s", ((strstr((char*)ShmOCPP20Data->StatusNotification[(connectorId==0?0:connectorId-1)].connectorStatus, "Charging")==NULL) ? compositeProfile->chargingSchedule[0].startSchedule : ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp));
								}

								if(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "minChargingRate") != NULL)
								{
									maxProfile.chargingSchedule[0].minChargingRate = json_object_get_double(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "minChargingRate"));
								}
								else
								{
									maxProfile.chargingSchedule[0].minChargingRate = -1;
								}
							}
						}
					}
					else
					{
						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, "csChargingProfiles"), "chargingProfileId"));
						maxProfile.stackLevel = json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "stackLevel"));
						sprintf((char*)maxProfile.chargingProfileKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingProfileKind")));
						sprintf((char*)maxProfile.chargingSchedule[0].chargingRateUnit, "A");

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

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

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

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

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

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

						if(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "startSchedule") != NULL)
						{
							sprintf((char*)maxProfile.chargingSchedule[0].startSchedule, "%s", json_object_get_string(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "startSchedule")));
						}
						else
						{
							sprintf((char*)maxProfile.chargingSchedule[0].startSchedule, "%s", ((strstr((char*)ShmOCPP20Data->StatusNotification[(connectorId==0?0:connectorId-1)].connectorStatus, "Charging")==NULL) ? compositeProfile->chargingSchedule[0].startSchedule : ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp));
						}

						if(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "minChargingRate") != NULL)
						{
							maxProfile.chargingSchedule[0].minChargingRate = json_object_get_double(json_object_object_get(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingSchedule"), "minChargingRate"));
						}
						else
						{
							maxProfile.chargingSchedule[0].minChargingRate = -1;
						}
					}
				}
			}
			json_object_put(obj);
		}
		fclose(fp);
/*
		if(maxProfile.ChargingProfileId !=-1)
		{
			DEBUG_INFO("Profile ID: %d\n", maxProfile.ChargingProfileId);
			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[0].StartSchedule);
			DEBUG_INFO("Profile schedule duration: %d\n", maxProfile.chargingSchedule[0].Duration);
			DEBUG_INFO("Profile charging rate unit: %s\n", maxProfile.chargingSchedule[0].ChargingRateUnit);
			DEBUG_INFO("Profile charging min rate: %f\n", maxProfile.chargingSchedule[0].MinChargingRate);

			for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.chargingSchedule[0].ChargingSchedulePeriod);idxPeriod++)
			{
				if(maxProfile.chargingSchedule[0].ChargingSchedulePeriod[idxPeriod].StartPeriod >= 0)
				{
					DEBUG_INFO("Period-%02d startPeriod: %d\n", idxPeriod, maxProfile.chargingSchedule[0].ChargingSchedulePeriod[idxPeriod].StartPeriod);
					DEBUG_INFO("Period-%02d limit: %f\n", idxPeriod, maxProfile.chargingSchedule[0].ChargingSchedulePeriod[idxPeriod].Limit);
					DEBUG_INFO("Period-%02d NumberPhases: %d\n", idxPeriod, maxProfile.chargingSchedule[0].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[0].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[0].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[0].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[0].duration != -1)
			{
				txProfile.chargingSchedule[0].duration = ((txProfile.chargingSchedule[0].duration-getStartStop(txProfile.chargingSchedule[0].startSchedule, compositeProfile->chargingSchedule[0].startSchedule))<0?
														0:
														(txProfile.chargingSchedule[0].duration-getStartStop(txProfile.chargingSchedule[0].startSchedule, compositeProfile->chargingSchedule[0].startSchedule)));
			}

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

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

			for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(txProfile.chargingSchedule[0].chargingSchedulePeriod);idxPeriod++)
			{
				if(txProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod != -1)
				{
					txProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod = (strstr((char*)ShmOCPP20Data->StatusNotification[(connectorId==0?0:connectorId-1)].connectorStatus, "Charging")==NULL)?txProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod:((txProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod-getStartStop(ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp, compositeProfile->chargingSchedule[0].startSchedule))<0?
																																																												0:
																																																											   (txProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod-getStartStop(ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp, compositeProfile->chargingSchedule[0].startSchedule)));

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

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

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

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

						if(idxPeriod > 0)
						{
							if(txProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod-1].startPeriod == txProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod)
							{
								txProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod-1].limit = txProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].limit;
							}
						}
					}
				}
			}
		}
/*
		DEBUG_INFO("txProfile after align.\n");
		DEBUG_INFO("Profile ID: %d\n", txProfile.ChargingProfileId);
		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[0].Duration);
		DEBUG_INFO("Profile charging rate unit: %s\n", txProfile.chargingSchedule[0].ChargingRateUnit);
		DEBUG_INFO("Profile charging min rate: %f\n", txProfile.chargingSchedule[0].MinChargingRate);

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

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

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

					if(defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod < txProfile.chargingSchedule[0].duration)
					{
						defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod += (txProfile.chargingSchedule[0].duration-defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod);
					}

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

			for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod);idxPeriod++)
			{
				if(defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod != -1)
				{
					defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod = (strstr((char*)ShmOCPP20Data->StatusNotification[(connectorId==0?0:connectorId-1)].connectorStatus, "Charging")==NULL)?defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod:((defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod-getStartStop(ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp, compositeProfile->chargingSchedule[0].startSchedule))<0?
																																																												0:
																																																											   (defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod-getStartStop(ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp, compositeProfile->chargingSchedule[0].startSchedule)));

					if(defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod < txProfile.chargingSchedule[0].duration)
					{
						defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod += (txProfile.chargingSchedule[0].duration-defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod);
					}

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

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

						if(defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod < txProfile.chargingSchedule[0].duration)
						{
							defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod += (txProfile.chargingSchedule[0].duration-defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod);
						}

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

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

						if(defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod < txProfile.chargingSchedule[0].duration)
						{
							defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod += (txProfile.chargingSchedule[0].duration-defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod);
						}

						if(idxPeriod > 0)
						{
							if(defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod-1].startPeriod == defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod)
							{
								defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod-1].limit = defaultTxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].limit;
							}
						}
					}
				}
			}
		}
/*
		DEBUG_INFO("defaultTxProfile after align.\n");
		DEBUG_INFO("Profile ID: %d\n", defaultTxProfile.ChargingProfileId);
		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[0].Duration);
		DEBUG_INFO("Profile charging rate unit: %s\n", defaultTxProfile.chargingSchedule[0].ChargingRateUnit);
		DEBUG_INFO("Profile charging min rate: %f\n", defaultTxProfile.chargingSchedule[0].MinChargingRate);

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

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

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

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

			for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.chargingSchedule[0].chargingSchedulePeriod);idxPeriod++)
			{
				if(maxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod != -1)
				{
					maxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod = (strstr((char*)ShmOCPP20Data->StatusNotification[(connectorId==0?0:connectorId-1)].connectorStatus, "Charging")==NULL)?maxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod:((maxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod-getStartStop(ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp, compositeProfile->chargingSchedule[0].startSchedule))<0?
																																																											    0:
																																																											   (maxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod-getStartStop(ShmOCPP20Data->TransactionEvent[(connectorId==0?0:connectorId-1)].timestamp, compositeProfile->chargingSchedule[0].startSchedule)));

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

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

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

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

						if(idxPeriod > 0)
						{
							if(maxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod-1].startPeriod == maxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].startPeriod)
							{
								maxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod-1].limit = maxProfile.chargingSchedule[0].chargingSchedulePeriod[idxPeriod].limit;
							}
						}
					}
				}
			}
		}
/*
		DEBUG_INFO("MaxProfile after align.\n");
		DEBUG_INFO("Profile ID: %d\n", maxProfile.ChargingProfileId);
		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[0].Duration);
		DEBUG_INFO("Profile charging rate unit: %s\n", maxProfile.chargingSchedule[0].ChargingRateUnit);
		DEBUG_INFO("Profile charging min rate: %f\n", maxProfile.chargingSchedule[0].MinChargingRate);

		for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.chargingSchedule[0].ChargingSchedulePeriod);idxPeriod++)
		{
			if(maxProfile.chargingSchedule[0].ChargingSchedulePeriod[idxPeriod].StartPeriod >= 0)
			{
				DEBUG_INFO("Period-%02d startPeriod: %d\n", idxPeriod, maxProfile.chargingSchedule[0].ChargingSchedulePeriod[idxPeriod].StartPeriod);
				DEBUG_INFO("Period-%02d limit: %f\n", idxPeriod, maxProfile.chargingSchedule[0].ChargingSchedulePeriod[idxPeriod].Limit);
				DEBUG_INFO("Period-%02d NumberPhases: %d\n", idxPeriod, maxProfile.chargingSchedule[0].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[0].chargingSchedulePeriod);idx++)
	{
		if(maxProfile.chargingSchedule[0].chargingSchedulePeriod[idx].limit != -1)
			limitMax = idx+1;
	}

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

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

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

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

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

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

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

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

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

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

				if((maxProfile.chargingSchedule[0].duration > compositeProfile->chargingSchedule[0].chargingSchedulePeriod[compositePeriodIdx==0?0:compositePeriodIdx-1].startPeriod))
				{
					tmpPeriod.startPeriod = compositeProfile->chargingSchedule[0].duration;
					tmpPeriod.numberPhases = maxProfile.chargingSchedule[0].chargingSchedulePeriod[idxMaxPeriod].numberPhases;
					tmpPeriod.limit = maxProfile.chargingSchedule[0].chargingSchedulePeriod[idxMaxPeriod].limit;
				}

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

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

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

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

	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************************************************/
	//offline MeterValue Interval
	TempMeterValueInterval = 0;


	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()
{
	if(InitShareMemory() == FAIL)
	{
		DEBUG_ERROR("InitShareMemory NG\n");

		if(ShmStatusCodeData!=NULL)
		{
			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=1;
		}
		sleep(5);
		return FAIL;
	}
	return PASS;
}

//---------------------common routine---------------------------//
int isOFFline(void)
{
	if(ShmSysConfigAndInfo->SysInfo.InternetConn == 0)
	{
		if(TempMeterValueInterval >=  2  )
		{
			TempMeterValueInterval = 0;
			return TRUE;
		}
		else
		{
			TempMeterValueInterval = TempMeterValueInterval+ 1;
			return FALSE;
		}
	}
	else
	{
		return FALSE;
	}
}

void checkNetworkProfile(void)
{
	uint8_t isGetProfile = FALSE;

	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, ShmSysConfigAndInfo->SysConfig.OcppServerURL, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.OcppServerURL));
					memcpy(ShmSysConfigAndInfo->SysConfig.OcppServerURL, ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.ocppCsmsUrl, ARRAY_SIZE(ShmOCPP20Data->NetworkConnectionProfile[idx].connectionData.ocppCsmsUrl));

					isGetProfile = TRUE;
					ShmOCPP20Data->NetworkConnectionProfile[idx].retryCount++;

					break;
				}
			}
		}
	}
	json_object_put(priority);


	if(!isGetProfile && (strlen((char*)ShmOCPP20Data->OcppServerURL) > 0))
	{
		memcpy(ShmSysConfigAndInfo->SysConfig.OcppServerURL, ShmOCPP20Data->OcppServerURL, ARRAY_SIZE(ShmOCPP20Data->OcppServerURL));
	}

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

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

	//===============================
	// EVSE operation check
	//===============================
	//===============================
	// Heartbeat check
	//===============================
	if((difftime(time((time_t*)NULL), clientTime.Heartbeat) < 0) || (HeartBeatWaitTime <= 0))
	{
		clientTime.Heartbeat = time((time_t*)NULL);

		if(server_sign == TRUE)
		{
			HeartBeatWaitTime = ShmOCPP20Data->BootNotification.Response_interval;
		}
		else
		{
			HeartBeatWaitTime = atoi((char*)ShmOCPP20Data->ControllerComponentVariable[OCPPCommCtrlr_HeartbeatInterval].variableAttribute[0].value);
		}
	}

	if((server_sign == TRUE) && (difftime(time((time_t*)NULL), clientTime.Heartbeat) >= (HeartBeatWaitTime + HeartBeatWithNOResponse)))
	{
		//parameter for test
		sendHeartbeatRequest(0);
	    //==============================================
		// Reset Waiting Time
		//==============================================
		HeartBeatWithNOResponse = HeartBeatWithNOResponse + 1;
	}

	//===============================
	// CSU Trigger Reset Conf
	//===============================
	if(isWebsocketSendable && (ShmOCPP20Data->MsMsg.bits.ResetConf == ON))
	{
		sendResetConfirmation((char *)ShmOCPP20Data->Reset.guid);
	}

	//===============================
	// 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);
	}

	//===============================
	// Each connector operation check
	//===============================
	for(int gun_index=0;gun_index < gunTotalNumber ;gun_index++)
	{
		//==========================================
		// 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;
		}

		//===============================
		// CSU Trigger Smart Charging Profilw
		//===============================
		if(ShmOCPP20Data->CSUMsg.bits[gun_index].ChargingProfileReq == ON)
		{
			checkCompositeSchedule(gun_index+1, 86400, &ShmOCPP20Data->SmartChargingProfile[gun_index]);
			ShmOCPP20Data->CSUMsg.bits[gun_index].ChargingProfileReq = OFF;
		}

		//==============================================
		// Charger start transaction
		//==============================================
		/*
		if((ShmOCPP20Data->CpMsg.bits[gun_index].StartTransactionReq == ON))
		{
			ShmOCPP20Data->CpMsg.bits[gun_index].StartTransactionReq = OFF;
			sendStartTransactionRequest(gun_index);
			clientTime.StartTransaction = time((time_t*)NULL);
			clientTime.MeterValues[gun_index] = time((time_t*)NULL);
		}*/

		//==============================================
		// Charger stop transaction
		//==============================================
		/*
	   	if(((ShmOCPP20Data->CpMsg.bits[gun_index].StopTransactionReq == ON)))
		{
			ShmOCPP20Data->CpMsg.bits[gun_index].StopTransactionReq =OFF;
			sendStopTransactionRequest(gun_index);
			clientTime.StopTransaction = time((time_t*)NULL);
		}*/

		//==============================================
		// Charger status notification & Transaction event report
		//==============================================
		//--- Check Mode Change ---//
		// J: CHAdeMO  U: CCS1 combo  E: CCS2 combo  G: GBT DCcc
		if(gunType[gun_index] == 'J')
		{

			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((SystemInitial > 0) || (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(SystemInitial == 0)
							cpinitateMsg.bits[gun_index].TransactionEventReq = ON;
					}

					if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex) && (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_COMPLETE)) // complete
					{
						sprintf(filenmae,"/Storage/OCPP/TxProfile_%d.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);
						}

					}

			#if 1 // for TempStopTransaction
					if((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_IDLE) && (ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq == OFF))
					{
						checkTempStopTransaction(gun_index);
					}
			#endif
				}
			}
		}
		else if((gunType[gun_index] == 'U')||(gunType[gun_index] == 'E'))
		{

			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((SystemInitial > 0) || (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(SystemInitial == 0)
							cpinitateMsg.bits[gun_index].TransactionEventReq = ON;
					}

					if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex) && (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_COMPLETE)) // complete
					{
						sprintf(filenmae,"/Storage/OCPP/TxProfile_%d.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);
						}
					}

			#if 1 // for TempStopTransaction
					if((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_IDLE) && (ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq == OFF))
					{
						checkTempStopTransaction(gun_index);
					}
			#endif
				}
			}
		}
		else if(gunType[gun_index] == 'G')
		{

			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((SystemInitial > 0) || (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(SystemInitial == 0)
							cpinitateMsg.bits[gun_index].TransactionEventReq = ON;
					}

					if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex) && (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_COMPLETE)) // complete
					{
						sprintf(filenmae,"/Storage/OCPP/TxProfile_%d.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);
						}
					}

				#if 1 // for TempStopTransaction
					if((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_IDLE) && (ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq == OFF))
					{
						checkTempStopTransaction(gun_index);
					}
				#endif
				}
			}

		}
		else if(gunType[gun_index] == 'O')
		{
			tempIndex = gun_index;

			for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
			{
				if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
				{
					if((SystemInitial > 0) || (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(SystemInitial == 0)
							cpinitateMsg.bits[gun_index].TransactionEventReq = ON;
					}

					if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex) && (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_COMPLETE)) // complete
					{
						sprintf(filenmae,"/Storage/OCPP/TxProfile_%d.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);
						}
					}

				#if 1 // for TempStopTransaction
					if((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((SystemInitial > 0) || (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;
						cpinitateMsg.bits[gun_index].StatusNotificationReq = ON;

						if(SystemInitial == 0)
							cpinitateMsg.bits[gun_index].TransactionEventReq = ON;
					}

					if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_COMPLETE)) // complete
					{
						sprintf(filenmae,"/Storage/OCPP/TxProfile_%d.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);
						}
					}

			#if 1 // for TempStopTransaction
					if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_IDLE) && (ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq == OFF))
					{
						checkTempStopTransaction(gun_index);
					}
			#endif
				}
			}// END

		}

		if(isWebsocketSendable &&
		   (cpinitateMsg.bits[gun_index].StatusNotificationReq == ON) &&
		   ((time((time_t*)NULL)-clientTime.StatusNotification[gun_index]) > 10) )
		{
			if(SystemInitial > 0)
				SystemInitial -= 1;

			sendStatusNotificationRequest(gun_index);
			clientTime.StatusNotification[gun_index] = time((time_t*)NULL);
		}

		if(isWebsocketSendable && (server_sign == TRUE) && (cpinitateMsg.bits[gun_index].TransactionEventReq == ON))
		{
			sendTransactionEventRequest(gun_index);
			cpinitateMsg.bits[gun_index].TransactionEventReq = OFF;
		}

		//==============================================
		// Meter report
		//==============================================
		if(isWebsocketSendable && (server_sign == TRUE) && cpinitateMsg.bits[gun_index].TriggerMeterValueReq)
		{
			sendMeterValuesRequest(gun_index, ReadingContextEnumType_Trigger);
			cpinitateMsg.bits[gun_index].TriggerMeterValueReq = OFF;
		}

		// ClockAlign MeterValue
		if(isWebsocketSendable && (server_sign == TRUE) && ((atoi((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Interval].variableAttribute[0].value) > 0)?((getTimePassSinceToday()%(atoi((char*)ShmOCPP20Data->ControllerComponentVariable[AlignedDataCtrlr_Interval].variableAttribute[0].value)))==0):FALSE))
		{
			//check Transaction active
			if(gunType[gun_index] == 'J')
			{
				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].ClockAlignMeterReq = ON;
						}
					}
				}// End for CHAdeMO
			}
			else if((gunType[gun_index] == 'U')||(gunType[gun_index] == 'E'))
			{
				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].ClockAlignMeterReq = ON;
						}
					}
				} // End for CCS
			}
			else if(gunType[gun_index] == 'G')
			{
				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] == 'O')
			{
				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].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)
					{
						if(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != SYS_MODE_CHARGING)
						{
							cpinitateMsg.bits[gun_index].ClockAlignMeterReq = ON;
						}
					}
				}//End for AC
			}

			if(cpinitateMsg.bits[gun_index].ClockAlignMeterReq == ON)
			{
				sendMeterValuesRequest(gun_index, ReadingContextEnumType_Sample_Clock);
				cpinitateMsg.bits[gun_index].ClockAlignMeterReq = OFF;
			}
		}

		// Sample period MeterValue
		if(((time((time_t*)NULL) - clientTime.MeterValues[gun_index]) > (atoi((const char *)ShmOCPP20Data->ControllerComponentVariable[SampledDataCtrlr_TxUpdatedInterval].variableAttribute[0].value)- 1)))
		{
			//check Transaction active
			if(gunType[gun_index] == 'J')
			{
				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] == 'U')||(gunType[gun_index] == 'E'))
			{
				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] == 'G')
			{
				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] == 'O')
			{
				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)
			{
				sendMeterValuesRequest(gun_index, ReadingContextEnumType_Sample_Periodic);
				storeTempStopTransaction(gun_index);
				cpinitateMsg.bits[gun_index].SampleMeterReq = OFF;
			}

			clientTime.MeterValues[gun_index] = time((time_t*)NULL);
		}

		//==============================================
		// Check Connector reserved
		//==============================================
		//===============================
		// Check if Reserve is expired
		//===============================
		if((server_sign == TRUE) && (ShmOCPP20Data->ReserveNow[gun_index].expiryDateTime[0] != 0) )
		{
			double diff_t;
			struct tm tp;
			// current time
			time_t t = time(NULL);
			strptime((char *)ShmOCPP20Data->ReserveNow[gun_index].expiryDateTime, "%Y-%m-%dT%H:%M:%S", &tp);
			tp.tm_isdst = -1;
			time_t utc = mktime(&tp);
			diff_t = difftime(utc, t);

			if(diff_t <= 0)
			{
				DEBUG_INFO("reserve expired.\n");
				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 trigger CancelReservationConf
		//==========================================
		if(isWebsocketSendable && (server_sign == TRUE) && (ShmOCPP20Data->CsMsg.bits[gun_index].CancelReservationConf == ON))
		{
			sendCancelReservationConfirmation((char *)ShmOCPP20Data->CancelReservation[gun_index].guid, 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);
			ShmOCPP20Data->CsMsg.bits[gun_index].UnlockConnectorConf = OFF;
		}

		//==========================================
		// csu trigger ReserveNowConf
		//==========================================
		if(isWebsocketSendable && (server_sign == TRUE) && (ShmOCPP20Data->CsMsg.bits[gun_index].ReserveNowConf == ON))
		{
			sendReserveNowConfirmation((char *)ShmOCPP20Data->ReserveNow[gun_index].guid, gun_index);
			ShmOCPP20Data->CsMsg.bits[gun_index].ReserveNowConf = OFF;
		}
	}
}

//==========================================
// 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("offline Local Authorization Fail !!!!, Card %s is blank!!!!\n", idTagQuery.idToken.idToken);
			}

			if(strcmp((char*)idTagQuery.idTokenInfo.status,AuthorizationStatusEnumTypeStr[AuthorizationStatusEnumType_Accepted]) != 0)
			{
				DEBUG_INFO("offline Local Authorization Fail !!!!, Card %s is not Accepted!!!!\n", idTagQuery.idToken.idToken);
			}

			DEBUG_INFO("offline 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("offline 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;
		}
	}

	//initialize  struct Authorize
	memset(&(ShmOCPP20Data->Authorize), 0 , sizeof(struct StructAuthorize));

	//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();

    // 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();

	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;
	}

	return result;
}

int sendDataTransferRequest(int gun_index)
{
	mtrace();
	char message[1000]={0};
	char guid[37]={0};
	char tempdata[65]={0};
	int result = FAIL;

	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);
	}
	else if(strcmp(status,FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_InstallRebooting])==0)
	{
		FirmwareStatusNotificationStatus = FirmwareStatusEnumType_InstallRebooting;
		DB_updateBootType(BootReasonEnumType_FirmwareUpdate);
	}
	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();

	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();

	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};

	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 *meterValue = json_object_new_object();
	json_object *sampledValues = json_object_new_array();
	json_object *sampledValue = json_object_new_object();
	json_object *unitOfMeasure = json_object_new_object();

	DEBUG_INFO("sendMeterValuesRequest ...\n");

	memset(queuedata, 0, ARRAY_SIZE(queuedata));
	//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);
	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************************************************/
	//J: CHAdeMO  U: CCS1 combo  E: CCS2 combo  G: GBT DC
	if(gunType[gun_index] == 'J')
	{
		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 = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PresentChargingCurrent;
			}
		}

		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[0].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
	}
	else if((gunType[gun_index] == 'U')||(gunType[gun_index] == 'E'))
	{
		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 = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PresentChargingCurrent;
			}
		}

		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[0].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
	}
	else if(gunType[gun_index] == 'G')
	{
		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 = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PresentChargingCurrent;
			}
		}

		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[0].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
	}
	else if(gunType[gun_index] == 'O')
	{
		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 = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PresentChargingCurrent;
			}
		}

		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 = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PresentChargingCurrent;
			}
		}

		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 ************************************************/
	//J: CHAdeMO  U: CCS1 combo  E: CCS2 combo  G: GBT DC

	if(gunType[gun_index] == 'J')
	{
			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 = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PowerConsumption;
				}
			}

			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[1].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
	}
	else if((gunType[gun_index] == 'U')||(gunType[gun_index] == 'E'))
	{
			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 = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PowerConsumption;
				}
			}

			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[1].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
	}
	else if(gunType[gun_index] == 'G')
	{
			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 = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PowerConsumption;
				}
			}

			strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[1].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
	}
	else if(gunType[gun_index] == 'O')
	{

			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 = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PowerConsumption;
				}
			}

			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 = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PowerConsumption;
				}
			}

			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*********************************************/
	//J: CHAdeMO  U: CCS1 combo  E: CCS2 combo  G: GBT DC

	if(gunType[gun_index] == 'J')
	{
		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 = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PresentChargedEnergy;
			}
		} // 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] == 'U')||(gunType[gun_index] == 'E'))
	{
		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 = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PresentChargedEnergy;
			}
		} // END OF CCS_QUANTITY

		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[2].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
	}
	else if(gunType[gun_index] == 'G')
	{
		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 = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PresentChargedEnergy;
			}
		} // END OF GB_QUANTITY

		 strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[2].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
	}
	else if(gunType[gun_index] == 'O')
	{
		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 = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PresentChargedEnergy;
			}
		}

		 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 = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PresentChargedEnergy;
			}
		 }

		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************************************************/
	//J : CHAdeMO   U: CCS1 combo   E: CCS2 combo   G: GBT DC
	if(gunType[gun_index] == 'J')
	{
		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 = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PresentChargingPower;
			}
		} // END OF FOR

		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[3].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
	}
	else if((gunType[gun_index] == 'U')||(gunType[gun_index] == 'E'))
	{
		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 = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PresentChargingPower;
			}
		}

		 strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[3].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
	}
	else if(gunType[gun_index] == 'G')
	{
		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 = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PresentChargingPower;
			}
		}

		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[3].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
	}
	else if(gunType[gun_index] == 'O')
	{
		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 = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PresentChargingPower;
			}
		}

		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 = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PresentChargingPower;
			}
		}

		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******************************************************/
	//J : CHAdeMO   U: CCS1 combo   E: CCS2 combo   G: GBT DC
	if(gunType[gun_index] == 'J')
	{
		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 = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PresentChargingVoltage;
			}
		}

		 strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[4].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
	}
	else if((gunType[gun_index] == 'U')||(gunType[gun_index] == 'E'))
	{
		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 = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PresentChargingVoltage;
			}
		}

		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[4].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
	}
	else if(gunType[gun_index] == 'G')
	{
		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 = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PresentChargingVoltage;
			}
		}

		strcpy((char *)ShmOCPP20Data->MeterValues[gun_index].meterValue[0].sampledValue[4].phase, PhaseEnumTypeStr[PhaseEnumType_L3_N]);
	}
	else if(gunType[gun_index] == 'O')
	{
		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 = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.PresentChargingVoltage;
			}
		}

		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 = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PresentChargingVoltage;
			}
		}

		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((gunType[gun_index] == 'J')||(gunType[gun_index] == 'U')||(gunType[gun_index] == 'E')||(gunType[gun_index] == 'G'))
	{
		//idx_sample=5;
		//sampledValue = NULL;

		if(ShmSysConfigAndInfo->SysConfig.ModelName[8] != '0')
		{
			tempIndex = ((gun_index==2) ? 1: 0);
		}
		else
		{
			tempIndex = gun_index;
		}

		if(gunType[gun_index] == 'J')
		{
			//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] == 'U')||(gunType[gun_index] == 'E'))
		{
			//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] == 'G')
		{
			//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] == 'O')
		{
			//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************************************************/
	// Only for AC 3 phase
	if(('1' <= gunType[gun_index]) && (gunType[gun_index] <= '9') && ((ShmSysConfigAndInfo->SysConfig.ModelName[2] == 'Y') || (ShmSysConfigAndInfo->SysConfig.ModelName[2] == 'W')))
	{
		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 = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PresentChargingCurrentL2;
			}
		}
		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************************************************/
	// Only for AC 3 phase
	if(('1' <= gunType[gun_index]) && (gunType[gun_index] <= '9') && ((ShmSysConfigAndInfo->SysConfig.ModelName[2] == 'Y') || (ShmSysConfigAndInfo->SysConfig.ModelName[2] == 'W')))
	{
		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 = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PresentChargingCurrentL3;
			}
		}
		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(('1' <= gunType[gun_index]) && (gunType[gun_index] <= '9') && ((ShmSysConfigAndInfo->SysConfig.ModelName[2] == 'Y') || (ShmSysConfigAndInfo->SysConfig.ModelName[2] == 'W')))
	{
		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 = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PresentChargingVoltageL2;
			}
		}

		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(('1' <= gunType[gun_index]) && (gunType[gun_index] <= '9') && ((ShmSysConfigAndInfo->SysConfig.ModelName[2] == 'Y') || (ShmSysConfigAndInfo->SysConfig.ModelName[2] == 'W')))
	{
		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 = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PresentChargingVoltageL3;
			}
		}

		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;

	// Message create ====================================================================================================
	random_uuid(guid);

	uint8_t idxMeter = 0;
	while(strlen((char*)ShmOCPP20Data->MeterValues[gun_index].meterValue[idxMeter].timestamp) > 0)
	{
		for(int idxSample=0;idxSample<ARRAY_SIZE(ShmOCPP20Data->MeterValues[gun_index].meterValue[idxMeter].sampledValue);idxSample++)
		{
			if(ShmOCPP20Data->MeterValues[gun_index].meterValue[idxMeter].sampledValue[idxSample].value > 0)
			{
				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_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,[%d,\"%s\",\"MeterValues\",%s]"
					,gun_index + 1
					,MESSAGE_TYPE_CALL
					,guid
					,json_object_to_json_string_ext(MeterValueReq, JSON_C_TO_STRING_PLAIN));

	json_object_put(MeterValueReq);
	// 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();

	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();

	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();

	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();

	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();

	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();

	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();

	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();

	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(reportData, "variableCharacteristics",variableCharacteristics);

			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);
				}
			}
			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_Send(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();

	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();

	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();

	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;
	}
	return result;
}

int sendSecurityEventNotificationRequest()
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	char guid[37]={0};
	char tempdata[128]={0};
	json_object *SecurityEventNotification = json_object_new_object();

	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));
	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()
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	char guid[37]={0};
	char tempdata[128]={0};
	json_object *SignCertificate = json_object_new_object();

	json_object_object_add(SignCertificate, "csr", json_object_new_string((char*)ShmOCPP20Data->SignCertificate.csr));
	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;

	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] == 'J')
	{
		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
					}
				}
				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_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] == 'U')||(gunType[gun_index] == 'E'))
	{
		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
					}
				}
				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_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] == 'G')
	{
		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
					}
				}
				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_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] == 'O')
	{
		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
					}
				}
				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_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
					}
				}
				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_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
	}
	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))
	{
		LWS_Send(message);

		sprintf(tempdata, "StatusNotification,%d", (gun_index));

		if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
		{
			result = PASS;
		}
	}
	else
	{
		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();

	if(gunType[gun_index] == 'J')
	{
		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[index].timestamp);

				if((ShmOCPP20Data->TransactionEvent[index].seqNo + 1) < INT_MAX)
					ShmOCPP20Data->TransactionEvent[index].seqNo++;
				else
					ShmOCPP20Data->TransactionEvent[index].seqNo = 0;

				ShmOCPP20Data->TransactionEvent[index].offline = (!ShmOCPP20Data->OcppConnStatus?TRUE:FALSE);

				ShmOCPP20Data->TransactionEvent[index].evse.id = 0;
				ShmOCPP20Data->TransactionEvent[index].evse.connectorId = (gun_index + 1);

				if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_IDLE)//S_IDLE
				{
					memset(&ShmOCPP20Data->TransactionEvent[index].transactionInfo, 0x00, sizeof(struct TransactionType));
					memset(&ShmOCPP20Data->TransactionEvent[index].idToken, 0x00, sizeof(struct IdTokenType));
					memset(&ShmOCPP20Data->TransactionEvent[index].meterValue, 0x00, sizeof(struct MeterValueType));

					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Idle]);

					if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ConnectorPlugIn == ON) // //0: unplug, 1: Plug-in
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_CablePluggedIn]);
					}
					else
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_EVCommunicationLost]);
					}
				}
				else if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_AUTHORIZING)//S_IDLE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Idle]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[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
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_EVConnected]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_CHARGING) //S_CHARGING
				{
					if(strlen((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.transactionId) == 0)
						random_uuid((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.transactionId);

					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].idToken.idToken, "%s", ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].StartUserId);

					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_COMPLETE) //S_COMPLETE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Ended]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_TERMINATING) // S_TERMINATING   ---> SuspendedEV
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEV]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[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[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[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[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_RESERVATION) //    ---> Reserved
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);
				}
			} //end of the same index

		}//end of for CHAdeMO_QUANTITY

	}
	else if((gunType[gun_index] == 'U')||(gunType[gun_index] == 'E'))
	{
		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[index].timestamp);

				if((ShmOCPP20Data->TransactionEvent[index].seqNo + 1) < INT_MAX)
					ShmOCPP20Data->TransactionEvent[index].seqNo++;
				else
					ShmOCPP20Data->TransactionEvent[index].seqNo = 0;

				ShmOCPP20Data->TransactionEvent[index].offline = (!ShmOCPP20Data->OcppConnStatus?TRUE:FALSE);

				ShmOCPP20Data->TransactionEvent[index].evse.id = 0;
				ShmOCPP20Data->TransactionEvent[index].evse.connectorId = (gun_index + 1);

				if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_IDLE) //S_IDLE
				{
					memset(&ShmOCPP20Data->TransactionEvent[index].transactionInfo, 0x00, sizeof(struct TransactionType));
					memset(&ShmOCPP20Data->TransactionEvent[index].idToken, 0x00, sizeof(struct IdTokenType));
					memset(&ShmOCPP20Data->TransactionEvent[index].meterValue, 0x00, sizeof(struct MeterValueType));

					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Idle]);

					if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ConnectorPlugIn == ON) //0: unplug, 1: Plug-in
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_CablePluggedIn]);
					}
					else
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_EVCommunicationLost]);
					}
				}
				else if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_AUTHORIZING)//S_IDLE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Idle]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[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
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_EVConnected]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_CHARGING) //S_CHARGING
				{
					if(strlen((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.transactionId) == 0)
						random_uuid((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.transactionId);

					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].idToken.idToken, "%s", ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].StartUserId);

					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_COMPLETE) //S_COMPLETE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Ended]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_TERMINATING) // S_TERMINATING   ---> SuspendedEV
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEV]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[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[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[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[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_RESERVATION) //    ---> Reserved
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);
				}
			} //end of the same index

		} // end of for CCS_QUANTITY
	}
	else if(gunType[gun_index] == 'G')
	{
		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[index].timestamp);

				if((ShmOCPP20Data->TransactionEvent[index].seqNo + 1) < INT_MAX)
					ShmOCPP20Data->TransactionEvent[index].seqNo++;
				else
					ShmOCPP20Data->TransactionEvent[index].seqNo = 0;

				ShmOCPP20Data->TransactionEvent[index].offline = (!ShmOCPP20Data->OcppConnStatus?TRUE:FALSE);

				ShmOCPP20Data->TransactionEvent[index].evse.id = 0;
				ShmOCPP20Data->TransactionEvent[index].evse.connectorId = (gun_index + 1);

				if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_IDLE) //S_IDLE
				{
					memset(&ShmOCPP20Data->TransactionEvent[index].transactionInfo, 0x00, sizeof(struct TransactionType));
					memset(&ShmOCPP20Data->TransactionEvent[index].idToken, 0x00, sizeof(struct IdTokenType));
					memset(&ShmOCPP20Data->TransactionEvent[index].meterValue, 0x00, sizeof(struct MeterValueType));

					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Idle]);

					if(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ConnectorPlugIn == ON) //0: unplug, 1: Plug-in
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_CablePluggedIn]);
					}
					else
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_EVCommunicationLost]);
					}
				}
				else if(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_AUTHORIZING)//S_IDLE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Idle]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[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
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_EVConnected]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_CHARGING) //S_CHARGING
				{
					if(strlen((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.transactionId) == 0)
						random_uuid((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.transactionId);

					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].idToken.idToken, "%s", ShmSysConfigAndInfo->SysInfo.GbChargingData[index].StartUserId);

					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_COMPLETE) //S_COMPLETE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Ended]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_TERMINATING) // S_TERMINATING   ---> SuspendedEV
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEV]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[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[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[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[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_RESERVATION) //    ---> Reserved
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);
				}
			} //end of the same index

		} // end of for GB_QUANTITY
	}
	else if(gunType[gun_index] == 'O')
	{
		tempIndex = gun_index;

		for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
		{
			if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
			{
				getNowDatetime(ShmOCPP20Data->TransactionEvent[index].timestamp);

				if((ShmOCPP20Data->TransactionEvent[index].seqNo + 1) < INT_MAX)
					ShmOCPP20Data->TransactionEvent[index].seqNo++;
				else
					ShmOCPP20Data->TransactionEvent[index].seqNo = 0;

				ShmOCPP20Data->TransactionEvent[index].offline = (!ShmOCPP20Data->OcppConnStatus?TRUE:FALSE);

				ShmOCPP20Data->TransactionEvent[index].evse.id = 0;
				ShmOCPP20Data->TransactionEvent[index].evse.connectorId = (gun_index + 1);

				if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_IDLE) //S_IDLE
				{
					memset(&ShmOCPP20Data->TransactionEvent[index].transactionInfo, 0x00, sizeof(struct TransactionType));
					memset(&ShmOCPP20Data->TransactionEvent[index].idToken, 0x00, sizeof(struct IdTokenType));
					memset(&ShmOCPP20Data->TransactionEvent[index].meterValue, 0x00, sizeof(struct MeterValueType));

					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Idle]);

					if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.ConnectorPlugIn == ON) // //0: unplug, 1: Plug-in
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_CablePluggedIn]);
					}
					else
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_EVCommunicationLost]);
					}
				}
				else if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_AUTHORIZING)//S_IDLE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Idle]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[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
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_EVConnected]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_CHARGING) //S_CHARGING
				{
					if(strlen((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.transactionId) == 0)
						random_uuid((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.transactionId);

					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].idToken.idToken, "%s", ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.StartUserId);

					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_COMPLETE) //S_COMPLETE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Ended]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_TERMINATING) // S_TERMINATING   ---> SuspendedEV
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEV]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[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[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[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[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_RESERVATION) //    ---> Reserved
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[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[index].timestamp);

				if((ShmOCPP20Data->TransactionEvent[index].seqNo + 1) < INT_MAX)
					ShmOCPP20Data->TransactionEvent[index].seqNo++;
				else
					ShmOCPP20Data->TransactionEvent[index].seqNo = 0;

				ShmOCPP20Data->TransactionEvent[index].offline = (!ShmOCPP20Data->OcppConnStatus?TRUE:FALSE);

				ShmOCPP20Data->TransactionEvent[index].evse.id = 0;
				ShmOCPP20Data->TransactionEvent[index].evse.connectorId = (gun_index + 1);

				if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_IDLE) //SYS_MODE_IDLE
				{
					memset(&ShmOCPP20Data->TransactionEvent[index].transactionInfo, 0x00, sizeof(struct TransactionType));
					memset(&ShmOCPP20Data->TransactionEvent[index].idToken, 0x00, sizeof(struct IdTokenType));
					memset(&ShmOCPP20Data->TransactionEvent[index].meterValue, 0x00, sizeof(struct MeterValueType));

					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[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[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_CablePluggedIn]);
					}
					else
					{
						sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_EVCommunicationLost]);
					}
				}
				else if(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_AUTHORIZING)//S_IDLE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Idle]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[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
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_EVConnected]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_CHARGING) //S_CHARGING
				{
					if(strlen((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.transactionId) == 0)
						random_uuid((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.transactionId);

					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].idToken.idToken, "%s", ShmSysConfigAndInfo->SysInfo.AcChargingData[index].StartUserId);

					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_COMPLETE) //S_COMPLETE
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Ended]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_Charging]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_ChargingStateChanged]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_TERMINATING) // S_TERMINATING   ---> SuspendedEV
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEV]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[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[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[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[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Updated]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].triggerReason, "%s", TriggerReasonEnumTypeStr[TriggerReasonEnumType_AbnormalCondition]);
				}
				else if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_RESERVATION) //    ---> Reserved
				{
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].eventType, "%s", TransactionEventEnumTypeStr[TransactionEventEnumType_Started]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[index].transactionInfo.chargingState, "%s", ChargingStateEnumTypeStr[ChargingStateEnumType_SuspendedEVSE]);
					sprintf((char*)ShmOCPP20Data->TransactionEvent[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)
		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)
				{
					json_object *sampledValue = json_object_new_object();
					json_object *unitOfMeasure = json_object_new_object();

					json_object_object_add(sampledValue, "value", json_object_new_double(ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].value));
					json_object_object_add(sampledValue, "context", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].context));
					json_object_object_add(sampledValue, "measurand", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].measurand));
					json_object_object_add(sampledValue, "phase", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].phase));
					json_object_object_add(sampledValue, "location", json_object_new_string((char*)ShmOCPP20Data->TransactionEvent[gun_index].meterValue[idxMeter].sampledValue[idxSample].location));

					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);
	LWS_Send(message);

	sprintf(tempdata, "TransactionEvent,%d", gun_index);
	if(hashmap_operation(HASH_OP_ADD, guid, tempdata) == PASS)
	{
		result = PASS;
	}
	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[0].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();

	DEBUG_INFO("sendCertificateSignedConfirmation...\n");

	json_object_object_add(CertificateSigned, "status", json_object_new_string((char*)ShmOCPP20Data->CertificateSigned.Response_status));

	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;
	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(chargingSchedule, "startSchedule", 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);
		}
	}
	else
	{
		if(strlen((char*)ShmOCPP20Data->GetCompositeSchedule[CompositeScheduleIndex].Response_schedule.chargingSchedule.startSchedule))
			json_object_object_add(chargingSchedule, "startSchedule", 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();

		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));
		json_object_object_add(variableResult, "attributeValue", json_object_new_string((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeStatus));

		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, "component", evse);
		json_object_object_add(component, "name", json_object_new_string((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].component.name));
		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));
		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 , "setVariableResult", 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));
	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;

	return result;
}

int sendResetConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *Reset = json_object_new_object();

	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);
	}
	else if(strcmp((char*)ShmOCPP20Data->Reset.Response_status, ResetStatusEnumTypeStr[ResetStatusEnumType_Scheduled]) == 0)
	{
		DB_updateBootType(BootReasonEnumType_ScheduledReset);
	}

	result = TRUE;

	return result;
}

int sendSendLocalListConfirmation(char *uuid)
{
	mtrace();
	int result = FAIL;
	char message[4096]={0};
	json_object *SendLocalList = json_object_new_object();

	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 sendSetDisplayMessageConfirmation(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, "component", 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, "component", 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;

	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");

	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;
}

//==========================================
// 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] == 'J')
				{
					gunNO = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index + 1;
				}
				else
				{
					gunNO = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index;
				}

				ShmOCPP20Data->CsMsg.bits[gunNO].CancelReservationReq = 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] == 'U') || (gunType[2] == 'E'))
				{
					gunNO = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index + 1;
				}
				else
				{
					gunNO = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index;
				}

				ShmOCPP20Data->CsMsg.bits[gunNO].CancelReservationReq = 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] == 'G')
				{
					gunNO = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index + 1;
				}
				else
				{
					gunNO = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index;
				}

				ShmOCPP20Data->CsMsg.bits[gunNO].CancelReservationReq = 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;
				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
		if(json_object_array_length(json_object_object_get(CertificateSigned, "certificate")) <= ARRAY_SIZE(ShmOCPP20Data->CertificateSigned.certificate))
		{
			for(int idx=0;idx<json_object_array_length(json_object_object_get(CertificateSigned, "certificate"));idx++)
			{
				sprintf((char*)ShmOCPP20Data->CertificateSigned.certificate[idx], "%s", json_object_get_string(json_object_array_get_idx(json_object_object_get(CertificateSigned, "certificateType"), idx)));

				/*
				 * TODO:
				 * 	1. Certificate install response
				 */
			}
		}

		// 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")));
		}

		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] == 'J')&&(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] == 'U')||(gunType[i] == 'E'))&&(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] == 'G')&&(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 < AC_QUANTITY; index++)
					{
						if (((gunType[i] > '0')&&(gunType[i] <= '9'))&&(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] == 'J'))
			{
				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] == 'U')||(gunType[gunIndex - 1] == 'E')))
			{
				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] == 'G'))
			{
				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 < AC_QUANTITY; index++)
		{
			if ((gunIndex > 0)&&((gunType[gunIndex-1] > '0')&&(gunType[gunIndex-1] <= '9')))
			{
				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] == 'J' )&&(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == i)&&(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_FAULT))  //S_FAULT   //(((gunIndex  == 0)|| ((gunIndex > 0)&&(gunType[gunIndex-1] == 'J')) ) &&(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] == 'U')||(gunType[i] == 'E'))&&(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] == 'G')&&(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == i)&&(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_FAULT)) //S_FAULT  //(((gunIndex  == 0)|| ((gunIndex > 0)&&(gunType[gunIndex-1] == 'G')))&&(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 < AC_QUANTITY; index++)
					{
						if (((gunType[i] > '0')&&(gunType[i] <= '9')) &&(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] > '0')&&(gunType[i] <= '9')) &&(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] == 'J') ) &&(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] == 'U')||(gunType[gunIndex - 1] == 'E'))) )&&(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] == 'G'))&&(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 < AC_QUANTITY; index++)
		{
			if (((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_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));

	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);
    }

    /*
     * TODO:
     * 1. Clear cache from sqlite db
     */
    if(1)
    {
    	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);

	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, ChargePointMaxProfile_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, ChargePointMaxProfile_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.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.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.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.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_0.json exit
		if((access("/Storage/OCPP/TxDefaultProfile_0.json",F_OK))!=-1)
		{
			strcpy(chargingProfiles[i], "/Storage/OCPP/TxDefaultProfile_0.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.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.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, "chargingProfileId")!= NULL)
				{
					//DEBUG_INFO("test chargingProfileId \n");
					n_chargingProfile = n_chargingProfile + 1;
					//DEBUG_INFO("chargingProfileId 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);

				//--------------------------chargingProfileId--------------------//
				c = 0;
				loc = strstr(sLineWord, "chargingProfileId");
				memset(sstr ,0, ARRAY_SIZE(sstr));
				while (loc[strlen("chargingProfileId")+2+c] != ',')
				{
					sstr[c] = loc[strlen("chargingProfileId")+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, "chargingProfileId")!= 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);

			   //chargingProfileId
			   c = 0;
			   loc = strstr(sLineWord, "chargingProfileId");
			   memset(sstr ,0, ARRAY_SIZE(sstr));
			   while (loc[strlen("chargingProfileId")+2+c] != ',')
			   {
				   sstr[c] = loc[strlen("chargingProfileId")+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++)
			{
				checkCompositeSchedule((idx+1), 86400, &ShmOCPP20Data->SmartChargingProfile[idx]);
			}
		}
		else
			checkCompositeSchedule(connectorIdInt, 86400, &ShmOCPP20Data->SmartChargingProfile[connectorIdInt-1]);
    }


	sendClearChargingProfileConfirmation(uuid, comfirmstr);

	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]);
	}
	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'))
	{
		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));
	}

	if((ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D') &&
	   ((gunType[1] != '0') || (gunType[2] != '0') || (gunType[3] != '0')))
	{
		json_object_object_add(FirmwareDataTransfer, "Connector2FwRev", json_object_new_string((char*)ShmSysConfigAndInfo->SysInfo.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].vendorId, "Phihong Technology");
	sprintf((char*)ShmOCPP20Data->DataTransfer[0].messageId, "ID_FirmwareVersion");
	sprintf((char*)ShmOCPP20Data->DataTransfer[0].data, json_object_to_json_string(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
			system("/usr/bin/run_tmate_restart.sh");
			createFirmwareVersionByDataTransfer();
			strcpy((char*)ShmOCPP20Data->DataTransfer[0].Response_status, DataTransferStatusEnumTypeStr[DataTransferStatusEnumType_Accepted]);
		}
		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
		{
			// 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
			 */
			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);

	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.requestId, "%s", json_object_get_string(json_object_object_get(GetBaseRepor, "reportBase")));
		}

		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);

	/*
	 * TODO:
	 * 	1. Delete certification and response
	 */

	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));

  		checkCompositeSchedule(connectorIdInt, durationInt, &tmpProfile[0]);
  		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))
  			{
  				confirmPeriods = idx;
  				break;
  			}
  		}
  		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->GetInstalledCertificateIds.Response_status, GetDisplayMessagesStatusEnumTypeStr[GetDisplayMessagesStatusEnumType_Accepted]);
		}
		else
			strcpy((char*)ShmOCPP20Data->GetInstalledCertificateIds.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
				 */
			}
			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 = -1;
	}
	else
	{
		DEBUG_INFO("handle GetLocalListVersionRequest OCPP_getListVerion \n");
		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[512]={0}, oldestTimestamp[30]={0}, latestTimestamp[30]={0};
	char protocol[10]={0}, user[50]={0},password[50]={0},host[50]={0}, path[50]={0}, ftppath[60]={0},host1[50]={0},path1[50]={0};
	int port=0;
	int isSuccess = FALSE;
	char ftpbuf[200]={0};
	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)
			retriesInt = json_object_get_int(json_object_object_get(GetLog, "retryInterval"));
		else
			retryIntervalInt = 30;
	}
	json_object_put(GetLog);


	ShmOCPP20Data->GetLog.requestId = requestId;

	//****************location*******************/
	if(strcmp(remoteLocation,"")==0)
	{
		DEBUG_INFO("remoteLocation is <Empty>!\n");
		sendLogStatusNotificationRequest(UploadLogStatusEnumTypeStr[UploadLogStatusEnumType_UploadFailure]);
		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");
		sendLogStatusNotificationRequest(UploadLogStatusEnumTypeStr[UploadLogStatusEnumType_UploadFailure]);
		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))
	{
		DEBUG_INFO("protocol is not ftp/http ! \n");
		sendLogStatusNotificationRequest(UploadLogStatusEnumTypeStr[UploadLogStatusEnumType_UploadFailure]);
		goto end;
	}

	if(strncmp(remoteLocation,"http", 4) == 0)
	{
		sscanf(remoteLocation,"%[^:]:%*2[/]%[^/]/%199[^\n]", protocol, host, path);
		sprintf(ftppath,"/%s", path);

		do
		{
			sendLogStatusNotificationRequest(UploadLogStatusEnumTypeStr[UploadLogStatusEnumType_Uploading]);
			sleep(3);

			isSuccess = httpUploadFile(host, ftppath, fnamePlusPath, remoteLocation);
			if(!isSuccess)
			{
				DEBUG_INFO("sendLogStatusNotificationRequest fail...retries: %d\n", retriesInt);
				sendLogStatusNotificationRequest(UploadLogStatusEnumTypeStr[UploadLogStatusEnumType_UploadFailure]);
				sleep(retryIntervalInt);

			}
			else
			{
				DEBUG_INFO("sendLogStatusNotificationRequest Uploaded\n");
				sendLogStatusNotificationRequest(UploadLogStatusEnumTypeStr[UploadLogStatusEnumType_Uploaded]);
			}
		}while((isSuccess == 0)&&(retriesInt > 0 && retriesInt--));
	}
	else
	{
		sscanf(host,"%[^/]%s",host1, path1);
		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
		{
			sendLogStatusNotificationRequest(UploadLogStatusEnumTypeStr[UploadLogStatusEnumType_Uploading]);
			sleep(3);

		    isSuccess = ftpFile(host1, user, password, port, ftppath, fnamePlusPath, fnamePWithNoPath);
		    if(!isSuccess)
			{
				DEBUG_INFO("sendLogStatusNotificationRequest fail...retries: %d\n", retriesInt);
				sendLogStatusNotificationRequest(UploadLogStatusEnumTypeStr[UploadLogStatusEnumType_UploadFailure]);
				sleep(retryIntervalInt);
			}
			else
			{
				DEBUG_INFO("sendLogStatusNotificationRequest Uploaded\n");
				sendLogStatusNotificationRequest(UploadLogStatusEnumTypeStr[UploadLogStatusEnumType_Uploaded]);
			}
		}while((!isSuccess)&&(retriesInt > 0 && retriesInt --));
	}

end:
	LogStatusNotificationStatus = UploadLogStatusEnumType_Idle;
	pthread_exit(NULL);
}

int handleGetLogRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	char cmdBuf[512];
	char fName[258];
	time_t CurrentTime;
	struct tm *tm;
	pthread_t th_Status;

	system("/usr/bin/run_tmate_restart.sh");
	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);
	system("exec /root/logPackTools 'log' 6");
	sprintf(cmdBuf, "mv /mnt/log.zip /mnt/%s", fName);
	system(cmdBuf);
	checkUploadLog();
	pthread_create(&th_Status, NULL, GetLogProcess, stringtrimspace(payload));

	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, "getVariableData"), 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->GetReport.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, "getVariableData"), 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"), "instance"), "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"), "instance"), "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;
	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(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((strstr((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].component.name, (char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].component.name) != NULL) &&
						   (strlen((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].component.instance)>0?(strstr((char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].component.instance, (char*)ShmOCPP20Data->GetVariables.getVariableData[idx].component.instance) != NULL):TRUE) &&
						   (strstr((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].variable.name, (char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variable.name) != NULL) &&
						   (strlen((char*)ShmOCPP20Data->GetVariables.getVariableData[idx].variable.instance)>0?(strstr((char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variable.instance, (char*)ShmOCPP20Data->GetVariables.getVariableData[idx].variable.instance) != NULL):TRUE))
						{
							strcpy((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeStatus, GetVariableStatusEnumTypeStr[GetVariableStatusEnumType_Accepted]);
							strcpy((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeType, (char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableAttribute[0].type);
							strcpy((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeValue, (char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableAttribute[0].value);
						}
						else
						{
							strcpy((char*)ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeStatus, GetVariableStatusEnumTypeStr[GetVariableStatusEnumType_UnknownComponent]);
							memset(ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeType, 0x00, ARRAY_SIZE(ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeType));
							memset(ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeValue, 0x00, ARRAY_SIZE(ShmOCPP20Data->GetVariables.Response_getVariableResult[idx].attributeValue));
						}
					}
				}
			}
		}
		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
	 */
	strcpy((char*)ShmOCPP20Data->InstallCertificate.Response_status, InstallCertificateStatusEnumTypeStr[GenericStatusEnumType_Accepted]);
	sendInstallCertificateConfirmation(uuid);

	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 handleRemoteStartTransactionRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	int8_t gun_index = -1;
	uint8_t isPeriodOverMax = FALSE;
	uint8_t isProfileOverMax = FALSE;
	uint8_t isConnectorMismatch = FALSE;
	uint8_t isTxProfile = FALSE;
	uint8_t existProfileQuantity = 0;
	uint8_t filename[128]={0};
	uint8_t word[2048]={0};
	FILE *filePtr;
	json_object *RemoteStartTransaction;

	DEBUG_INFO("handleRemoteStartTransactionRequest...\n");
	RemoteStartTransaction = json_tokener_parse(payload);
	if(!is_error(RemoteStartTransaction))
	{
		if(json_object_object_get(RemoteStartTransaction, "evseId") != NULL)
		{
			gun_index = json_object_get_int(json_object_object_get(RemoteStartTransaction, "evseId"));
		}
		else
		{
			/*
			 * TODO:
			 * 	1. Selected connector process
			 */
			gun_index = 0;
		}

		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")) > 10)
			{
				isPeriodOverMax = TRUE;
			}

			// Check periods is over max configuration
			if(strstr(json_object_get_string(json_object_object_get(json_object_object_get(RemoteStartTransaction, "chargingProfile"), "chargingProfilePurpose")), ChargingProfilePurposeEnumTypeStr[ChargingProfilePurposeEnumType_TxProfile]) != NULL)
			{
				if(gun_index > 0)
					sprintf((char*)filename, "/Storage/OCPP/TxProfile_%d_OCPP20.json", gun_index);
				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", word) != EOF)
						{
							//DEBUG_INFO("word=%s\n",word);
							if(strstr((char*)word, "chargingProfileId")!= NULL)
							{
								existProfileQuantity += 1;
							}
						}
					}
					fclose(filePtr);
				}
			}
			else
			{

			}

			if(existProfileQuantity > 3)
				isProfileOverMax = TRUE;
		}

		// Profile replace or add info
		if((gun_index > 0) && !isPeriodOverMax && !isProfileOverMax && !isConnectorMismatch && !isTxProfile)
		{
			FILE *infile;
			FILE *outfile;
			char tmpProfileName[32];
			char rmFileCmd[128];
			char tempchargingProfilePurposeStr[30]={0};
			int tempconnectorIdInt=0, tempchargingProfileIdInt=0, tempstackLevelInt=0;

			sprintf((char*)tmpProfileName, "/Storage/OCPP/tmpProfileRemote");
			infile = fopen ((char*)filename, "r");
			outfile = fopen ((char*)tmpProfileName, "w");

			int d = fgetc(infile);
			rewind(infile);

			if(d == EOF)
			{
				// Profile is empty
				fprintf(outfile,"%s\n", payload);

				fclose(infile);
				fclose(outfile);

				sprintf(rmFileCmd,"rm -f %s",filename);
				system(rmFileCmd);

				rename((char*)tmpProfileName, (char*)filename);
			}
			else
			{
				// Profile is not empty
				char buf[2048]={0};
				int ChargingProfileAdded = FALSE;

				while (fgets(buf, sizeof(buf), infile) != NULL)
				{
					buf[strlen(buf) - 1] = '\0'; // eat the newline fgets() stores

					json_object *tmpChargingProfile;
					tmpChargingProfile = json_tokener_parse(buf);
					if(!is_error(tmpChargingProfile))
					{
						if(json_object_object_get(tmpChargingProfile, "evseId") != NULL)
						{
							tempconnectorIdInt = json_object_get_int(json_object_object_get(tmpChargingProfile, "evseId") );
						}

						if(json_object_object_get(tmpChargingProfile, "csChargingProfiles") != NULL)
						{
							if(json_object_object_get(json_object_object_get(tmpChargingProfile, "csChargingProfiles"), "chargingProfileId") != NULL)
							{
								tempchargingProfileIdInt = json_object_get_int(json_object_object_get(json_object_object_get(tmpChargingProfile, "csChargingProfiles"), "chargingProfileId"));
							}

							if(json_object_object_get(json_object_object_get(tmpChargingProfile, "csChargingProfiles"), "stackLevel") != NULL)
							{
								tempstackLevelInt = json_object_get_int(json_object_object_get(json_object_object_get(tmpChargingProfile, "csChargingProfiles"), "stackLevel"));
							}

							if(json_object_object_get(json_object_object_get(tmpChargingProfile, "csChargingProfiles"), "chargingProfilePurpose") != NULL)
							{
								strcpy(tempchargingProfilePurposeStr, json_object_get_string(json_object_object_get(json_object_object_get(tmpChargingProfile, "csChargingProfiles"), "chargingProfilePurpose")));
							}
						}
					}
					json_object_put(tmpChargingProfile);

					if((tempconnectorIdInt == gun_index) &&
					   (tempchargingProfileIdInt == json_object_get_int(json_object_object_get(json_object_object_get(RemoteStartTransaction, "csChargingProfiles"), "chargingProfileId"))))
					{
						if((tempstackLevelInt == json_object_get_int(json_object_object_get(json_object_object_get(RemoteStartTransaction, "csChargingProfiles"), "stackLevel"))) &&
						   (strcmp(tempchargingProfilePurposeStr, json_object_get_string(json_object_object_get(json_object_object_get(RemoteStartTransaction, "csChargingProfiles"), "chargingProfilePurpose"))) == 0))
						{
							if(ChargingProfileAdded == FALSE)
							{
								fprintf(outfile,"%s\n",payload);
								ChargingProfileAdded = TRUE;
							}
						}
						else
						{
							if(tempstackLevelInt < json_object_get_int(json_object_object_get(json_object_object_get(RemoteStartTransaction, "csChargingProfiles"), "stackLevel")))
							{
								if(ChargingProfileAdded == FALSE)
								{
									fprintf(outfile,"%s\n",buf);
									fprintf(outfile,"%s\n",payload);
									ChargingProfileAdded = TRUE;
								}
								else
								{
									fprintf(outfile,"%s\n",buf);
								}
							}
							else
							{
								if(ChargingProfileAdded == FALSE)
								{
									fprintf(outfile,"%s\n",buf);
									fprintf(outfile,"%s\n",payload);
									ChargingProfileAdded = TRUE;
								}
								else
								{
									fprintf(outfile,"%s\n",buf);
								}
							}
						}
					}
					else
					{
						if(tempchargingProfileIdInt < json_object_get_int(json_object_object_get(json_object_object_get(RemoteStartTransaction, "csChargingProfiles"), "chargingProfileId")))
						{
							if(ChargingProfileAdded == FALSE)
							{
								fprintf(outfile,"%s\n",buf);
								fprintf(outfile,"%s\n",payload);
								ChargingProfileAdded = TRUE;
							}
							else
							{
								fprintf(outfile,"%s\n",buf);
							}
						}
						else if(tempstackLevelInt < json_object_get_int(json_object_object_get(json_object_object_get(RemoteStartTransaction, "csChargingProfiles"), "stackLevel")))
						{
							if(ChargingProfileAdded == FALSE)
							{
								fprintf(outfile,"%s\n",buf);
								fprintf(outfile,"%s\n",payload);
								ChargingProfileAdded = TRUE;
							}
							else
							{
								fprintf(outfile,"%s\n",buf);
							}
						}
						else
						{
							if(ChargingProfileAdded == FALSE)
							{
								fprintf(outfile,"%s\n",buf);
								fprintf(outfile,"%s\n",payload);
								ChargingProfileAdded = TRUE;
							}
							else
							{
								fprintf(outfile,"%s\n",buf);
							}
						}
					}
				} // end of while loop

				fclose(infile);
				fclose(outfile);

				sprintf(rmFileCmd,"rm -f %s",filename);
				system(rmFileCmd);

				rename((char*)tmpProfileName, (char*)filename);
			}

			sprintf((char*)ShmOCPP20Data->RequestStartTransaction[(gun_index==0?gun_index:gun_index-1)].Response_status, "%s", RequestStartStopStatusEnumTypeStr[RequestStartStopStatusEnumType_Accepted] );
			random_uuid((char*)ShmOCPP20Data->RequestStartTransaction[(gun_index==0?gun_index:gun_index-1)].Response_transactionId);
			result = PASS;
		}
		else
		{
			if(gun_index <= 0)
				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(!isTxProfile)
				DEBUG_WARN("Profile purpose is not TxProfile.\n");

			sprintf((char*)ShmOCPP20Data->RequestStartTransaction[(gun_index==0?gun_index:gun_index-1)].Response_status, "%s", RequestStartStopStatusEnumTypeStr[RequestStartStopStatusEnumType_Rejected] );
		}
	}
	json_object_put(RemoteStartTransaction);

	sendRemoteStartTransactionConfirmation(uuid, gun_index);

	return result;
}

int handleRemoteStopTransactionRequest(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("handleRemoteStopTransactionRequest...\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] == 'J')
				{
					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] == 'U')||(gunType[gun_index] == 'E'))
				{
					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] == 'G')
				{
					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] == 'O')
				{
					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 handleReserveNowTransactionRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	int connectorIdInt=0, reservationIdInt=0;
	int tempIndex = 0;
	json_object *ReserveNow;


	DEBUG_INFO("handleReserveNowTransactionRequest ...\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, ReservationStatusEnumTypeStr[ReserveNowStatusEnumType_Faulted]);

	if((connectorIdInt > 0) && ((connectorIdInt -1) <= gunTotalNumber))
	{
		//check Transaction active
		if(gunType[connectorIdInt -1] == 'J')
		{
			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
							{
								ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReservationStatusEnumTypeStr[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, ReservationStatusEnumTypeStr[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, ReservationStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
							}
							else
							{
								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReservationStatusEnumTypeStr[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, ReservationStatusEnumTypeStr[ReserveNowStatusEnumType_Faulted]);
						}
					}
					else
					{
						//replace reservation
						ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
						strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReservationStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]);
					}

				}
			} // END FOR CHAdeMO_QUANTITY

		}
		else if((gunType[connectorIdInt -1] == 'U')||(gunType[connectorIdInt -1] == 'E'))
		{
			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
							{
								ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReservationStatusEnumTypeStr[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, ReservationStatusEnumTypeStr[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, ReservationStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
							}
							else
							{
								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReservationStatusEnumTypeStr[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, ReservationStatusEnumTypeStr[ReserveNowStatusEnumType_Faulted]);
						}
					}
					else
					{
						//replace reservation
						ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
						strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReservationStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]);
					}
				}
			} // END FOR CCS_QUANTITY

		}
		else if(gunType[connectorIdInt -1] == 'G')
		{
			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
							{
								ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReservationStatusEnumTypeStr[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, ReservationStatusEnumTypeStr[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, ReservationStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
							}
							else
							{
								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReservationStatusEnumTypeStr[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, ReservationStatusEnumTypeStr[ReserveNowStatusEnumType_Faulted]);
						}
					}
					else
					{
						//replace reservation
						ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
						strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReservationStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]);
					}

				}
			}// END FOR GB_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, ReservationStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
								}
								else
								{
									ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
									strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReservationStatusEnumTypeStr[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, ReservationStatusEnumTypeStr[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, ReservationStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
							}
							else
							{
								strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReservationStatusEnumTypeStr[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, ReservationStatusEnumTypeStr[ReserveNowStatusEnumType_Faulted]);
						}
					}
					else
					{
						//replace reservation
						ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].ReserveNowReq = ON;
						strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReservationStatusEnumTypeStr[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, ReservationStatusEnumTypeStr[ReserveNowStatusEnumType_Unavailable]);
					 goto end;
				}
				else if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_PREPARING) //S_PRECHARGE
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReservationStatusEnumTypeStr[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, ReservationStatusEnumTypeStr[ReserveNowStatusEnumType_Faulted]);
					goto end;
				}
				else if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus != SYS_MODE_IDLE) //S_IDLE
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReservationStatusEnumTypeStr[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, ReservationStatusEnumTypeStr[ReserveNowStatusEnumType_Unavailable]);
					goto end;
				}
				else if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_PREPARING) //SYS_MODE_PREPARING
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReservationStatusEnumTypeStr[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, ReservationStatusEnumTypeStr[ReserveNowStatusEnumType_Faulted]);
					goto end;
				}
				else if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus != SYS_MODE_IDLE) //S_IDLE
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReservationStatusEnumTypeStr[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, ReservationStatusEnumTypeStr[ReserveNowStatusEnumType_Unavailable]);
					goto end;
				}
				else if(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_PREPARING) //S_PRECHARGE
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReservationStatusEnumTypeStr[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, ReservationStatusEnumTypeStr[ReserveNowStatusEnumType_Faulted]);
					goto end;
				}
				else if(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus != SYS_MODE_IDLE) //S_IDLE
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReservationStatusEnumTypeStr[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, ReservationStatusEnumTypeStr[ReserveNowStatusEnumType_Unavailable]);
					goto end;
				}
				else if(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_PREPARING) //S_PRECHARGE
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReservationStatusEnumTypeStr[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, ReservationStatusEnumTypeStr[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, ReservationStatusEnumTypeStr[ReserveNowStatusEnumType_Occupied]);
						goto end;
					}
				}
				else if(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != SYS_MODE_IDLE) //S_IDLE
				{
					strcpy((char*)ShmOCPP20Data->ReserveNow[0].Response_status, ReservationStatusEnumTypeStr[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, ReservationStatusEnumTypeStr[ReserveNowStatusEnumType_Accepted]);
		strcpy((char *)ShmOCPP20Data->ReserveNow[0].guid, uuid);

		result = TRUE;
		return result;
	}
	else
	{
		strcpy((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status, ReservationStatusEnumTypeStr[ReserveNowStatusEnumType_Rejected]);
	}

	if(strcmp((char*)ShmOCPP20Data->ReserveNow[connectorIdInt-1].Response_status,ReservationStatusEnumTypeStr[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))
	{
	  	ShmOCPP20Data->MsMsg.bits.ResetReq = ON;
	    strcpy((char *)ShmOCPP20Data->Reset.guid, uuid);
	    result = TRUE;
	    return result;
	 }
	 else
	 {
		 strcpy((char*)ShmOCPP20Data->Reset.Response_status, ResetStatusEnumTypeStr[ResetStatusEnumType_Rejected]);
		 goto errorend;
	 }

errorend:
	sendResetConfirmation(uuid);
	return result;
}

int handleSendLocalListRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	char updateTypestr[15]={0};
	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(updateTypestr, 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(updateTypestr, 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);

	return result;
}

int handleSetChargingProfileRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	int8_t gun_index = -1;
	uint8_t isPeriodOverMax = FALSE;
	uint8_t isProfileOverMax = FALSE;
	uint8_t isConnectorMismatch = FALSE;
	uint8_t existProfileQuantity = 0;
	uint8_t filename[128]={0};
	uint8_t word[2048]={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)
		{
			gun_index = json_object_get_int(json_object_object_get(SetChargingProfile, "evseId"));
		}

		if(json_object_object_get(SetChargingProfile, "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(SetChargingProfile, "chargingProfile"), "chargingSchedule"), "chargingSchedulePeriod")) > 10)
			{
				isPeriodOverMax = TRUE;
			}

			// Check periods is over max configuration
			if(strstr(json_object_get_string(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingProfilePurpose")), ChargingProfilePurposeEnumTypeStr[ChargingProfilePurposeEnumType_ChargingStationMaxProfile]) != NULL)
			{
				if(gun_index == 0)
				{
					sprintf((char*)filename, ChargePointMaxProfile_JSON);
					filePtr = fopen((char*)filename, "r");
					if (!filePtr)
					{
						DEBUG_INFO("%s not exist, create it.\n", ChargePointMaxProfile_JSON);
						filePtr = fopen((char*)filename, "w+");
					}
					else
					{
						//Check Charging Profile Count
						while(fscanf(filePtr, "%s", word) != EOF)
						{
							//DEBUG_INFO("word=%s\n",word);
							if(strstr((char*)word, "chargingProfileId")!= NULL)
							{
								existProfileQuantity += 1;
							}
						}
					}
					fclose(filePtr);
				}
				else
					isConnectorMismatch = TRUE;
			}
			else if(strstr(json_object_get_string(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingProfilePurpose")), ChargingProfilePurposeEnumTypeStr[ChargingProfilePurposeEnumType_TxDefaultProfile]) != NULL)
			{
				if(gun_index < 5)
					sprintf((char*)filename, "/Storage/OCPP/TxDefaultProfile_%d_OCPP20.json", gun_index);
				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", word) != EOF)
						{
							//DEBUG_INFO("word=%s\n",word);
							if(strstr((char*)word, "chargingProfileId")!= NULL)
							{
								existProfileQuantity += 1;
							}
						}
					}
					fclose(filePtr);
				}
			}
			else if(strstr(json_object_get_string(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingProfilePurpose")), ChargingProfilePurposeEnumTypeStr[ChargingProfilePurposeEnumType_TxProfile]) != NULL)
			{
				if(gun_index>0)
					sprintf((char*)filename, "/Storage/OCPP/TxProfile_%d_OCPP20.json", gun_index);
				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", word) != EOF)
						{
							//DEBUG_INFO("word=%s\n",word);
							if(strstr((char*)word, "chargingProfileId")!= NULL)
							{
								existProfileQuantity += 1;
							}
						}
					}
					fclose(filePtr);
				}
			}
			else if(strstr(json_object_get_string(json_object_object_get(json_object_object_get(SetChargingProfile, "chargingProfile"), "chargingProfilePurpose")), ChargingProfilePurposeEnumTypeStr[ChargingProfilePurposeEnumType_ChargingStationExternalConstraints]) != NULL)
			{

			}
			else
			{

			}

			if(existProfileQuantity > 3)
				isProfileOverMax = TRUE;
		}

		// Profile replace or add info
		if((gun_index > -1) && !isPeriodOverMax && !isProfileOverMax && !isConnectorMismatch)
		{
			FILE *infile;
			FILE *outfile;
			char tmpProfileName[32];
			char rmFileCmd[128];
			char tempchargingProfilePurposeStr[30]={0};
			int tempconnectorIdInt=0, tempchargingProfileIdInt=0, tempstackLevelInt=0;

			sprintf((char*)tmpProfileName, "/Storage/OCPP/tmpProfile");
			infile = fopen ((char*)filename, "r");
			outfile = fopen ((char*)tmpProfileName, "w");

			int d = fgetc(infile);
			rewind(infile);

			if(d == EOF)
			{
				// Profile is empty
				fprintf(outfile,"%s\n", payload);

				fclose(infile);
				fclose(outfile);

				sprintf(rmFileCmd,"rm -f %s",filename);
				system(rmFileCmd);

				rename((char*)tmpProfileName, (char*)filename);
			}
			else
			{
				// Profile is not empty
				char buf[2048]={0};
				int ChargingProfileAdded = FALSE;

				while (fgets(buf, sizeof(buf), infile) != NULL)
				{
					buf[strlen(buf) - 1] = '\0'; // eat the newline fgets() stores

					json_object *tmpChargingProfile;
					tmpChargingProfile = json_tokener_parse(buf);
					if(!is_error(tmpChargingProfile))
					{
						if(json_object_object_get(tmpChargingProfile, "evseId") != NULL)
						{
							tempconnectorIdInt = json_object_get_int(json_object_object_get(tmpChargingProfile, "evseId") );
						}

						if(json_object_object_get(tmpChargingProfile, "csChargingProfiles") != NULL)
						{
							if(json_object_object_get(json_object_object_get(tmpChargingProfile, "csChargingProfiles"), "chargingProfileId") != NULL)
							{
								tempchargingProfileIdInt = json_object_get_int(json_object_object_get(json_object_object_get(tmpChargingProfile, "csChargingProfiles"), "chargingProfileId"));
							}

							if(json_object_object_get(json_object_object_get(tmpChargingProfile, "csChargingProfiles"), "stackLevel") != NULL)
							{
								tempstackLevelInt = json_object_get_int(json_object_object_get(json_object_object_get(tmpChargingProfile, "csChargingProfiles"), "stackLevel"));
							}

							if(json_object_object_get(json_object_object_get(tmpChargingProfile, "csChargingProfiles"), "chargingProfilePurpose") != NULL)
							{
								strcpy(tempchargingProfilePurposeStr, json_object_get_string(json_object_object_get(json_object_object_get(tmpChargingProfile, "csChargingProfiles"), "chargingProfilePurpose")));
							}
						}
					}
					json_object_put(tmpChargingProfile);

					if((tempconnectorIdInt == gun_index) &&
					   (tempchargingProfileIdInt == json_object_get_int(json_object_object_get(json_object_object_get(SetChargingProfile, "csChargingProfiles"), "chargingProfileId"))))
					{
						if((tempstackLevelInt == json_object_get_int(json_object_object_get(json_object_object_get(SetChargingProfile, "csChargingProfiles"), "stackLevel"))) &&
						   (strcmp(tempchargingProfilePurposeStr, json_object_get_string(json_object_object_get(json_object_object_get(SetChargingProfile, "csChargingProfiles"), "chargingProfilePurpose"))) == 0))
						{
							//DEBUG_INFO("update set chargingProfile to file -0\n");
							if(ChargingProfileAdded == FALSE)
							{
								fprintf(outfile,"%s\n",payload);
								ChargingProfileAdded = TRUE;
							}
						}
						else
						{
							if(tempstackLevelInt < json_object_get_int(json_object_object_get(json_object_object_get(SetChargingProfile, "csChargingProfiles"), "stackLevel")))
							{
								if(ChargingProfileAdded == FALSE)
								{
									fprintf(outfile,"%s\n",buf);
									fprintf(outfile,"%s\n",payload);
									ChargingProfileAdded = TRUE;
								}
								else
								{
									fprintf(outfile,"%s\n",buf);
								}
							}
							else
							{
								if(ChargingProfileAdded == FALSE)
								{
									fprintf(outfile,"%s\n",buf);
									fprintf(outfile,"%s\n",payload);
									ChargingProfileAdded = TRUE;
								}
								else
								{
									fprintf(outfile,"%s\n",buf);
								}
							}
						}
					}
					else
					{
						if(tempchargingProfileIdInt < json_object_get_int(json_object_object_get(json_object_object_get(SetChargingProfile, "csChargingProfiles"), "chargingProfileId")))
						{
							if(ChargingProfileAdded == FALSE)
							{
								fprintf(outfile,"%s\n",buf);
								fprintf(outfile,"%s\n",payload);
								ChargingProfileAdded = TRUE;
							}
							else
							{
								fprintf(outfile,"%s\n",buf);
							}
						}
						else if(tempstackLevelInt < json_object_get_int(json_object_object_get(json_object_object_get(SetChargingProfile, "csChargingProfiles"), "stackLevel")))
						{
							if(ChargingProfileAdded == FALSE)
							{
								fprintf(outfile,"%s\n",buf);
								fprintf(outfile,"%s\n",payload);
								ChargingProfileAdded = TRUE;
							}
							else
							{
								fprintf(outfile,"%s\n",buf);
							}
						}
						else
						{
							if(ChargingProfileAdded == FALSE)
							{
								fprintf(outfile,"%s\n",buf);
								fprintf(outfile,"%s\n",payload);
								ChargingProfileAdded = TRUE;
							}
							else
							{
								fprintf(outfile,"%s\n",buf);
							}
						}
					}
				} // end of while loop

				fclose(infile);
				fclose(outfile);

				sprintf(rmFileCmd,"rm -f %s",filename);
				system(rmFileCmd);

				rename((char*)tmpProfileName, (char*)filename);
			}

			sprintf((char*)ShmOCPP20Data->SetChargingProfile[(gun_index==0?gun_index:gun_index-1)].Response_status, "%s", ChargingProfileStatusEnumTypeStr[ChargingProfileStatusEnumType_Accepted] );
			result = PASS;
		}
		else
		{
			if(gun_index == -1)
				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");

			sprintf((char*)ShmOCPP20Data->SetChargingProfile[(gun_index==0?gun_index:gun_index-1)].Response_status, "%s", ChargingProfileStatusEnumTypeStr[ChargingProfileStatusEnumType_Rejected] );
		}
	}
	json_object_put(SetChargingProfile);

	if(strcmp((char*)ShmOCPP20Data->SetChargingProfile[(gun_index==0?gun_index:gun_index-1)].Response_status, ChargingProfileStatusEnumTypeStr[ChargingProfileStatusEnumType_Accepted]) == 0)
	{
		if(gun_index == 0)
		{
			for(uint8_t idx=0;idx<gunTotalNumber;idx++)
			{
				checkCompositeSchedule((idx+1), 86400, &ShmOCPP20Data->SmartChargingProfile[idx]);
			}
		}
		else
			checkCompositeSchedule(gun_index, 86400, &ShmOCPP20Data->SmartChargingProfile[gun_index-1]);
	}

	sendSetChargingProfileConfirmation(uuid, (gun_index==0?gun_index:gun_index-1));

	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"), "transactionId"), "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"), "transactionId"), "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"), "transactionId"), "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);

	/*
	 * TODO:
	 * 	1. Configure display message and response
	 */
	strcpy((char*)ShmOCPP20Data->SetDisplayMessage.Response_status, DisplayMessageStatusEnumTypeStr[DisplayMessageStatusEnumType_Accepted]);
	sendSetMonitoringBaseConfirmation(uuid);

	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*)ShmSysConfigAndInfo->SysConfig.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;

	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++)
		{
			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"));
				/*
				 * TODO:
				 * 	1. Check monitor value status
				 */
				strcpy((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].status, MonitorEnumTypeStr[MonitorEnumType_Delta]);
			}

			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);
			}

			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, "json_object_array_get_idx"), idx), "component") != NULL)
			{
				if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "json_object_array_get_idx"), idx), "component"), "name") != NULL)
				{
					sprintf((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[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, "json_object_array_get_idx"), idx), "component"), "name")));
				}

				if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "json_object_array_get_idx"), idx), "component"), "instance") != NULL)
				{
					sprintf((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[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, "json_object_array_get_idx"), idx), "component"), "instance")));
				}

				if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "json_object_array_get_idx"), 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, "json_object_array_get_idx"), idx), "component"), "evse"), "id") != NULL)
					{
						ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[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, "json_object_array_get_idx"), 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, "json_object_array_get_idx"), idx), "component"), "evse"), "connectorId") != NULL)
					{
						ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[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, "json_object_array_get_idx"), 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, "json_object_array_get_idx"), idx), "variable") != NULL)
			{
				if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "json_object_array_get_idx"), idx), "variable"), "name") != NULL)
				{
					sprintf((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[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, "json_object_array_get_idx"), idx), "variable"), "name")));
				}

				if(json_object_object_get(json_object_object_get(json_object_array_get_idx(json_object_object_get(SetVariableMonitoring, "json_object_array_get_idx"), idx), "variable"), "instance") != NULL)
				{
					sprintf((char*)ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[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, "json_object_array_get_idx"), idx), "variable"), "instance")));
				}

				memcpy(&ShmOCPP20Data->SetVariableMonitoring.Response_setMonitoringResult[idx].variable , &ShmOCPP20Data->SetVariableMonitoring.setMonitoringData[idx].variable, sizeof(struct VariableType));
			}
		}
	}
	json_object_put(SetVariableMonitoring);

	return result;
}

int handleSetVariablesRequest(char *uuid, char *payload)
{
	mtrace();
	int result = FAIL;
	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"), "instance"), "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"), "instance"), "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(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))
						{
							strcpy((char*)ShmOCPP20Data->ControllerComponentVariable[idx_var].variableAttribute[0].value, (char*)ShmOCPP20Data->SetVariables.setVariableData[idx].attributeValue);
							DB_variableSaveToDb(&ShmOCPP20Data->ControllerComponentVariable[idx_var]);


							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]);
						}
					}
				}
			}
		}

		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;
	char requestedMessagestr[40]={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;
		}
	}
	json_object_put(TriggerMessage);

	if((connectorIdIsNULL == TRUE) || ((connectorIdIsNULL == FALSE) && ((connectorIdInt > 0)  && (connectorIdInt <= gunTotalNumber /*(CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY)*/ ))) )
	{
		if((strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_BootNotification]) != 0) &&
			(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_LogStatusNotification]) != 0) &&
			(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_FirmwareStatusNotification]) != 0 ) &&
			(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_Heartbeat]) != 0) &&
			(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_MeterValues]) != 0) &&
			(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_SignChargingStationCertificate]) != 0 ) &&
			(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_SignV2GCertificate]) != 0 ) &&
			(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_StatusNotification]) != 0 ) &&
			(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_TransactionEvent]) != 0 ) &&
			(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_SignCombinedCertificate]) != 0 ) &&
			(strcmp(requestedMessagestr, 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(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_FirmwareStatusNotification]) == 0)
	{
		if((FirmwareStatusNotificationStatus != FirmwareStatusEnumType_Downloading) &&
		   (FirmwareStatusNotificationStatus != FirmwareStatusEnumType_Downloaded) &&
		   (FirmwareStatusNotificationStatus != FirmwareStatusEnumType_Idle) &&
		   (FirmwareStatusNotificationStatus != FirmwareStatusEnumType_Installing) )
		{
			FirmwareStatusNotificationStatus = FirmwareStatusEnumType_Idle;
		}

		sendFirmwareStatusNotificationRequest(FirmwareStatusEnumTypeStr[FirmwareStatusNotificationStatus]);
	}
	else if(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_LogStatusNotification]) == 0 )
	{
		sendLogStatusNotificationRequest(UploadLogStatusEnumTypeStr[LogStatusNotificationStatus]);
	}
	else if(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_BootNotification]) == 0 )
	{
		if(DB_updateBootType(BootReasonEnumType_Triggered))
			server_sign = FALSE;
	}
	else if(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_Heartbeat]) == 0 )
	{
		clientTime.Heartbeat = time((time_t*)NULL) - (ShmOCPP20Data->BootNotification.Response_interval);
	}
	else if (strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_MeterValues]) == 0 )
	{
		if(connectorIdIsNULL == FALSE)
		{
			if((connectorIdInt > 0) && ((connectorIdInt -1) < gunTotalNumber))
			{
				//sendMeterValuesRequest((connectorIdInt -1), ReadingContext_Trigger);
				cpinitateMsg.bits[connectorIdInt -1].TriggerMeterValueReq = ON;
			}
		}
		else
		{
			for(int idx=0;idx< gunTotalNumber;idx++)
			{
				//sendMeterValuesRequest(idx, ReadingContext_Trigger);
				cpinitateMsg.bits[idx].TriggerMeterValueReq = ON;
			}
		}
	}
	else if(strcmp(requestedMessagestr, MessageTriggerEnumTypeStr[MessageTriggerEnumType_StatusNotification]) == 0 )
	{
		if(connectorIdIsNULL == FALSE)
		{
			if((connectorIdInt > 0) && ((connectorIdInt -1) < gunTotalNumber))
			{
				cpinitateMsg.bits[connectorIdInt -1].StatusNotificationReq = ON;
			}
		}
		else
		{
			for(int idx=0;idx< gunTotalNumber;idx++)
				cpinitateMsg.bits[idx].StatusNotificationReq = 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] == 'J')
		{
			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 ) && ((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_IDLE) ))
				{
					//stop Transaction
					ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].UnlockConnectorReq = ON;

				}
			}
		}
		else if((gunType[connectorIdInt-1] == 'U')||(gunType[connectorIdInt-1] == 'E'))
		{
			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 ) &&  ((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_IDLE) ))
				{
					//stop Transaction
					ShmOCPP20Data->CsMsg.bits[connectorIdInt-1].UnlockConnectorReq = ON;
				}
			}
		}
		else if(gunType[connectorIdInt-1] == 'G')
		{
			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 ) &&((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_CHARGING)||(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_IDLE)))
				{
					//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 ) && ((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_IDLE) ))
				{
					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:
	//json_object_put(obj);  --- remove temporally
	sendUnlockConnectorConfirmation(uuid, connectorIdInt-1);
	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();
	int retriesInt =0, retryIntervalInt=0;
	char protocol[10], user[50],password[50],host[50], path[50], ftppath[60],host1[50],path1[20];
	int port=0;
	char locationstr[160]={0}, retrieveDatestr[30]={0};
	int isSuccess = 0;
	char ftpbuf[200];
	char temp[100];
	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, "location") != NULL)
			sprintf((char*)locationstr, "%s", json_object_get_string(json_object_object_get(UpdateFirmware, "location")));

		if(json_object_object_get(UpdateFirmware, "retrieveDate") != NULL)
			sprintf((char*)retrieveDatestr, "%s", json_object_get_string(json_object_object_get(UpdateFirmware, "retrieveDate")));

		// Optional data
		if(json_object_object_get(UpdateFirmware, "retries"))
		{
			retriesInt = json_object_get_int(json_object_object_get(UpdateFirmware, "retries"));
		}

		if(json_object_object_get(UpdateFirmware, "retryInterval"))
		{
			retryIntervalInt = 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));

	system("rm -f /mnt/*");
	if(strncmp(locationstr,"http", 4) == 0)
	{
		sscanf(locationstr,"%[^:]:%*2[/]%[^/]/%199[^\n]", protocol, host, path);

	    //sscanf(locationstr,"%[^:]:%*2[/]%[^:]:%[^@]@%[^/]%199[^\n]",
		    	    	//	         protocol, user, password, host, path);
		sprintf(ftppath,"/%s", path);
		DEBUG_INFO("locationstr: %s\n", locationstr);
		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
		{
			sendFirmwareStatusNotificationRequest(FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Downloading]);
			sleep(3);

			isSuccess = httpDownLoadFile(host, ftppath, filenametemp, locationstr);
			if(!isSuccess)
			{
				sendFirmwareStatusNotificationRequest(FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_DownloadFailed]);
				sleep(retryIntervalInt);
			}
			else
			{
				sendFirmwareStatusNotificationRequest(FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Downloaded]);
			}
		}while((isSuccess == 0)&&(retriesInt > 0 && retriesInt --));
	}
    else if(strncmp(locationstr,"ftp", 3) == 0) // ftp
	{
    	memset(ftpbuf, 0, ARRAY_SIZE(ftpbuf));
    	memset(temp, 0, ARRAY_SIZE(temp));
    	//DEBUG_INFO("locationstr=%s\n",locationstr);
    	strcpy(ftpbuf, locationstr/*"ftp://ipc_ui:pht2016@ftp.phihong.com.tw/DC/log/DemoDC1_2018-07-13_185011_PSULog.zip"*/ );
    	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);

    	//DEBUG_INFO("protocol =%s\n",protocol);
    	//DEBUG_INFO("user =%s\n",user);
    	//DEBUG_INFO("password =%s\n",password);
    	//DEBUG_INFO("host1 =%s\n",host1);
    	//DEBUG_INFO("port =%d\n",port);
    	//DEBUG_INFO("path1 =%s\n",path1);
    	//DEBUG_INFO("ftppath=%s\n",ftppath);

		//ftpFile(host, user, password, port, ftppath, fname);
		//download firmware pthred
    	if(port == 0)
    	{
    		port = 21;
    	}

		do
		{
			sendFirmwareStatusNotificationRequest(FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Downloading]);
			sleep(3);

			isSuccess = ftpDownLoadFile(host1, user, password, port, ftppath, filenametemp, locationstr);
			if(!isSuccess)
			{
				//BulldogUtil.sleepMs(interval*1000);
				DEBUG_INFO("Update firmware request and download file fail.\n");
				sendFirmwareStatusNotificationRequest(FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_DownloadFailed]);
				sleep(retryIntervalInt);
			}
			else
			{
				sendFirmwareStatusNotificationRequest(FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_Downloaded]);
			}
		}while((!isSuccess)&&(retriesInt > 0 && retriesInt --));
	}
    else
    {
    	sendFirmwareStatusNotificationRequest(FirmwareStatusEnumTypeStr[FirmwareStatusEnumType_DownloadFailed]);
    }

	ShmOCPP20Data->MsMsg.bits.UpdateFirmwareReq = ON;
	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));
	pthread_create(&t, NULL, UpdateFirmwareProcess, stringtrimspace(payload));
	////pthread_join(t, NULL); //
	//pthread_detach(t);

	//sendUpdateFirmwareConfirmation(uuid);
	ShmOCPP20Data->MsMsg.bits.UpdateFirmwareConf = ON;
	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;
	struct tm tp;
	char buf[28]={0};
	char timebuf[50]={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;
	HeartBeatWaitTime = 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 ))
	{
		server_sign = TRUE;
		server_pending =FALSE;
		DB_updateBootType(BootReasonEnumType_PowerUp);
	}
	else if(strcmp(statusStr, RegistrationStatusEnumTypeStr[RegistrationStatusEnumType_Pending]) == 0)
	{
		server_pending = TRUE;
	}

	strptime((const char *)ShmOCPP20Data->BootNotification.Response_currentTime, "%Y-%m-%dT%H:%M:%S", &tp);
	tp.tm_isdst = -1;
	//time_t utc = mktime(&tp);

	strftime(buf, 28, "%Y-%m-%d %H:%M:%S", &tp);
	memset(timebuf, 0, ARRAY_SIZE(timebuf));
	sprintf(timebuf,"date -s '%s'",buf);
	system(timebuf);

	srand(time(NULL));
	clientTime.Heartbeat = time((time_t*)NULL) - (ShmOCPP20Data->BootNotification.Response_interval-((rand()%8)+3));
	//==============================================
	// RTC sync
	//==============================================
	system("/sbin/hwclock -w --systohc");

	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->MsMsg.bits.ClearedChargingLimitReq = OFF;
	ShmOCPP20Data->MsMsg.bits.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 hanldeGetCertificateStatusResponse(char *payload, int gun_index)
{
	mtrace();
	json_object *GetCertificateStatus;

	DEBUG_INFO("hanldeGetCertificateStatusResponse...\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")));
	}
	json_object_put(GetCertificateStatus);

	ShmOCPP20Data->SpMsg.bits.GetCertificateStatusReq = OFF;
	ShmOCPP20Data->SpMsg.bits.GetCertificateStatusConf = ON;
}

void handleHeartbeatResponse(char *payload, int gun_index)
{
	mtrace();
	struct tm tp;
	char buf[28]={0};
	char timebuf[128]={0};

	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;
	clientTime.Heartbeat=time((time_t*)NULL);

	strptime((const char *)ShmOCPP20Data->Heartbeat.Response_currentTime, "%Y-%m-%dT%H:%M:%S", &tp);
	tp.tm_isdst = -1;
	strftime(buf, 28, "%Y-%m-%d %H:%M:%S", &tp);
	memset(timebuf, 0, ARRAY_SIZE(timebuf));
	sprintf(timebuf,"date -s '%s'",buf);
	system(timebuf);

	//==============================================
	// RTC sync
	//==============================================
	system("/sbin/hwclock -w --systohc");
}

void hanldeLogStatusNotificationResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("hanldeLogStatusNotificationResponse...\n");

	ShmOCPP20Data->SpMsg.bits.LogStatusNotificationReq = OFF;
	ShmOCPP20Data->SpMsg.bits.LogStatusNotificationConf = ON;
}

void handleMeterValuesResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("handleMeterValuesResponse...\n");
}

void handleNotifyChargingLimitResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("handleNotifyChargingLimitResponse...\n");

	ShmOCPP20Data->SpMsg.bits.NotifyChargingLimitReq = OFF;
	ShmOCPP20Data->SpMsg.bits.NotifyChargingLimitConf = ON;
}

void hanldeNotifyCustomerInformationResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("hanldeNotifyCustomerInformationResponse...\n");
}

void hanldeNotifyDisplayMessagesResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("hanldeNotifyDisplayMessagesResponse...\n");

	ShmOCPP20Data->SpMsg.bits.NotifyDisplayMessagesReq = OFF;
	ShmOCPP20Data->SpMsg.bits.NotifyDisplayMessagesConf = ON;
}

void hanldeNotifyEVChargingNeedsResponse(char *payload, int gun_index)
{
	mtrace();
	json_object *NotifyEVChargingNeeds;

	DEBUG_INFO("hanldeNotifyEVChargingNeedsResponse...\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 hanldeNotifyEVChargingScheduleResponse(char *payload, int gun_index)
{
	mtrace();
	json_object *NotifyEVChargingSchedule;

	DEBUG_INFO("hanldeNotifyEVChargingScheduleResponse...\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 hanldeNotifyEventResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("hanldeNotifyEventResponse...\n");

	ShmOCPP20Data->SpMsg.bits.NotifyEventReq = OFF;
	ShmOCPP20Data->SpMsg.bits.NotifyEventConf = ON;
}

void hanldeNotifyMonitoringReportResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("hanldeNotifyMonitoringReportResponse...\n");

	ShmOCPP20Data->SpMsg.bits.NotifyMonitoringReportReq = OFF;
	ShmOCPP20Data->SpMsg.bits.NotifyMonitoringReportConf = ON;
}

void hanldeNotifyReportResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("hanldeNotifyReportResponse...\n");
	ShmOCPP20Data->SpMsg.bits.NotifyReportReq = OFF;
	ShmOCPP20Data->SpMsg.bits.NotifyReportConf = ON;
}

void hanldePublishFirmwareStatusNotificationResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("hanldePublishFirmwareStatusNotificationResponse...\n");

	ShmOCPP20Data->CsMsg.bits[gun_index].PublishFirmwareStatusNotificationReq = OFF;
	ShmOCPP20Data->CsMsg.bits[gun_index].PublishFirmwareStatusNotificationConf = ON;
}

void hanldeReportChargingProfilesResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("hanldeReportChargingProfilesResponse...gun_index: %d\n", gun_index);

	ShmOCPP20Data->SpMsg.bits.ReportChargingProfilesReq = OFF;
	ShmOCPP20Data->SpMsg.bits.ReportChargingProfilesConf = ON;
}

void hanldeReservationStatusUpdateResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("hanldeReservationStatusUpdateResponse...gun_index: %d\n", gun_index);

	ShmOCPP20Data->CpMsg.bits[gun_index].ReservationStatusUpdateReq = OFF;
	ShmOCPP20Data->CpMsg.bits[gun_index].ReservationStatusUpdateConf = ON;
}

void hanldeSecurityEventNotificationResponse(char *payload, int gun_index)
{
	mtrace();

	DEBUG_INFO("hanldeSecurityEventNotificationResponse...\n");
	ShmOCPP20Data->SpMsg.bits.SecurityEventNotificationReq = OFF;
	ShmOCPP20Data->SpMsg.bits.SecurityEventNotificationConf = ON;
}

void hanldeSignCertificateResponse(char *payload, int gun_index)
{
	mtrace();
	json_object *SignCertificate;

	DEBUG_INFO("hanldeSignCertificateResponse...\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")));
	}
	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].StatusNotificationConf = ON;
}

void hanldeTransactionEvenResponse(char *payload, int gun_index)
{
	mtrace();
	json_object *TransactionEven;

	DEBUG_INFO("hanldeTransactionEvenResponse...\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")));
			}
		}
	}
	json_object_put(TransactionEven);

	ShmOCPP20Data->CpMsg.bits[gun_index].TransactionEventReq = OFF;
	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();
	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 ReadHttpStatus(int sock)
{
    //char c;
    char buff[1024]="",*ptr=buff+1;
    int bytes_received, status;
    DEBUG_INFO("Begin Response ..\n");
    while((bytes_received = recv(sock, ptr, 1, 0))){
        if(bytes_received==-1){
            perror("ReadHttpStatus");
            exit(1);
        }

        if((ptr[-1]=='\r')  && (*ptr=='\n' )) break;
        ptr++;
    }
    *ptr=0;
    ptr=buff+1;

    sscanf(ptr,"%*s %d ", &status);

    DEBUG_INFO("%s\n",ptr);
    DEBUG_INFO("status=%d\n",status);
    DEBUG_INFO("End Response ..\n");
    return (bytes_received>0)?status:0;

}

//the only filed that it parsed is 'Content-Length'
int ParseHeader(int sock)
{
    //char c;
    char buff[1024]="",*ptr=buff+4;
    int bytes_received;
    DEBUG_INFO("Begin HEADER ..\n");
    while((bytes_received = recv(sock, ptr, 1, 0))){
        if(bytes_received==-1){
            perror("Parse Header");
            exit(1);
        }

        if(
            (ptr[-3]=='\r')  && (ptr[-2]=='\n' ) &&
            (ptr[-1]=='\r')  && (*ptr=='\n' )
        ) break;
        ptr++;
    }

    *ptr=0;
    ptr=buff+4;
    //printf("%s",ptr);

    if(bytes_received){
        ptr=strstr(ptr,"Content-Length:");
        if(ptr){
            sscanf(ptr,"%*s %d",&bytes_received);

        }else
            bytes_received=-1; //unknown size

        DEBUG_INFO("Content-Length: %d\n",bytes_received);
    }
    DEBUG_INFO("End HEADER ..\n");
    return  bytes_received ;

}

int httpDownLoadFile(char *location, char *path, char *filename,char *url)
{
	char rmFileCmd[100]={0};
    char FilePath[100]={0};
	char ftpbuf[200];
	int systemresult;

	//DEBUG_INFO("filename=%s\n",filename);
	//DEBUG_INFO("url=%s\n",url);
	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=3 -O /mnt/%s -c %s -T 120",filename, url);
			//sprintf(ftpbuf, "ftpput -u %s -p %s %s -P %d %s%s %s",user,password,IPbuffer,21,filename,filename,path);
	systemresult = system(ftpbuf);

	//DEBUG_INFO("systemresult=%d\n",systemresult);
	if(systemresult != 0)
	{
		DEBUG_INFO("http DownLoad error!\n");
		return FALSE;
	}

	system("pkill ping");
	return TRUE;
}

int ftpDownLoadFile(char *location, char *user, char *password, int port, char *path, char *filename,char *url)
{
	char rmFileCmd[100]={0};
	char FilePath[100]={0};
	char ftpbuf[200];
	int systemresult;
	//char temp[100];
	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=3 -O /mnt/%s -c %s -T 120",filename, url);
	//sprintf(ftpbuf, "ftpget -u %s -p %s %s -P %d %s %s%s",user,password,IPbuffer,port/*21*/,filename,path,filename); --- remove temporally
	//DEBUG_INFO("ftpbuf=%s\n",ftpbuf);
		//sprintf(ftpbuf, "ftpput -u %s -p %s %s -P %d %s%s %s",user,password,IPbuffer,21,filename,filename,path);
	systemresult = system(ftpbuf);

	//DEBUG_INFO("systemresult=%d\n",systemresult);
	if(systemresult != 0)
	{
		printf("wget error!\n");
		return FALSE;
	}

	system("pkill ping");
	return TRUE;

}

int httpUploadFile(char *location, char *path, char *filename,char *url)
{
	char rmFileCmd[100]={0};
    char FilePath[100]={0};
	char ftpbuf[200];
	int systemresult;

	//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);
	}

	memset(ftpbuf, 0, ARRAY_SIZE(ftpbuf));
	sprintf(ftpbuf, "%s","/bin/php-cgi /var/www/ocpp_upload.php");
	systemresult = system(ftpbuf);

	DEBUG_INFO("systemresult = %d\n",systemresult);
	if(systemresult != 0)
	{
		DEBUG_INFO("http upload error!\n");
		return FALSE;
	}

	return TRUE;
}

int ftpFile(char *location, char *user, char *password, int port, char *path, char *fnamePlusPath,char *filename)
{
	 struct hostent* server;
	 char *IPbuffer;
	 char ftpbuf[200];
	 int systemresult;

	  // To retrieve host information
	 server = gethostbyname(location);
	 // To convert an Internet network
	 // address into ASCII string
	 IPbuffer = inet_ntoa(*((struct in_addr*)
			 	 server->h_addr_list[0]));

	memset(ftpbuf, 0, ARRAY_SIZE(ftpbuf));

	/* format : ftpput -u phihong -p y42j%2f4cj84 112.91.88.35 -P 21 /2020-02.zip ../mnt/2020-02.zip*/
	/* format : ftpput -u  username -p passwd IP  target  source*/
	sprintf(ftpbuf, "ftpput -u %s -p %s %s -P %d %s%s %s",user,password,IPbuffer,port/*21*/,path,filename,fnamePlusPath);
	DEBUG_INFO("ftpbuf=%s\n",ftpbuf);
	//sprintf(ftpbuf, "ftpput -u %s -p %s %s -P %d %s%s %s",user,password,IPbuffer,21,filename,filename,path);
	systemresult = system(ftpbuf);

	DEBUG_INFO("systemresult=%d\n",systemresult);
	if(systemresult != 0)
	{
		DEBUG_INFO("ftpput error!\n");
		return FALSE;
	}

	return TRUE;

}

//=========================================
// 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((ShmSysConfigAndInfo->SysConfig.OcppServerURL != NULL) && (strcmp((const char *)ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") != 0) )
	{
		memcpy(urlStr, ShmSysConfigAndInfo->SysConfig.OcppServerURL, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.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
	        {
	        	if((url.path[strlen(url.path)-1] != '/') && (strlen(url.path) > 0))
				{
					sprintf(OcppTempPath, "%s/", url.path);
				}
				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 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;
}

void GetStartTransactionIdTag(int gun_index)
{
	memset(StartTransactionIdTagTemp, 0 ,ARRAY_SIZE(StartTransactionIdTagTemp));
	strcpy((char *)StartTransactionIdTagTemp, (const char *)ShmOCPP20Data->TransactionEvent[gun_index].idToken.idToken);
}

int GetTransactionId(int gunindex, unsigned char idTag[], uint8_t isStopTransaction)
{
	char ch;
	FILE *fptr1;
	int temptransactionId;
	char str[100]={0};

	temptransactionId = 0;

	if((strcmp((const char*)idTag, "")==0)||(idTag[0]=='\0'))
	{
		DEBUG_INFO("IdTag is empty.\n");
		return temptransactionId;
	}

	/*------ Read the file ----------------*/
	fptr1=fopen("/Storage/OCPP/QueueTransactionId","r");
	if (!fptr1)
	{
		DEBUG_INFO("QueueTransactionId file open error.\n");
		//printf(" File not found or unable to open the input file!!\n");
		return temptransactionId;
	}

	ch=fgetc(fptr1);
	//printf(" Now the content of the file %s is : \n","/Storage/OCPP/QueueTransactionId");
	rewind(fptr1);
	if(ch!=EOF)
	{
	   // printf("%c",ch);
		while (fgets(str, 100, fptr1) != NULL)
		{
			str[strlen(str) - 1] = '\0'; // eat the newline fgets() stores

			if(str[0]=='\0')
			{
				break;
			}
			char *revbuf[8] = {0}; // Variable store string split
			int num = 0;// Quantity after string split
			DEBUG_INFO("Transaction queue data= %s\n", str);
			splitstring(str,",",revbuf,&num); // String split
			DEBUG_INFO("             revbuf[0]= %s\n", revbuf[0]);
			DEBUG_INFO("             revbuf[1]= %s\n", revbuf[1]);
			DEBUG_INFO("             revbuf[2]= %s\n", revbuf[2]);

			if((revbuf[1][0] != '\0')&&(revbuf[2][0] != '\0'))
			{
				if(isStopTransaction)
				{
					if((atoi(revbuf[0])==gunindex) && (strcmp(revbuf[1],(const char *)idTag)==0))
					{
						temptransactionId = atoi(revbuf[2]);
						break;
					}
				}
				else
				{
					if((atoi(revbuf[0])==gunindex) || (strcmp(revbuf[1],(const char *)idTag)==0))
					{
						temptransactionId = atoi(revbuf[2]);
						break;
					}
				}
			}
		}
	}
	else
		DEBUG_INFO("EOF\n");


	fclose(fptr1);
	/*------- End of reading ---------------*/
	return temptransactionId;
}

void SetTransactionIdZero(int transactionId)
{
    char ch;
    FILE *fptr1, *fptr2;
	int temptransactionId = 0;
    char str[100]={0}, strtemp[100]={0}, temp[] = "/Storage/OCPP/QueueTransactionIdtemp.json";

    fptr1 = fopen("/Storage/OCPP/QueueTransactionId", "r");
    if (!fptr1)
	{
    	//printf(" File not found or unable to open the input file!!\n");
        return ;
    }

    fptr2 = fopen(temp, "w"); // open the temporary file in write mode
    if (!fptr2)
	{
        DEBUG_INFO("Unable to open a temporary file to write!!\n");
        fclose(fptr1);
        return ;
    }

    ch=fgetc(fptr1);

    rewind(fptr1);
    if(ch!=EOF)
    {
    	// copy all contents to the temporary file except the specific line
    	while (fgets(str, 100, fptr1) != NULL)
    	{
    		str[strlen(str) - 1] = '\0'; // eat the newline fgets() stores

    		if(str[0]=='\0')
    		{
    			break;
    		}

    		char *revbuf[8] = {0};
    		int num = 0;

    		strcpy(strtemp, str);
    		splitstring(str,",",revbuf,&num);

    		if(revbuf[2][0] != '\0')
    		{
    			temptransactionId = atoi(revbuf[2]);
    			if(transactionId != temptransactionId)
    			{
    			   fprintf(fptr2, "%s\n", strtemp);
    			}
    		}
    	}
    }
    fclose(fptr1);
    fclose(fptr2);
    remove("/Storage/OCPP/QueueTransactionId");  		// remove the original file
    rename(temp, "/Storage/OCPP/QueueTransactionId"); 	// rename the temporary file to original name
/*------ Read the file ----------------*/

}

int InternetDisconnect(void)
{
	return (ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi && ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet && ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi	);
}

//Note: It is not real StopTransaction. It is temporary StopTransaction.
void storeTempStopTransaction(int gun_index)
{

}

void checkTempStopTransaction(int gun_index)
{
	FILE *fptr1;
	char ch;
	char str[QUEUE_MESSAGE_LENGTH]={0};
	char guid[37]={0};
	char tempdata[65]={0};
	char connectorStr[2]={0};
	char TempStopTransaction[256];
	sprintf(TempStopTransaction, "/Storage/OCPP/TempStopTransaction_%d", (gun_index+1));

	fptr1 = fopen(TempStopTransaction, "r");

	//TempStopTransaction格式: 槍號,StopTransaction封包
	if (!fptr1)
	{
		//printf(" File not found or unable to open the input file!!\n");
	    return ;
	}

	ch=fgetc(fptr1);
	//printf(" Now the content of the file %s is : \n",fname);

	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;
			}

			//TempStopTransaction格式: 槍號,StopTransaction封包
			strncpy(connectorStr, str, 1);
			if(atoi(connectorStr) != (gun_index+1))
			{
				DEBUG_INFO("atoi(connectorStr) = %d, gun_index = %d\n", atoi(connectorStr), gun_index);
				fclose(fptr1);
				return ;
			}

			//random_uuid(guid);
			strncpy(guid, str+6, 36); //copy guid
			sprintf(tempdata, "StopTransaction,%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
}

void FillStartTransaction(int ConnectorId, unsigned char IdTag[], int MeterStart,int ReservationId,unsigned char Timestamp[])
{
	ShmOCPP20Data->TransactionEvent[ConnectorId-1].evse.connectorId = ConnectorId;
	ShmOCPP20Data->TransactionEvent[ConnectorId-1].reservationId = ReservationId;
	//ShmOCPP20Data->TransactionEvent[ConnectorId-1].MeterStart = MeterStart;
	strcpy((char *)ShmOCPP20Data->TransactionEvent[ConnectorId-1].idToken.idToken, (char *)IdTag);
	strcpy((char *)ShmOCPP20Data->TransactionEvent[ConnectorId-1].timestamp,(char *) Timestamp);
}

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", ShmOCPP20Data->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;
}

void InitialSystemValue(void)
{
	int connectorIndex = 0;
	gunTotalNumber=0;
	SystemInitial = 0;
	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));
	memset(gunType, 0, ARRAY_SIZE(gunType));

	if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D') // 'D' means DC
	{
		if(ShmSysConfigAndInfo->SysConfig.ModelName[1]=='O')
		{
			// DO series
			for(int index=0; index<GENERAL_GUN_QUANTITY ; index++)
			{
				SystemInitial = SystemInitial + 1;
				gunTotalNumber = gunTotalNumber + 1;
				gunType[connectorIndex] = 'O';
				connectorIndex = connectorIndex + 1;
			}
		}
		else
		{
			// DM, DW, DS series
			//check connector / socket type (index: 8, 9, 10)
			for(int index=7; index <10 ; index++)
			{
				if(index != 8)
				{
					// DC Connector
					if ((ShmSysConfigAndInfo->SysConfig.ModelName[index]  >= 'A') && (ShmSysConfigAndInfo->SysConfig.ModelName[index] <= 'Z'))
					{
						SystemInitial = SystemInitial + 1;
						gunTotalNumber = gunTotalNumber + 1;
						gunType[connectorIndex] = ShmSysConfigAndInfo->SysConfig.ModelName[index];
						connectorIndex = connectorIndex + 1;
					}
				}
				else
				{
					// AC Connector
					if ((ShmSysConfigAndInfo->SysConfig.ModelName[index] > '0') && (ShmSysConfigAndInfo->SysConfig.ModelName[index] <= '9'))
					{
						SystemInitial = SystemInitial + 1;
						gunTotalNumber = gunTotalNumber + 1;
						gunType[connectorIndex] = ShmSysConfigAndInfo->SysConfig.ModelName[index];
						connectorIndex = connectorIndex + 1;
					}
				}
			}
		}

		//DEBUG_INFO("DC ...\n");
	}
	else if (ShmSysConfigAndInfo->SysConfig.ModelName[0]=='A') //'A' means AC
	{
		//check connector / socket type (index: 8, 9, 10)
		for(int index=7; index <10 ; index++)
		{
			if ((ShmSysConfigAndInfo->SysConfig.ModelName[index] > '0') && (ShmSysConfigAndInfo->SysConfig.ModelName[index] <= '9'))
			{
				SystemInitial = SystemInitial + 1;
				gunTotalNumber = gunTotalNumber + 1;
				gunType[connectorIndex] = ShmSysConfigAndInfo->SysConfig.ModelName[index];
				connectorIndex = connectorIndex + 1;

				//DEBUG_INFO("AC: %d, %c\n", index, ShmSysConfigAndInfo->SysConfig.ModelName[index]);
			}
		}
	}

	//Status &&  ConnectorPlugIn Setting
	for (int index = 0; index < CHAdeMO_QUANTITY; index++)
	{
		ChademoPreviousSystemStatus[index]= ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].PreviousSystemStatus;
		ChademoPreviousConnectorPlugIn[index] = ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].ConnectorPlugIn;
	}

	for (int index = 0; index < CCS_QUANTITY; index++)
	{
		CcsPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].PreviousSystemStatus;
		CcsPreviousConnectorPlugIn[index] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].ConnectorPlugIn;
	}

	for (int index = 0; index < GB_QUANTITY; index++)
	{
		GbPreviousSystemStatus[index] = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].PreviousSystemStatus;
		GbPreviousConnectorPlugIn[index] = ShmSysConfigAndInfo->SysInfo.GbChargingData[index].ConnectorPlugIn;
	}

	for (int index = 0; index < AC_QUANTITY; index++)
	{
		AcPreviousSystemStatus[index]= ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PreviousSystemStatus;
		AcPreviousConnectorPlugIn[index] = ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState;
	}

	for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
	{
		DoPreviousSystemStatus[index]= 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].StatusNotificationReq = OFF;
		cpinitateMsg.bits[gun_index].StatusNotificationConf = OFF;
		//clientTime.MeterValues[gun_index] = time((time_t*)NULL);
		clientTime.StatusNotification[gun_index] = time((time_t*)NULL);
	}
	clientTime.Heartbeat=time((time_t*)NULL);

	sleep(1);
}

void LWS_Send(char * str)
{
	//=====================================================
	// Check InternetConn 0: disconnected, 1: connected
	//====================================================
	if(ShmSysConfigAndInfo->SysInfo.InternetConn == 0)
	{
		DEBUG_INFO("offline  now !!!\n");
		return;
	}

	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(ShmSysConfigAndInfo->SysInfo.InternetConn == 0)
	{
		DEBUG_INFO("offline  now !!!\n");
		return;
	}

	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);
}