/*
 * Module_DcMeter.c 
 *
 *  Created on: 2021/5/31 
 *      Author: foluswen
 */
#include "Module_DcMeter.h"
#include "meterComm.h"
#include "Module_RatedCurrent.h"

#define _DEBUG_ 0

#if _DEBUG_
#define PR(...) printf(__VA_ARGS__)
#else
#define PR(...)
#endif

/**
 * Initial share memory  
 * @return
 */
int InitShareMemory()
{
	int result = PASS;
	int MeterSMId;

	//Initialize 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
    {}

   	//Initialize ShmStatusCodeData
   	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
    {}

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






//==========================================
// Main loop
//==========================================
int main(void)
{
	printf("main start\n");
	ParsingRatedCur modelnameInfo = {0};
	Meter_Info meter_info[4];
	Meter_Status_Info meter_status_info[4];
	Meter_transaction_Action meter_read_transaction_record[4];
	Meter_transaction_Action meter_transaction_Action[4];
	Meter_transaction_Result meter_transaction_Result[4];
	//log use
	Meter_Info before_meter_info[4];
	uint8_t before_failCount[4];
	Meter_transaction_Action before_meter_transaction_Action[4];
	Meter_transaction_Action before_meter_read_transaction_record[4];
	
	uint8_t failCount[4];
	uint8_t startTransactionFailCount[4];
	uint8_t stopTransactionFailCount[4];
	uint8_t getTransactionOcmfFailCount[4];
	uint8_t meterSyncTimeFailCount[4];
	uint16_t RecordLogTimerCount = 0;

#ifndef DEBUG_STANDALONG

	// Initialize share memory
	if(InitShareMemory() == FAIL)
	{
		DEBUG_ERROR("InitShareMemory NG\n");

		if(ShmStatusCodeData!=NULL)
		{
			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=ON;
		}
		sleep(5);
		return -1;
	}
	
	/*
	for(;;)
	{
		printf("ActionCmd : %d \n", ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[0].ActionCmd);
		sleep(1);
	}
	*/

	RatedCurrentParsing((char*)ShmSysConfigAndInfo->SysConfig.ModelName, &modelnameInfo);

#else
	modelnameInfo.GetGunCount = 1;

#endif//DEBUG_STANDALONG

	
	// Initialize DC meter model
	/*
	 *	TODO:
	 *		1. Maybe need to parse configuration by model name
	 */
	meterInitialize(METER_MODEL_LEM_L18005A);
	
	
	//DEBUG_INFO("modelnameInfo.GetGunCount : %d \n", modelnameInfo.GetGunCount);
	#ifndef DEBUG_STANDALONG
	//if Power up and DC meter is runing (need stop)
	for(uint8_t gun_index=0;gun_index<modelnameInfo.GetGunCount;gun_index++){
		
		readMeterStatusInfo(gun_index,&meter_status_info[gun_index]);
		if(meter_status_info[gun_index].MeterStatusFlag.bits.transactionIsOnGoing == 1)
		{
			ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].ActionCmd = 2;
			readMeterLegal(gun_index,&meter_transaction_Action[gun_index]);
			strcpy((char*)ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].head.transactionId,(char*)meter_transaction_Action[gun_index].head.transactionId);
		}
	}
	
		printf("shm ");
	DEBUG_INFO("shm ");
	#endif
	
	printf("modelnameInfo.GetGunCount : %d \n\n\n", modelnameInfo.GetGunCount);
	DEBUG_INFO("modelnameInfo.GetGunCount : %d \n\n\n", modelnameInfo.GetGunCount);
	

	
	//uint8_t gun_index=0;
	//meter_transaction_Action[0].ActionCmd = 2;
	//strcpy(meter_transaction_Action[0].head.transactionId, "ddd5002");	

	//strcpy(ShmSysConfigAndInfo->SysInfo.DcMeterReadTransactionRecord[0].head.transactionId, "12345678" );
	//ShmSysConfigAndInfo->SysInfo.DcMeterReadTransactionRecord[0].ActionCmd = 1;
	
	// Main loop
	for(;;)
	{
		for(uint8_t gun_index=0;gun_index<modelnameInfo.GetGunCount;gun_index++)
		{

			if(modelnameInfo.ParsingInfo[gun_index].GunType != Gun_Type_AC)
			{
					#ifndef DEBUG_STANDALONG
					meter_transaction_Action[gun_index].ActionCmd = ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].ActionCmd;
					meter_read_transaction_record[gun_index].ActionCmd = ShmSysConfigAndInfo->SysInfo.DcMeterReadTransactionRecord[gun_index].ActionCmd;
					meter_read_transaction_record[gun_index].OcmfInfoReady = ShmSysConfigAndInfo->SysInfo.DcMeterReadTransactionRecord[gun_index].OcmfInfoReady;
					meter_transaction_Action[gun_index].OcmfInfoReady = ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].OcmfInfoReady;
					
					if(before_meter_transaction_Action[gun_index].ActionCmd != ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].ActionCmd || 
					before_meter_transaction_Action[gun_index].OcmfInfoReady != ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].OcmfInfoReady ||
					before_meter_read_transaction_record[gun_index].ActionCmd != ShmSysConfigAndInfo->SysInfo.DcMeterReadTransactionRecord[gun_index].ActionCmd || 
					before_meter_read_transaction_record[gun_index].OcmfInfoReady != ShmSysConfigAndInfo->SysInfo.DcMeterReadTransactionRecord[gun_index].OcmfInfoReady ||
					before_meter_info[gun_index].LinkStatus != meter_info[gun_index].LinkStatus || 
					before_failCount[gun_index] != failCount[gun_index])
					{
						DEBUG_INFO("shm Meter %d - LinkStatus %d :  failCount: %d   ActionCmd: %d  OcmpInfoReady: %d RecordActionCmd: %d RecordOcmpInfoReady: %d \n", gun_index, 
						meter_info[gun_index].LinkStatus,failCount[gun_index] ,
						ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].ActionCmd ,
						ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].OcmfInfoReady,
						ShmSysConfigAndInfo->SysInfo.DcMeterReadTransactionRecord[gun_index].ActionCmd ,
						ShmSysConfigAndInfo->SysInfo.DcMeterReadTransactionRecord[gun_index].OcmfInfoReady);
						
						before_meter_transaction_Action[gun_index].ActionCmd = ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].ActionCmd;
						before_meter_transaction_Action[gun_index].OcmfInfoReady = ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].OcmfInfoReady;
						before_meter_read_transaction_record[gun_index].ActionCmd = ShmSysConfigAndInfo->SysInfo.DcMeterReadTransactionRecord[gun_index].ActionCmd;
						before_meter_read_transaction_record[gun_index].OcmfInfoReady = ShmSysConfigAndInfo->SysInfo.DcMeterReadTransactionRecord[gun_index].OcmfInfoReady;
						before_meter_info[gun_index].LinkStatus = meter_info[gun_index].LinkStatus;
						before_failCount[gun_index] = failCount[gun_index];
					}
					#endif
					
					
					
					PR("for index : %d \n", gun_index);
					//if Transaction Cmd				
					if(meter_transaction_Action[gun_index].ActionCmd || meter_read_transaction_record[gun_index].ActionCmd)
					{
							//if start Transaction record
							if(meter_transaction_Action[gun_index].ActionCmd == 1)
							{
									PR("<<<<<<<<<  meter_sync_time : %d  >>>>>>>>>\n", gun_index);
									//first sync sys time
									if(configure_meter_time(gun_index) != FAIL)
									{
											
											//update transaction content
											#ifndef DEBUG_STANDALONG											
											strcpy((char*)meter_transaction_Action[gun_index].head.evseId, (char*)ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].head.evseId);
											strcpy((char*)meter_transaction_Action[gun_index].head.transactionId,  (char*)ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].head.transactionId);
											strcpy((char*)meter_transaction_Action[gun_index].head.clientId,  (char*)ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].head.clientId);
											meter_transaction_Action[gun_index].head.tariffId =  ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].head.tariffId;
											meter_transaction_Action[gun_index].head.cableId = ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].head.cableId;
											strcpy((char*)meter_transaction_Action[gun_index].head.userData,  (char*)ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].head.userData);
											#else
											strcpy(meter_transaction_Action[gun_index].head.evseId, "evse45");
											strcpy(meter_transaction_Action[gun_index].head.transactionId, "ddd5002");
											strcpy(meter_transaction_Action[gun_index].head.clientId, "client1");
											meter_transaction_Action[gun_index].head.tariffId = 2;
											meter_transaction_Action[gun_index].head.cableId =3;
											strcpy(meter_transaction_Action[gun_index].head.userData, "Phihong12");
											#endif

											PR(" ****** evseId : %s\n",meter_transaction_Action[gun_index].head.evseId);	
											PR(" ****** transactionId : %s\n",meter_transaction_Action[gun_index].head.transactionId);	
											PR(" ****** clientId : %s\n",meter_transaction_Action[gun_index].head.clientId);	
											PR(" ****** tariffId : %d\n",meter_transaction_Action[gun_index].head.tariffId);
											PR(" ****** clientId : %d\n",meter_transaction_Action[gun_index].head.cableId);
											PR(" ****** userData : %s\n",meter_transaction_Action[gun_index].head.userData);
																						
																						
											meterSyncTimeFailCount[gun_index] = 0;
											#ifndef DEBUG_STANDALONG
											ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MeterSyncTimeError = OFF;
											#endif 
											
											PR("<<<<<<<<<  meter_transaction_Action : %d  >>>>>>>>>\n", gun_index);
											//start Transaction
											if(startMeterTransaction(gun_index,&meter_transaction_Action[gun_index]) != FAIL)
											{
														#ifndef DEBUG_STANDALONG
														/*
														 *	TODO:
														 *		1. Synchronize data to share memory
														 */
														//clear ocmf value
														strcpy((char *) meter_transaction_Action[gun_index].transactionOCMF, "");
														sprintf((char*)&ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].transactionOCMF,
															"%s",meter_transaction_Action[gun_index].transactionOCMF);
															
														 #ifdef DEBUG_SHAREMEM_TRANSACTION_START_LOG

														 #endif
														 
														#else

														#endif//DEBUG_STANDALONG
														
														//clear OCMF info flag
														meter_transaction_Action[gun_index].OcmfInfoReady = 0;
							
														failCount[gun_index] = 0;
														startTransactionFailCount[gun_index] = 0;														
														#ifndef DEBUG_STANDALONG
														ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MetertStartTransactionError = OFF;
														#endif

														//clear need action cmd
														meter_transaction_Action[gun_index].ActionCmd = 0;
														
											}
											else
											{
														if(failCount[gun_index] < 5){
															failCount[gun_index]++;
														}
														
														if(startTransactionFailCount[gun_index] < 5){
															startTransactionFailCount[gun_index]++;
														}else{
															meter_transaction_Action[gun_index].ActionCmd = 0;
															#ifndef DEBUG_STANDALONG
															ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MetertStartTransactionError = ON;
															#endif
														}
											}
										}
										else
										{
												if(failCount[gun_index] < 5){
													failCount[gun_index]++;
												}
												
												if(meterSyncTimeFailCount[gun_index] < 5){
													meterSyncTimeFailCount[gun_index]++;
												}else{
													meter_transaction_Action[gun_index].ActionCmd = 0;
													#ifndef DEBUG_STANDALONG
													ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MeterSyncTimeError = ON;
													#endif 
														
												}
										}							
							}

							//if stop Transaction and record
							if(meter_transaction_Action[gun_index].ActionCmd == 2)
							{
									PR("<<<<<<<<<  stopMeterTransaction : %d >>>>>>>>>\n", gun_index);
									if(stopMeterTransaction(gun_index,&meter_transaction_Action[gun_index],&meter_transaction_Result[gun_index]) != FAIL)
									{
												#ifndef DEBUG_STANDALONG
												/*
												 *	TODO:
												 *		1. Synchronize data to share memory
												 */
												 
												 ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].paginationCounter = 
												 meter_transaction_Result[gun_index].paginationCounter;
												 
												sprintf((char*)&ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].head.transactionId,
												"%s",meter_transaction_Result[gun_index].head.transactionId);										 
												 
												sprintf((char*)&ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].head.evseId,
												"%s",meter_transaction_Result[gun_index].head.evseId);										 

												sprintf((char*)&ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].head.clientId,
												"%s",meter_transaction_Result[gun_index].head.clientId);										 
												 
												ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].head.tariffId = 
												meter_transaction_Result[gun_index].head.tariffId;	
												
												ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].head.cableId = 
												meter_transaction_Result[gun_index].head.cableId;	

												sprintf((char*)&ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].head.userData,
												"%s",meter_transaction_Result[gun_index].head.userData);										 
												 
												sprintf((char*)&ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].timestampStart,
												"%s",meter_transaction_Result[gun_index].timestampStart);
												
												sprintf((char*)&ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].timestampStop,
												"%s",meter_transaction_Result[gun_index].timestampStop);
												
												 ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].transactionDuration = 
												 meter_transaction_Result[gun_index].transactionDuration;
												
												 ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].transactionStatus = 
												 meter_transaction_Result[gun_index].transactionStatus;
												
												sprintf((char*)&ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].energyUnit,
												"%s",meter_transaction_Result[gun_index].energyUnit);
												
												 ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].energyImport = 
												 meter_transaction_Result[gun_index].energyImport;

												 ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].energyImportTotalStart = 
												 meter_transaction_Result[gun_index].energyImportTotalStart;										

												 ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].energyImportTotalStop = 
												 meter_transaction_Result[gun_index].energyImportTotalStop;

												 ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].energyExport = 
												 meter_transaction_Result[gun_index].energyExport;
												 
												 ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].energyExportTotalStart = 
												 meter_transaction_Result[gun_index].energyExportTotalStart;

												 ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].energyExportTotalStop = 
												 meter_transaction_Result[gun_index].energyExportTotalStop;
												 
												sprintf((char*)&ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].signature,
												"%s",meter_transaction_Result[gun_index].signature);										 
												 
			
														#ifdef DEBUG_SHAREMEM_TRANSACTION_RESULT_LOG
														DEBUG_INFO(" ================================= ShareMem Transaction Result : %d ================================= \n",gun_index);
														DEBUG_INFO(" %-26s : %d\n", "paginationCounter", ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].paginationCounter);										
														DEBUG_INFO(" %-26s : %s\n", "transactionId", ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].head.transactionId);										
														DEBUG_INFO(" %-26s : %s\n", "evseId", ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].head.evseId);										
														DEBUG_INFO(" %-26s : %s\n", "clientId", ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].head.clientId);										
														DEBUG_INFO(" %-26s : %d\n", "tariffId", ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].head.tariffId);
														DEBUG_INFO(" %-26s : %d\n", "cableId", ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].head.cableId);
														DEBUG_INFO(" %-26s : %s\n", "userData", ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].head.userData);										
														DEBUG_INFO(" %-26s : %s\n", "timestampStart", ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].timestampStart);
														DEBUG_INFO(" %-26s : %s\n", "timestampStop", ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].timestampStop);
														DEBUG_INFO(" %-26s : %d\n", "transactionDuration", ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].transactionDuration);
														DEBUG_INFO(" %-26s : %d\n", "transactionStatus", ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].transactionStatus);
														DEBUG_INFO(" %-26s : %s\n", "energyUnit", ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].energyUnit);
														DEBUG_INFO(" %-26s : %.3f\n", "energyImport", ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].energyImport);
														DEBUG_INFO(" %-26s : %.3f\n", "energyImportTotalStart", ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].energyImportTotalStart);
														DEBUG_INFO(" %-26s : %.3f\n", "energyImportTotalStop", ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].energyImportTotalStop);
														DEBUG_INFO(" %-26s : %.3f\n", "energyExport", ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].energyExport);
														DEBUG_INFO(" %-26s : %.3f\n", "energyExportTotalStart", ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].energyExportTotalStart);
														DEBUG_INFO(" %-26s : %.3f\n", "energyExportTotalStop", ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].energyExportTotalStop);
														DEBUG_INFO(" %-26s : %s\n\n\n\n\n\n", "signature", ShmSysConfigAndInfo->SysInfo.DcMeterTransactionResult[gun_index].signature);												
														#endif
												 
												#else	//DEBUG_STANDALONG
												
														#ifdef DEBUG_STANDALONE_TRANSACTION_RESULT_LOG
														DEBUG_INFO(" ================================= Standalone Transaction Result : %d ================================= \n",gun_index);
														DEBUG_INFO(" %-26s : %d\n", "paginationCounter", meter_transaction_Result[gun_index].paginationCounter);										
														DEBUG_INFO(" %-26s : %s\n", "transactionId", meter_transaction_Result[gun_index].head.transactionId);										
														DEBUG_INFO(" %-26s : %s\n", "evseId", meter_transaction_Result[gun_index].head.evseId);										
														DEBUG_INFO(" %-26s : %s\n", "clientId", meter_transaction_Result[gun_index].head.clientId);										
														DEBUG_INFO(" %-26s : %d\n", "tariffId", meter_transaction_Result[gun_index].head.tariffId);
														DEBUG_INFO(" %-26s : %d\n", "cableId", meter_transaction_Result[gun_index].head.cableId);
														DEBUG_INFO(" %-26s : %s\n", "userData", meter_transaction_Result[gun_index].head.userData);										
														DEBUG_INFO(" %-26s : %s\n", "timestampStart", meter_transaction_Result[gun_index].timestampStart);
														DEBUG_INFO(" %-26s : %s\n", "timestampStop", meter_transaction_Result[gun_index].timestampStop);
														DEBUG_INFO(" %-26s : %d\n", "transactionDuration", meter_transaction_Result[gun_index].transactionDuration);
														DEBUG_INFO(" %-26s : %d\n", "transactionStatus", meter_transaction_Result[gun_index].transactionStatus);
														DEBUG_INFO(" %-26s : %s\n", "energyUnit", meter_transaction_Result[gun_index].energyUnit);
														DEBUG_INFO(" %-26s : %.3f\n", "energyImport", meter_transaction_Result[gun_index].energyImport);
														DEBUG_INFO(" %-26s : %.3f\n", "energyImportTotalStart", meter_transaction_Result[gun_index].energyImportTotalStart);
														DEBUG_INFO(" %-26s : %.3f\n", "energyImportTotalStop", meter_transaction_Result[gun_index].energyImportTotalStop);
														DEBUG_INFO(" %-26s : %.3f\n", "energyExport", meter_transaction_Result[gun_index].energyExport);
														DEBUG_INFO(" %-26s : %.3f\n", "energyExportTotalStart", meter_transaction_Result[gun_index].energyExportTotalStart);
														DEBUG_INFO(" %-26s : %.3f\n", "energyExportTotalStop", gun_index, meter_transaction_Result[gun_index].energyExportTotalStop);
														DEBUG_INFO(" %-26s : %s\n\n\n\n\n\n", "signature", meter_transaction_Result[gun_index].signature);
														#endif
														
												#endif	//DEBUG_STANDALONG
					
												failCount[gun_index] = 0;
												stopTransactionFailCount[gun_index] = 0;
												#ifndef DEBUG_STANDALONG
												ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MetertStopTransactionError = OFF;
												#endif 
													
												PR("<<<<<<<<<  Get Transaction OCMF : %d >>>>>>>>>\n", gun_index);
												//auto OCMF
												if(readMeterTransactionOCMF(gun_index,&meter_transaction_Action[gun_index]) != FAIL)
												{
															#ifndef DEBUG_STANDALONG
															/*
															 *	TODO:
															 *		1. Synchronize data to share memory
															 */
															 
														
															sprintf((char*)&ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].transactionOCMF,
															"%s",meter_transaction_Action[gun_index].transactionOCMF);
															
															PR("OCMF : %s , %s\n", ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].transactionOCMF,
																				   meter_transaction_Action[gun_index].transactionOCMF);
															
																	#ifdef DEBUG_SHAREMEM_TRANSACTION_RESULT_LOG
																	DEBUG_INFO("shm transactionOCMF %d : %s\n", gun_index, ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].transactionOCMF);															
																	DEBUG_INFO("shm publicKeyOCMF   %d : %s\n\n\n", gun_index, ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].publicKeyOcmf);
																	#endif
															 
															#else	//DEBUG_STANDALONG
															
																PR("OCMF : %s\n",meter_transaction_Action[gun_index].transactionOCMF);
																				   
																	#ifdef DEBUG_STANDALONE_TRANSACTION_RESULT_LOG
																	DEBUG_INFO("transactionOCMF %d : %s\n", gun_index, meter_transaction_Action[gun_index].transactionOCMF);
																	#endif	
																													
															#endif//DEBUG_STANDALONG	
															
															meter_transaction_Action[gun_index].OcmfInfoReady = 1;
					
															failCount[gun_index] = 0;
															getTransactionOcmfFailCount[gun_index] = 0;
															meter_transaction_Action[gun_index].ActionCmd = 0;
															#ifndef DEBUG_STANDALONG
															ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MetertGetTransactionOcmfError = OFF;
															#endif 
												}
												else
												{
													
															meter_transaction_Action[gun_index].OcmfInfoReady = 0;
															
															if(failCount[gun_index] < 5){
																failCount[gun_index]++;
															}
															
															if(getTransactionOcmfFailCount[gun_index] < 5){
																getTransactionOcmfFailCount[gun_index]++;
															}else{
																meter_transaction_Action[gun_index].ActionCmd = 0;
																#ifndef DEBUG_STANDALONG
																ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MetertGetTransactionOcmfError = ON;
																#endif 																	
															}
												}				
									}
									else
									{
												if(failCount[gun_index] < 5){
													failCount[gun_index]++;
												}
												
												if(stopTransactionFailCount[gun_index] < 5){
													stopTransactionFailCount[gun_index]++;
												}else{
													meter_transaction_Action[gun_index].ActionCmd = 0;
													#ifndef DEBUG_STANDALONG
													ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MetertStopTransactionError = ON;
													#endif 
														
												}
									}
							}


							//if stop Transaction and record
							if(meter_read_transaction_record[gun_index].ActionCmd == 1)
							{
												meter_read_transaction_record[gun_index].OcmfInfoReady = 0;
												
												#ifndef DEBUG_STANDALONG
												strcpy((char*)meter_read_transaction_record[gun_index].head.transactionId,  (char*)ShmSysConfigAndInfo->SysInfo.DcMeterReadTransactionRecord[gun_index].head.transactionId);
												#endif
												
												PR("<<<<<<<<<  Get Record Transaction OCMF : %d - ID : %s>>>>>>>>>\n", gun_index,meter_read_transaction_record[gun_index].head.transactionId);
												//auto OCMF
												if(readMeterTransactionOCMF(gun_index,&meter_read_transaction_record[gun_index]) != FAIL)
												{
															#ifndef DEBUG_STANDALONG
															/*
															 *	TODO:
															 *		1. Synchronize data to share memory
															 */
															 
														
															sprintf((char*)&ShmSysConfigAndInfo->SysInfo.DcMeterReadTransactionRecord[gun_index].transactionOCMF,
															"%s",meter_read_transaction_record[gun_index].transactionOCMF);
															
															PR("OCMF : %s ,%s\n", ShmSysConfigAndInfo->SysInfo.DcMeterReadTransactionRecord[gun_index].transactionOCMF,
																	      	   	  meter_read_transaction_record[gun_index].transactionOCMF);

															
																	#ifdef DEBUG_SHAREMEM_TRANSACTION_RESULT_LOG
																	DEBUG_INFO("shm record transactionOCMF %d : %s\n", gun_index, ShmSysConfigAndInfo->SysInfo.DcMeterReadTransactionRecord[gun_index].transactionOCMF);															
																	DEBUG_INFO("shm record publicKeyOCMF   %d : %s\n\n\n", gun_index, ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].publicKeyOcmf);
																	#endif
																	 
																	#else
																			#ifdef DEBUG_STANDALONE_TRANSACTION_RESULT_LOG
																			DEBUG_INFO("transactionOCMF %d : %s\n", gun_index, meter_read_transaction_record[gun_index].transactionOCMF);
																			#endif													
																	#endif//DEBUG_STANDALONG	
																	
																	meter_read_transaction_record[gun_index].OcmfInfoReady = 1;
							
																	failCount[gun_index] = 0;
																	getTransactionOcmfFailCount[gun_index] = 0;
																	meter_read_transaction_record[gun_index].ActionCmd = 0;
																	#ifndef DEBUG_STANDALONG
																	ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MetertGetTransactionOcmfError = OFF;
																	#endif 
												}
												else
												{
													
															meter_read_transaction_record[gun_index].OcmfInfoReady = 0;
															
															if(failCount[gun_index] < 5){
																failCount[gun_index]++;
															}
															
															if(getTransactionOcmfFailCount[gun_index] < 5){
																getTransactionOcmfFailCount[gun_index]++;
															}else{
																meter_read_transaction_record[gun_index].ActionCmd = 0;
																getTransactionOcmfFailCount[gun_index] = 0;
																#ifndef DEBUG_STANDALONG
																meter_read_transaction_record[gun_index].OcmfInfoReady = 2;
																//ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MetertGetTransactionOcmfError = ON;
																#endif 																	
															}
												}	


								
							}
														
							#ifndef DEBUG_STANDALONG
							ShmSysConfigAndInfo->SysInfo.DcMeterReadTransactionRecord[gun_index].ActionCmd = meter_read_transaction_record[gun_index].ActionCmd;
							ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].ActionCmd = meter_transaction_Action[gun_index].ActionCmd;
							ShmSysConfigAndInfo->SysInfo.DcMeterReadTransactionRecord[gun_index].OcmfInfoReady = meter_read_transaction_record[gun_index].OcmfInfoReady;
							ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].OcmfInfoReady = meter_transaction_Action[gun_index].OcmfInfoReady;
							#endif
						
					}					
					else
					{		

							if(readMeterLivemeasure(gun_index,&meter_info[gun_index]) != FAIL)
							{
										#ifndef DEBUG_STANDALONG
										/*
										 *	TODO:
										 *		1. Synchronize data to share memory
										 */
										ShmSysConfigAndInfo->SysInfo.DcMeterInfo[gun_index].presetVoltage = meter_info[gun_index].presetVoltage;
										ShmSysConfigAndInfo->SysInfo.DcMeterInfo[gun_index].presentCurrent = meter_info[gun_index].presentCurrent;
										ShmSysConfigAndInfo->SysInfo.DcMeterInfo[gun_index].presentPower = meter_info[gun_index].presentPower;
										ShmSysConfigAndInfo->SysInfo.DcMeterInfo[gun_index].totlizeImportEnergy = meter_info[gun_index].totlizeImportEnergy;
										ShmSysConfigAndInfo->SysInfo.DcMeterInfo[gun_index].totlizeExportEnergy = meter_info[gun_index].totlizeExportEnergy;
										sprintf((char*)&ShmSysConfigAndInfo->SysInfo.DcMeterInfo[gun_index].timestamp, "%s",meter_info[gun_index].timestamp);
										 
											#ifdef DEBUG_SHAREMEM_LIVEMEASURE_LOG
											//evern 60s record 1s
											if((RecordLogTimerCount % 60 == 0)
											{
											DEBUG_INFO(" ================================= ShareMem Livemeasure : %d ================================= \n",gun_index);
											DEBUG_INFO(" %-26s : %.3f V\n", "Output voltage", ShmSysConfigAndInfo->SysInfo.DcMeterInfo[gun_index].presetVoltage);
											DEBUG_INFO(" %-26s : %.3f A\n", "Output current", ShmSysConfigAndInfo->SysInfo.DcMeterInfo[gun_index].presentCurrent);
											DEBUG_INFO(" %-26s : %.3f kw\n", "Output power", ShmSysConfigAndInfo->SysInfo.DcMeterInfo[gun_index].presentPower);
											DEBUG_INFO(" %-26s : %.3f kwh\n", "Totalize import energy", ShmSysConfigAndInfo->SysInfo.DcMeterInfo[gun_index].totlizeImportEnergy);
											DEBUG_INFO(" %-26s : %.3f kwh\n", "Totalize export energy", ShmSysConfigAndInfo->SysInfo.DcMeterInfo[gun_index].totlizeExportEnergy);
											DEBUG_INFO(" %-26s : %s\n\n\n\n\n\n", "timestamp", ShmSysConfigAndInfo->SysInfo.DcMeterInfo[gun_index].timestamp);
											}
											#endif
										 
										#else
										
											#ifdef DEBUG_STANDALONE_LIVEMEASURE_LOG
											DEBUG_INFO(" ================================= Standalone Livemeasure : %d ================================= \n",gun_index);
											DEBUG_INFO(" %-26s : %.3f V\n", "Output voltage", meter_info[gun_index].presetVoltage);
											DEBUG_INFO(" %-26s : %.3f A\n", "Output current", meter_info[gun_index].presentCurrent);
											DEBUG_INFO(" %-26s : %.3f kw\n", "Output power", meter_info[gun_index].presentPower);
											DEBUG_INFO(" %-26s : %.3f kwh\n", "Totalize import energy", meter_info[gun_index].totlizeImportEnergy);   
											DEBUG_INFO(" %-26s : %.3f kwh\n", "Totalize export energy", meter_info[gun_index].totlizeExportEnergy);
											DEBUG_INFO(" %-26s : %s\n\n\n\n\n\n", "timestamp", meter_info[gun_index].timestamp);
											#endif
											
										#endif//DEBUG_STANDALONG
			
										failCount[gun_index] = 0;
							}
							else
							{
										PR("read Livemeasure fail : %d \n", gun_index);
										if(failCount[gun_index] < 5)
											failCount[gun_index]++;
							}


							if(readMeterStatusInfo(gun_index,&meter_status_info[gun_index]) != FAIL)
							{
										//PR("run readMeterStatusInfo : %d \n", gun_index);
										#ifndef DEBUG_STANDALONG
										/*
										 *	TODO:
										 *		1. Synchronize data to share memory
										 */
										ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].StatusValue = meter_status_info[gun_index].StatusValue;
										 
										ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterStatusFlag.bits.suLinkStatusIsOk = 
										meter_status_info[gun_index].MeterStatusFlag.bits.suLinkStatusIsOk;

										ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterStatusFlag.bits.muFatalErrorOccured = 
										meter_status_info[gun_index].MeterStatusFlag.bits.muFatalErrorOccured;
										 
										ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterStatusFlag.bits.transactionIsOnGoing = 
										meter_status_info[gun_index].MeterStatusFlag.bits.transactionIsOnGoing;

										ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterStatusFlag.bits.tamperingIsDetected = 
										meter_status_info[gun_index].MeterStatusFlag.bits.tamperingIsDetected;

										ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterStatusFlag.bits.timeSyncStatusIsOk = 
										meter_status_info[gun_index].MeterStatusFlag.bits.timeSyncStatusIsOk;
										 
										ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterStatusFlag.bits.overTemperatureIsDetected = 
										meter_status_info[gun_index].MeterStatusFlag.bits.overTemperatureIsDetected;
										 
										ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterStatusFlag.bits.reversedVoltage = 
										meter_status_info[gun_index].MeterStatusFlag.bits.reversedVoltage;
										 
										ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterStatusFlag.bits.suMeasureFailureOccurred = 
										meter_status_info[gun_index].MeterStatusFlag.bits.suMeasureFailureOccurred;
										 								 
										sprintf((char*)&ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].applicationFirmwareVersion,
										"%s",meter_status_info[gun_index].applicationFirmwareVersion);
										  
										sprintf((char*)&ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].applicationFirmwareAuthTag,
										"%s",meter_status_info[gun_index].applicationFirmwareAuthTag);
										 
										sprintf((char*)&ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].legalFirmwareVersion,
										"%s",meter_status_info[gun_index].legalFirmwareVersion);
										
										sprintf((char*)&ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].legalFirmwareAuthTag,
										"%s",meter_status_info[gun_index].legalFirmwareAuthTag);
										 
										sprintf((char*)&ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].sensorFirmwareVersion,
										"%s",meter_status_info[gun_index].sensorFirmwareVersion);								

										sprintf((char*)&ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].sensorFirmwareCrc,
										"%s",meter_status_info[gun_index].sensorFirmwareCrc);
										
										sprintf((char*)&ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].ipAddress,
										"%s",meter_status_info[gun_index].ipAddress);
										 
										sprintf((char*)&ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].meterId,
										"%s",meter_status_info[gun_index].meterId);
										
										ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterErrorFlag.bits.muInitIsFailed = 
										meter_status_info[gun_index].MeterErrorFlag.bits.muInitIsFailed;

										ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterErrorFlag.bits.suStateIsInvalid = 
										meter_status_info[gun_index].MeterErrorFlag.bits.suStateIsInvalid;
										 
										ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterErrorFlag.bits.versionCheckIsFailed = 
										meter_status_info[gun_index].MeterErrorFlag.bits.versionCheckIsFailed;

										ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterErrorFlag.bits.muRngInitIsFailed = 
										meter_status_info[gun_index].MeterErrorFlag.bits.muRngInitIsFailed;

										ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterErrorFlag.bits.muDataIntegrityIsFailed = 
										meter_status_info[gun_index].MeterErrorFlag.bits.muDataIntegrityIsFailed;
										 
										ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterErrorFlag.bits.muFwIntegrityIsFailed = 
										meter_status_info[gun_index].MeterErrorFlag.bits.muFwIntegrityIsFailed;
																		
										ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterErrorFlag.bits.suIntegrityIsFailed = 
										meter_status_info[gun_index].MeterErrorFlag.bits.suIntegrityIsFailed;

										ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterErrorFlag.bits.logbookIntegrityIsFailed = 
										meter_status_info[gun_index].MeterErrorFlag.bits.logbookIntegrityIsFailed;
										 
										ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterErrorFlag.bits.logbookIsFull = 
										meter_status_info[gun_index].MeterErrorFlag.bits.logbookIsFull;								
										
										ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterErrorFlag.bits.memoryAccessIsFailed = 
										meter_status_info[gun_index].MeterErrorFlag.bits.memoryAccessIsFailed;
										 
										ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterErrorFlag.bits.muStateIsFailed = 
										meter_status_info[gun_index].MeterErrorFlag.bits.muStateIsFailed;
										
										sprintf((char*)&ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].publicKey,
										"%s",meter_status_info[gun_index].publicKey);
										 
										sprintf((char*)&ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].publicKeyOcmf,
										"%s",meter_status_info[gun_index].publicKeyOcmf);								
										
										ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].indexOfLastTransaction = meter_status_info[gun_index].indexOfLastTransaction;
										ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].numberOfStoredTransactions = meter_status_info[gun_index].numberOfStoredTransactions;							

												#ifdef DEBUG_SHAREMEM_STATUS_INFO_LOG	
												//evern 60s record 1s
												if((RecordLogTimerCount % 60 == 0)
												{
												DEBUG_INFO(" ================================= ShareMem Status info : %d ================================= \n",gun_index);
												DEBUG_INFO(" %-26s : %d \n", "status-value",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].StatusValue);
												DEBUG_INFO(" %-26s : %d \n", "b-suLinkStatusIsOk",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterStatusFlag.bits.suLinkStatusIsOk);
												DEBUG_INFO(" %-26s : %d \n", "b-muFatalErrorOccured",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterStatusFlag.bits.muFatalErrorOccured);
												DEBUG_INFO(" %-26s : %d \n", "b-transactionIsOnGoing",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterStatusFlag.bits.transactionIsOnGoing);
												DEBUG_INFO(" %-26s : %d \n", "b-tamperingIsDetected",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterStatusFlag.bits.tamperingIsDetected);
												DEBUG_INFO(" %-26s : %d \n", "b-timeSyncStatusIsOk",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterStatusFlag.bits.timeSyncStatusIsOk);
												DEBUG_INFO(" %-26s : %d \n", "b-overTemperatureIsDetected",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterStatusFlag.bits.overTemperatureIsDetected);
												DEBUG_INFO(" %-26s : %d \n", "b-reversedVoltage",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterStatusFlag.bits.reversedVoltage);
												DEBUG_INFO(" %-26s : %d \n", "b-suMeasureFailureOccurred",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterStatusFlag.bits.suMeasureFailureOccurred);
												DEBUG_INFO(" %-26s : %s \n", "applicationFirmwareVersion",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].applicationFirmwareVersion);
												DEBUG_INFO(" %-26s : %s \n", "applicationFirmwareAuthTag",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].applicationFirmwareAuthTag);
												DEBUG_INFO(" %-26s : %s \n", "legalFirmwareVersion",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].legalFirmwareVersion);
												DEBUG_INFO(" %-26s : %s \n", "applicationFirmwareAuthTag",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].legalFirmwareAuthTag);
												DEBUG_INFO(" %-26s : %s \n", "sensorFirmwareVersion",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].sensorFirmwareVersion);
												DEBUG_INFO(" %-26s : %s \n", "sensorFirmwareCrc",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].sensorFirmwareCrc);
												DEBUG_INFO(" %-26s : %s \n", "ipAddress",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].ipAddress);
												DEBUG_INFO(" %-26s : %s \n", "meterId",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].meterId);
												DEBUG_INFO(" %-26s : %d \n", "b-muInitIsFailed",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterErrorFlag.bits.muInitIsFailed);
												DEBUG_INFO(" %-26s : %d \n", "b-suStateIsInvalid",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterErrorFlag.bits.suStateIsInvalid);
												DEBUG_INFO(" %-26s : %d \n", "b-versionCheckIsFailed",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterErrorFlag.bits.versionCheckIsFailed);
												DEBUG_INFO(" %-26s : %d \n", "b-muRngInitIsFailed",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterErrorFlag.bits.muRngInitIsFailed);
												DEBUG_INFO(" %-26s : %d \n", "b-muDataIntegrityIsFailed",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterErrorFlag.bits.muDataIntegrityIsFailed);
												DEBUG_INFO(" %-26s : %d \n", "b-muFwIntegrityIsFailed",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterErrorFlag.bits.muFwIntegrityIsFailed);
												DEBUG_INFO(" %-26s : %d \n", "b-suIntegrityIsFailed",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterErrorFlag.bits.suIntegrityIsFailed);
												DEBUG_INFO(" %-26s : %d \n", "b-logbookIntegrityIsFailed",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterErrorFlag.bits.logbookIntegrityIsFailed);
												DEBUG_INFO(" %-26s : %d \n", "b-logbookIsFull",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterErrorFlag.bits.logbookIsFull);
												DEBUG_INFO(" %-26s : %d \n", "b-memoryAccessIsFailed",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterErrorFlag.bits.memoryAccessIsFailed);
												DEBUG_INFO(" %-26s : %d \n", "b-muStateIsFailed",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterErrorFlag.bits.muStateIsFailed);
												DEBUG_INFO(" %-26s : %s \n", "publicKey",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].publicKey);
												DEBUG_INFO(" %-26s : %s \n", "publicKeyOcmf",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].publicKeyOcmf);
												DEBUG_INFO(" %-26s : %d \n", "indexOfLastTransaction",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].indexOfLastTransaction);
												DEBUG_INFO(" %-26s : %d \n\n\n\n\n\n", "numberOfStoredTransactions",ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].numberOfStoredTransactions);
												}
												#endif
										 
										#else
												#ifdef DEBUG_STANDALONG_STATUS_INFO_LOG	
												DEBUG_INFO(" =================================  Standalong Status info : %d ================================= \n",gun_index);
												DEBUG_INFO(" %-26s : %d \n", "status-value",meter_status_info[gun_index].StatusValue);
												DEBUG_INFO(" %-26s : %d \n", "b-suLinkStatusIsOk",meter_status_info[gun_index].MeterStatusFlag.bits.suLinkStatusIsOk);
												DEBUG_INFO(" %-26s : %d \n", "b-muFatalErrorOccured",meter_status_info[gun_index].MeterStatusFlag.bits.muFatalErrorOccured);
												DEBUG_INFO(" %-26s : %d \n", "b-transactionIsOnGoing",meter_status_info[gun_index].MeterStatusFlag.bits.transactionIsOnGoing);
												DEBUG_INFO(" %-26s : %d \n", "b-tamperingIsDetected",meter_status_info[gun_index].MeterStatusFlag.bits.tamperingIsDetected);
												DEBUG_INFO(" %-26s : %d \n", "b-timeSyncStatusIsOk",meter_status_info[gun_index].MeterStatusFlag.bits.timeSyncStatusIsOk);
												DEBUG_INFO(" %-26s : %d \n", "b-overTemperatureIsDetected",meter_status_info[gun_index].MeterStatusFlag.bits.overTemperatureIsDetected);
												DEBUG_INFO(" %-26s : %d \n", "b-reversedVoltage",meter_status_info[gun_index].MeterStatusFlag.bits.reversedVoltage);
												DEBUG_INFO(" %-26s : %d \n", "b-suMeasureFailureOccurred",meter_status_info[gun_index].MeterStatusFlag.bits.suMeasureFailureOccurred);
												DEBUG_INFO(" %-26s : %s \n", "applicationFirmwareVersion",meter_status_info[gun_index].applicationFirmwareVersion);
												DEBUG_INFO(" %-26s : %s \n", "applicationFirmwareAuthTag",meter_status_info[gun_index].applicationFirmwareAuthTag);
												DEBUG_INFO(" %-26s : %s \n", "legalFirmwareVersion",meter_status_info[gun_index].legalFirmwareVersion);
												DEBUG_INFO(" %-26s : %s \n", "applicationFirmwareAuthTag",meter_status_info[gun_index].legalFirmwareAuthTag);
												DEBUG_INFO(" %-26s : %s \n", "sensorFirmwareVersion",meter_status_info[gun_index].sensorFirmwareVersion);
												DEBUG_INFO(" %-26s : %s \n", "sensorFirmwareCrc",meter_status_info[gun_index].sensorFirmwareCrc);
												DEBUG_INFO(" %-26s : %s \n", "ipAddress",meter_status_info[gun_index].ipAddress);
												DEBUG_INFO(" %-26s : %s \n", "meterId",meter_status_info[gun_index].meterId);
												DEBUG_INFO(" %-26s : %d \n", "b-muInitIsFailed",meter_status_info[gun_index].MeterErrorFlag.bits.muInitIsFailed);
												DEBUG_INFO(" %-26s : %d \n", "b-suStateIsInvalid",meter_status_info[gun_index].MeterErrorFlag.bits.suStateIsInvalid);
												DEBUG_INFO(" %-26s : %d \n", "b-versionCheckIsFailed",meter_status_info[gun_index].MeterErrorFlag.bits.versionCheckIsFailed);
												DEBUG_INFO(" %-26s : %d \n", "b-muRngInitIsFailed",meter_status_info[gun_index].MeterErrorFlag.bits.muRngInitIsFailed);
												DEBUG_INFO(" %-26s : %d \n", "b-muDataIntegrityIsFailed",meter_status_info[gun_index].MeterErrorFlag.bits.muDataIntegrityIsFailed);
												DEBUG_INFO(" %-26s : %d \n", "b-muFwIntegrityIsFailed",meter_status_info[gun_index].MeterErrorFlag.bits.muFwIntegrityIsFailed);
												DEBUG_INFO(" %-26s : %d \n", "b-suIntegrityIsFailed",meter_status_info[gun_index].MeterErrorFlag.bits.suIntegrityIsFailed);
												DEBUG_INFO(" %-26s : %d \n", "b-logbookIntegrityIsFailed",meter_status_info[gun_index].MeterErrorFlag.bits.logbookIntegrityIsFailed);
												DEBUG_INFO(" %-26s : %d \n", "b-logbookIsFull",meter_status_info[gun_index].MeterErrorFlag.bits.logbookIsFull);
												DEBUG_INFO(" %-26s : %d \n", "bits-memoryAccessIsFailed",meter_status_info[gun_index].MeterErrorFlag.bits.memoryAccessIsFailed);
												DEBUG_INFO(" %-26s : %d \n", "bits-muStateIsFailed",meter_status_info[gun_index].MeterErrorFlag.bits.muStateIsFailed);
												DEBUG_INFO(" %-26s : %s \n", "publicKey",meter_status_info[gun_index].publicKey);
												DEBUG_INFO(" %-26s : %s \n", "publicKeyOcmf",meter_status_info[gun_index].publicKeyOcmf);
												DEBUG_INFO(" %-26s : %d \n", "indexOfLastTransaction",meter_status_info[gun_index].indexOfLastTransaction);
												DEBUG_INFO(" %-26s : %d \n\n\n\n\n\n", "numberOfStoredTransactions",meter_status_info[gun_index].numberOfStoredTransactions);
												#endif
										#endif//DEBUG_STANDALONG

										//sync meter systime
										if(meter_status_info[gun_index].MeterStatusFlag.bits.suLinkStatusIsOk == 1 && 
												meter_status_info[gun_index].MeterStatusFlag.bits.timeSyncStatusIsOk == 0)
										{
												configure_meter_time(gun_index);											
										}
										
										failCount[gun_index] = 0;
							}
							else
							{
										PR("read status fail : %d \n", gun_index);
										if(failCount[gun_index] < 5)
											failCount[gun_index]++;
							}
					}


					if(failCount[gun_index] >= 5)
					{
							//if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MeterCommTimeout)
							//{
							DEBUG_ERROR("Meter %d communication timeout \n",gun_index);
							#ifndef DEBUG_STANDALONG
							ShmSysConfigAndInfo->SysInfo.DcMeterInfo[gun_index].LinkStatus = 3;
							if(gun_index == 0){
								ShmStatusCodeData->AlarmCode.AlarmEvents.bits.Meter1CommTimeout = ON;
							}else if(gun_index == 1){
								ShmStatusCodeData->AlarmCode.AlarmEvents.bits.Meter2CommTimeout = ON;
							}else if(gun_index == 2){
								ShmStatusCodeData->AlarmCode.AlarmEvents.bits.Meter3CommTimeout = ON;
							}else if(gun_index == 3){
								ShmStatusCodeData->AlarmCode.AlarmEvents.bits.Meter4CommTimeout = ON;
							}
							#else
							meter_info[gun_index].LinkStatus = 3;
							#endif
							//}
							PR("failconut fail : %d \n", gun_index);
					}
					else
					{
							if(meter_status_info[gun_index].MeterStatusFlag.bits.timeSyncStatusIsOk == 1 && 
						  	meter_status_info[gun_index].MeterStatusFlag.bits.suLinkStatusIsOk == 1)
							{
									meter_info[gun_index].LinkStatus = 2;
							}else{
									meter_info[gun_index].LinkStatus = 1;
							}
							
							#ifndef DEBUG_STANDALONG							
							ShmSysConfigAndInfo->SysInfo.DcMeterInfo[gun_index].LinkStatus = meter_info[gun_index].LinkStatus;							
							ShmSysConfigAndInfo->SysInfo.DcMeterInfo[gun_index].LinkStatus = 3;
							if(gun_index == 0){
								ShmStatusCodeData->AlarmCode.AlarmEvents.bits.Meter1CommTimeout = OFF;
							}else if(gun_index == 1){
								ShmStatusCodeData->AlarmCode.AlarmEvents.bits.Meter2CommTimeout = OFF;
							}else if(gun_index == 2){
								ShmStatusCodeData->AlarmCode.AlarmEvents.bits.Meter3CommTimeout = OFF;
							}else if(gun_index == 3){
								ShmStatusCodeData->AlarmCode.AlarmEvents.bits.Meter4CommTimeout = OFF;
							}							
							//linkstatus 1 = los meter slave, 2 is can to be Transaction
						  if(ShmSysConfigAndInfo->SysInfo.DcMeterInfo[gun_index].LinkStatus == 1)
							{															
									ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MeterSlaveLosLink = ON;										
							}else{
									ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MeterSlaveLosLink = OFF;
							}	
							#endif
							//PR("failconut pass : %d \n", gun_index);
					}
			}
				
			#ifndef DEBUG_STANDALONG
			
			PR ("===================   ModelName %s\n", ShmSysConfigAndInfo->SysConfig.ModelName);
			PR("end : %d  ActionCmd : %d OcmfInfoReady : %d RecordActionCmd: %d RecordOcmpInfoReady: %d \n", gun_index,ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].ActionCmd, 
			ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].OcmfInfoReady,
			ShmSysConfigAndInfo->SysInfo.DcMeterReadTransactionRecord[gun_index].ActionCmd,
			ShmSysConfigAndInfo->SysInfo.DcMeterReadTransactionRecord[gun_index].OcmfInfoReady);
			PR("shm bits-suLinkStatusIsOk %d : %d \n", gun_index,ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterStatusFlag.bits.suLinkStatusIsOk);
			PR("shm bits-transactionIsOnGoing %d : %d \n", gun_index,ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterStatusFlag.bits.transactionIsOnGoing);
			PR("shm bits-timeSyncStatusIsOk %d : %d \n", gun_index,ShmSysConfigAndInfo->SysInfo.DcMeterStatusInfo[gun_index].MeterStatusFlag.bits.timeSyncStatusIsOk);

			#else
			/*
			DEBUG_INFO("Meter %d - LinkStatus %d :  failCount: %d  ActionCmd: %d  OcmpInfoReady: %d RecordActionCmd: %d RecordOcmpInfoReady: %d \n", gun_index,
			meter_info[gun_index].LinkStatus,failCount[gun_index] ,
			meter_transaction_Action[gun_index].ActionCmd ,
			meter_transaction_Action[gun_index].OcmfInfoReady,
			meter_read_transaction_record[gun_index].ActionCmd ,
			meter_read_transaction_record[gun_index].OcmfInfoReady);
			*/
			
			PR ("===================   STAND ALONE\n");
			PR("end : %d  ActionCmd : %d OcmfInfoReady : %d RecordActionCmd: %d RecordOcmpInfoReady: %d \n", gun_index,meter_transaction_Action[gun_index].ActionCmd, 
			meter_transaction_Action[gun_index].OcmfInfoReady,
			meter_read_transaction_record[gun_index].ActionCmd,
			meter_read_transaction_record[gun_index].OcmfInfoReady);
			PR("shm bits-suLinkStatusIsOk %d : %d \n", gun_index,meter_status_info[gun_index].MeterStatusFlag.bits.suLinkStatusIsOk);
			PR("shm bits-transactionIsOnGoing %d : %d \n", gun_index,meter_status_info[gun_index].MeterStatusFlag.bits.transactionIsOnGoing);
			PR("shm bits-timeSyncStatusIsOk %d : %d \n", gun_index,meter_status_info[gun_index].MeterStatusFlag.bits.timeSyncStatusIsOk);			
			
			#endif
			
			usleep(1000000/modelnameInfo.GetGunCount);
			if(gun_index == modelnameInfo.GetGunCount){
					RecordLogTimerCount++;
			}
			
			//PR("end : %d  ActionCmd : %d \n", gun_index,ShmSysConfigAndInfo->SysInfo.DcMeterTransactionAction[gun_index].ActionCmd);
			
		}
				
	}

	return -1;
}