#include <stdio.h>      /*標準輸入輸出定義*/
#include <stdlib.h>     /*標準函數庫定義*/
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <time.h>

#include <sys/ioctl.h>
#include <sys/timeb.h>

#include "Module_LcmControl.h"
#include "../Log/log.h"
#include "../ShareMemory/shmMem.h"
#include "../Define/define.h"
#include "../Config.h"
#include "../SelectGun/SelectGun.h"
#include "../CSU/main.h"
#include "../timeout.h"

#define uSEC_VAL                                (1000000)

//------------------------------------------------------------------------------
//struct SysConfigAndInfo         *ShmSysConfigAndInfo;
//struct StatusCodeData           *ShmStatusCodeData;
static struct SysConfigData *pSysConfig = NULL;
static struct SysInfoData *pSysInfo = NULL;
static struct WARNING_CODE_INFO *pSysWarning = NULL;
static struct OCPP16Data *ShmOCPP16Data = NULL;
static struct FanModuleData *ShmFanModuleData;
static struct PrimaryMcuData *ShmPrimaryMcuData;
static SelectGunInfo *ShmSelectGunInfo = NULL;
static struct ChargingInfoData *pDcChargingInfo = NULL;
static DcCommonInfo *ShmDcCommonData            = NULL;
//int CardReadFd = -1;

short _currentPage              = _PAGE_NONE;
uint8_t _totalCount;
uint8_t _showInformIndex = 0;
float ChargeMaxPower_0 = 0;
float ChargeMaxPower_1 = 0;
bool _battery_display_ani = false;
int _port;
//char* pPortName         = "/dev/ttyO2";
char *pPortName           = "/dev/ttyS3";
char *moduleName          = "DMT80480T070_09WT";
bool is_show = false;
bool is_stop = false;
uint8_t _everyPageRollChange;
uint8_t _btn_press = 0;
short _btn_press_id = 0;
uint8_t _btn_press_count = 0;
int _Text_Running_Count = 1;
int Battery_Test = 0;
extern void UpdateLcmFunction(DcCommonInfo *ShmDcCommonData,int _lcmport);
//==========================================
// Open and Close RS232 and R/W
//==========================================
void AuthorizingStart(void)
{
    ShmOCPP16Data->SpMsg.bits.AuthorizeReq = YES;
    pSysInfo->AuthorizeFlag = YES;
}
void GetClockTime(struct timespec *_now_time, void *null)
{
    clock_gettime(CLOCK_MONOTONIC, _now_time);
}
void StartSystemTimeoutDet(uint8_t flag)
{
    if (pSysInfo->SystemTimeoutFlag != flag) {
        GetClockTime(&pSysInfo->SystemTimeoutTimer, NULL);
    }
    pSysInfo->SystemTimeoutFlag = flag;
}

void StopSystemTimeoutDet(void)
{
    GetClockTime(&pSysInfo->SystemTimeoutTimer, NULL);
    pSysInfo->SystemTimeoutFlag = Timeout_None;
}

void StartGunInfoTimeoutDet(uint8_t gunIndex, uint8_t flag)
{
    pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);

    if (gunIndex < pSysConfig->TotalConnectorCount) {
        if (pDcChargingInfo->TimeoutFlag != flag) {
            gettimeofday(&pDcChargingInfo->TimeoutTimer, NULL);
        }
        pDcChargingInfo->TimeoutFlag = flag;
    }
}

void StopGunInfoTimeoutDet(uint8_t gunIndex)
{
    pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);

    if (gunIndex < pSysConfig->TotalConnectorCount) {
        pDcChargingInfo->TimeoutFlag = Timeout_None;
    }
}
unsigned long GetClockTimeoutValue(struct timespec _start_time)
{
    struct timespec ts_end;
    unsigned long ret = 0;

    clock_gettime(CLOCK_MONOTONIC, &ts_end);

    ret = ((unsigned long)(ts_end.tv_sec - _start_time.tv_sec) * 1000000) + ((unsigned long)((ts_end.tv_nsec / 1000) - (_start_time.tv_nsec/ 1000)));

    return ret;
}
int CreateCommunicationLcmPort()
{
    int fd;
    struct termios tios;

    fd = open(pPortName, O_RDWR);
    if (fd <= 0) {
        log_error("open /dev/ttyS3 NG ");
        return -1;
    }
    ioctl(fd, TCGETS, &tios);
    tios.c_cflag = B115200 | CS8 | CLOCAL | CREAD;
    tios.c_lflag = 0;
    tios.c_iflag = 0;
    tios.c_oflag = 0;
    tios.c_cc[VMIN] = 0;
    tios.c_cc[VTIME] = (uint8_t) 5;
    tios.c_lflag = 0;
    tcflush(fd, TCIFLUSH);
    ioctl(fd, TCSETS, &tios);

    return fd;
}

void CloseCommunicationLcmPort()
{
    close(_port);
}

void setSelGunWaitToAuthor(uint8_t curSel)
{
    if (curSel == LEFT_GUN_NUM && ShmSelectGunInfo->SelGunInfo.LeftGun == SEL_GUN_CONFIRM) {
        ShmSelectGunInfo->SelGunInfo.LeftGun = SEL_GUN_ATHOR;
        log_info("setSelGunWaitToAuthor left");

    } else if (curSel == RIGHT_GUN_NUM && ShmSelectGunInfo->SelGunInfo.RightGun == SEL_GUN_CONFIRM) {
        ShmSelectGunInfo->SelGunInfo.RightGun = SEL_GUN_ATHOR;
        log_info("setSelGunWaitToAuthor right");

    }
}
void confirmSelGun(uint8_t selGun)
{
    if (selGun == LEFT_GUN_NUM) {
        ShmSelectGunInfo->SelGunInfo.LeftGun = SEL_GUN_CONFIRM;
        //printf("confirmSelGun left");
    } else if (selGun == RIGHT_GUN_NUM) {
        ShmSelectGunInfo->SelGunInfo.RightGun = SEL_GUN_CONFIRM;
        //printf("confirmSelGun right");
    }
    //changeLcmPage(_PAGE_PLUGIN);

    //StartGunInfoTimeoutDet(selGun, Timeout_SelectGun);
    //StartSystemTimeoutDet(Timeout_ReturnViewPage);
}
void GetDeviceInfoStatus(short address, uint8_t len)
{
    uint8_t cmd[8];
    memset(cmd, 0x00, sizeof(cmd));
    uint8_t msg[11];
    memset(msg, 0x00, sizeof(msg));

    cmd[0] = CMD_TITLE_1;
    cmd[1] = CMD_TITLE_2;
    cmd[2] = 0x04;
    cmd[3] = CMD_MULTI_READ;
    cmd[4] = (address >> 8) & 0xff;
    cmd[5] = (address >> 0) & 0xff;
    cmd[6] = len;

    WriteCmdToLcm(cmd, ARRAY_SIZE(cmd));
    usleep(1000);
    ReadMsgFromLcm(msg, ARRAY_SIZE(msg));
}
void WriteCmdToLcm(uint8_t *cmd, uint8_t cmdLen)
{
    int len = write(_port, cmd, cmdLen);
    if (len < sizeof(cmd)) {
        log_error("Write cmd to LCM Failure. ");
    }
}

void TradeRunning(uint8_t _run)
{
    if (_run == TRUE) {
        ChangeDisplay2Value(_Icon_PreAuth, 1);
        ChangeDisplay2Value(_Icon_Ani_Dot, 1);
        ChangeDisplay2Value(_Icon_CountDownBG, 0);
        ChangeDisplay2Value(_Icon_CancelCntDownTen, 0);
        ChangeDisplay2Value(_Icon_CancelCntDownDigits, 0);
    }
    else {
        ChangeDisplay2Value(_Icon_PreAuth, _TCC_TradeCancelString);
        ChangeDisplay2Value(_Icon_Ani_Dot, 0);
        ChangeDisplay2Value(_Icon_CountDownBG, _TCC_TradeCancelFrame);
        if (pSysInfo->SystemTimeoutFlag == Timeout_TradeCancel) {
            unsigned long _time = TCC_TRADECANCEL_TIMEOUT-(GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL);
            ChangeDisplay2Value(_Icon_CancelCntDownTen, (short)(_TCC_CancelNum_0 + (_time / 10)));
            ChangeDisplay2Value(_Icon_CancelCntDownDigits, (short)(_TCC_CancelNum_0 + (_time % 10)));
        }

    }
}

void CheckIdlePress()
{
    pSysInfo->SystemPage = _PAGE_SELECT_GUN;
    log_info("IDLE Enter Select Gun Page");
}
void CheckReturnPress()
{
	int i;
	pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(pSysInfo->CurGunSelected);
	//pDcChargingInfo->SystemStatus = S_IDLE;
    if (pSysInfo->SystemPage >= _PAGE_BILL && pSysInfo->SystemPage <= _PAGE_PLUGIN) {
        ShmDcCommonData->OperateIDLE[pSysInfo->CurGunSelected] = 1;
        log_info("Operate return to IDLE");
    }
	if ( pDcChargingInfo->SystemStatus == S_AUTHORIZING ) {
        ShmDcCommonData->TradeCancel = TRUE;
        /*
		if (pSysInfo->SystemPage == _PAGE_AUTHORIZE ) {
			pSysInfo->SystemPage = _PAGE_SELECT_PAY;
		} else if (pSysInfo->SystemPage == _PAGE_PLUGIN)
            pSysInfo->SystemPage = _PAGE_SELECT_GUN;
            */
        for (i = 0; i <= 30; i++) {
            if (ShmDcCommonData->PreAuth_Config == _CREDITCARD_IDLE)
                break;
            sleep(1);
        }
        pSysInfo->SystemPage = _PAGE_SENSING;
        StopGunInfoTimeoutDet(pSysInfo->CurGunSelected);
        StartSystemTimeoutDet(Timeout_TradeCancel);
        ShmDcCommonData->PreAuth_Result = 0;
        log_info("Press Return button cancel PreAuth");
		ShmDcCommonData->PreAuth_Config = _CREDITCARD_CANCEL;
		ShmDcCommonData->PreAuth_Result = 0;
		for(i=0;i<=30;i++) {
			if(ShmDcCommonData->PreAuth_Config == _CREDITCARD_IDLE)
				break;
			sleep(1);
		}
		ShmDcCommonData->PreAuth_Result = 0;
        StopSystemTimeoutDet();
        pDcChargingInfo->SystemStatus = S_IDLE;
		strcpy((char *)pSysConfig->UserId, "");
		return;
	}
    if (pDcChargingInfo->SystemStatus == S_IDLE && pSysInfo->SystemPage == _PAGE_AUTHORIZE) {
        ShmDcCommonData->TradeCancel = TRUE;
        pSysInfo->SystemPage = _PAGE_SENSING;
        StartSystemTimeoutDet(Timeout_TradeCancel);
        if (ShmDcCommonData->PreAuth_Config == _CREDITCARD_PREAUTH) {
            for (i = 0; i <= 30; i++) {
                if (ShmDcCommonData->PreAuth_Result != 0)
                    break;
                sleep(1);
            }
            ShmDcCommonData->PreAuth_Result = 0;
            if (ShmDcCommonData->AuthPass_flag[pSysInfo->CurGunSelected] == TRUE) {
                ShmDcCommonData->PreAuth_Config = _CREDITCARD_CANCEL;
                ShmDcCommonData->PreAuth_Result = 0;
                for (i = 0; i <= 30; i++) {
                    if (ShmDcCommonData->PreAuth_Config == _CREDITCARD_IDLE)
                        break;
                    sleep(1);
                }
            }
            pSysInfo->SystemPage = _PAGE_SELECT_PAY;
        }
        return;
    }
	if ( pSysInfo->SystemPage == _PAGE_EXIT ) {
        StopSystemTimeoutDet();
		pDcChargingInfo->SystemStatus = S_IDLE;
		pSysInfo->SystemPage = _PAGE_IDLE;
		return;
	}

    if (pSysInfo->SystemPage == _PAGE_AUTHORIZE)
        pSysInfo->SystemPage = _PAGE_SELECT_PAY;
    else
        pSysInfo->SystemPage = _PAGE_SELECT_GUN;
}
void CheckStopPress()
{
	is_stop = TRUE;
	//ChangeDisplay2Value(_ConfirmStopIcon,is_stop);
	if (pSysInfo->CurGunSelected == LEFT_GUN_NUM)
		pSysInfo->SystemPage = _PAGE_STOP_CONFIRM_LEFT;
	else
		pSysInfo->SystemPage = _PAGE_STOP_CONFIRM_RIGHT;
}
void CheckStopConfirmPress()
{
	int result;
	pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(pSysInfo->CurGunSelected);
	pDcChargingInfo->SystemStatus = S_TERMINATING;
	pSysInfo->SystemPage = _PAGE_PAYING;
	is_stop = FALSE;
	ShmDcCommonData->StopCharge[pSysInfo->CurGunSelected] = TRUE;
	StartGunInfoTimeoutDet(pSysInfo->CurGunSelected,Timeout_FinalCost);
	/*
	ShmDcCommonData->PreAuth_Config = _CREDITCARD_CANCEL;
	ShmDcCommonData->PreAuth_Result = 0;
	*/

}
void CheckStopCancelPress()
{
	is_stop = FALSE;
	//ChangeDisplay2Value(_ConfirmStopIcon,is_stop);
	pSysInfo->SystemPage = _PAGE_CHARGING;
}
void CheckConfirmGun(uint8_t gunIndex)
{
	pSysInfo->CurGunSelected = gunIndex;
	pSysInfo->SystemPage = _PAGE_BILL;
}
void CheckDonateBill(uint8_t gunIndex)
{
	if (gunIndex == LEFT_GUN_NUM) {
		pSysInfo->SystemPage = _PAGE_DONATE_LEFT;
	} else
		pSysInfo->SystemPage = _PAGE_DONATE_RIGHT;
}
void CheckDonateYes()
{
	pSysInfo->SystemPage = _PAGE_SELECT_PAY;
	ShmDcCommonData->donate_flag[pSysInfo->CurGunSelected] = TRUE;
}
void CheckDonateNo()
{
	pSysInfo->SystemPage = _PAGE_BILL;
	ShmDcCommonData->donate_flag[pSysInfo->CurGunSelected] = FALSE;
}
void CheckPayCreditCard()
{
    ShmDcCommonData->LineStatus[pSysInfo->CurGunSelected] = 0;
    ShmDcCommonData->TradeCancel = FALSE;
   	pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(pSysInfo->CurGunSelected);
	if (pDcChargingInfo->SystemStatus == S_IDLE) {
		//confirmSelGun(pSysInfo->CurGunSelected);
        ShmDcCommonData->PreAuth_Config = _CREDITCARD_PREAUTH;
        ShmDcCommonData->PreAuth_Result = 0;
		//setSelGunWaitToAuthor(pSysInfo->CurGunSelected);
		pSysInfo->SystemPage = _PAGE_AUTHORIZE;
		//pDcChargingInfo->SystemStatus = S_AUTHORIZING;

		//
		//AuthorizingStart();
	}
}
void CheckPayIcash()
{

}
void CheckPayLinePay()
{

}
void CheckTouchPress(short id)
{

    GetDeviceInfoStatus(id,1);
    if (_btn_press >= 1 && _btn_press_id == id ) {
    	_btn_press_count++;
    }
    if (_btn_press >= 1 && _btn_press_id == id && _btn_press_count >= 3) {
        ChangeDisplay2Value(id, 0);
        //log_info("Press id : 0x%04x",id);
        _btn_press_count = 0;
        switch (id) {
        case _Touch_Show_Left:
        	if (pSysInfo->SystemPage >= _PAGE_ADD_FRIEND && pSysInfo->SystemPage <= _PAGE_PLUGIN) {
        		log_info("Authorize Process can't select gun");
        		return;
        	}
            // Show log
        	if(pSysInfo->CurGunSelected != LEFT_GUN_NUM) {
        		pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(LEFT_GUN_NUM);
        		pSysInfo->CurGunSelected = LEFT_GUN_NUM;
                if(pDcChargingInfo->SystemStatus == S_IDLE) {
                	pSysInfo->SystemPage = _PAGE_SELECT_GUN;
                }
				log_info("LCM left Gun down...............................%x %x %x",
						pSysInfo->CurGunSelected,pDcChargingInfo->SystemStatus,pSysInfo->SystemPage);
			}

        	if (pSysInfo->SystemPage == _PAGE_CHARGING || pSysInfo->SystemPage == _PAGE_COMPLETE ||
        			pSysInfo->SystemPage == _PAGE_PAYFAIL) {
				StopSystemTimeoutDet();
				StartSystemTimeoutDet(Timeout_ReturnViewPage);
        	}
            break;
        case _Touch_Show_Right:
        	if (pSysInfo->SystemPage >= _PAGE_ADD_FRIEND && pSysInfo->SystemPage <= _PAGE_PLUGIN) {
        		log_info("Authorize Process can't select gun");
        		return;
        	}
			// Show log
			if(pSysInfo->CurGunSelected != RIGHT_GUN_NUM) {
				pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(RIGHT_GUN_NUM);
				pSysInfo->CurGunSelected = RIGHT_GUN_NUM;
	            if(pDcChargingInfo->SystemStatus == S_IDLE) {
	            	pSysInfo->SystemPage = _PAGE_SELECT_GUN;
	            }
				log_info("LCM Right Gun down...............................%x %x %x",
						pSysInfo->CurGunSelected,pDcChargingInfo->SystemStatus,pSysInfo->SystemPage);
			}

        	if (pSysInfo->SystemPage == _PAGE_CHARGING || pSysInfo->SystemPage == _PAGE_COMPLETE ||
        			pSysInfo->SystemPage == _PAGE_PAYFAIL) {
				StopSystemTimeoutDet();
				StartSystemTimeoutDet(Timeout_ReturnViewPage);
        	}
            break;
        case _Touch_Return:
        	CheckReturnPress();
        	break;
        case _Touch_IDLE:
            CheckIdlePress();
            break;
        case _Touch_StopCharge:
        	CheckStopPress();
        	is_stop = TRUE;
        	break;
        case _Touch_Stop_Confirm:
        	CheckStopConfirmPress();
        	is_stop = FALSE;
        	break;
        case _Touch_Stop_Cancel:
        	CheckStopCancelPress();
        	is_stop = FALSE;
        	break;
        case _Touch_Select_Left:
        	CheckConfirmGun(LEFT_GUN_NUM);
        	break;
        case _Touch_Select_Right:
        	CheckConfirmGun(RIGHT_GUN_NUM);
        	break;
        case _Touch_DonateBill:
        	StopSystemTimeoutDet();
        	CheckDonateBill(pSysInfo->CurGunSelected);
        	break;
        case _Touch_DonateYes:
        	CheckDonateYes();
        	break;
        case _Touch_DonateNo:
        	StartSystemTimeoutDet(Timeout_AddLine);
        	CheckDonateNo();
        	break;
        case _Touch_Pay_CreditCard:
        	CheckPayCreditCard();
        	break;
        case _Touch_Pay_Icash:
        	CheckPayIcash();
        	break;
        case _Touch_Pay_LinePay:
        	CheckPayLinePay();
        	break;
        } // switch

    }   //if (_btn_press >= 3)
}

void CheckLCMPressed()
{
	int i;
    pid_t Pid = fork();
    if ( Pid == 0 ) {
        while (1) {
        	if (pSysInfo->SystemPage != _PAGE_SELECT_GUN) {
				CheckTouchPress(_Touch_Show_Left);
				CheckTouchPress(_Touch_Show_Right);
        	}
            switch (pSysInfo->SystemPage) {
            case _PAGE_IDLE:
				CheckTouchPress(_Touch_IDLE);
                break;
            case _PAGE_SELECT_GUN:
				CheckTouchPress(_Touch_Select_Left);
				CheckTouchPress(_Touch_Select_Right);
            	break;
            case _PAGE_BILL:
            	CheckTouchPress(_Touch_Return);
            	CheckTouchPress(_Touch_DonateBill);
            	break;
            case _PAGE_ADD_FRIEND:
            	CheckTouchPress(_Touch_Return);
            	CheckTouchPress(_Touch_DonateBill);
            	break;
            case _PAGE_DONATE_LEFT:
            case _PAGE_DONATE_RIGHT:
            	CheckTouchPress(_Touch_Return);
            	CheckTouchPress(_Touch_DonateYes);
            	CheckTouchPress(_Touch_DonateNo);
            	break;
            case _PAGE_SELECT_PAY:
            	CheckTouchPress(_Touch_Return);
            	CheckTouchPress(_Touch_Pay_CreditCard);
            	break;
            case _PAGE_PLUGIN:
            	CheckTouchPress(_Touch_Return);

            	break;
            ///*
            case _PAGE_CHARGING:
				CheckTouchPress(_Touch_StopCharge);
            	break;
            case _PAGE_AUTHORIZE:
            	CheckTouchPress(_Touch_Return);
            	break;
            case _PAGE_STOP_CONFIRM_LEFT:
            case _PAGE_STOP_CONFIRM_RIGHT:
            	StopSystemTimeoutDet();
				CheckTouchPress(_Touch_Stop_Confirm);
				CheckTouchPress(_Touch_Stop_Cancel);
            	break;
            case _PAGE_EXIT:
            	CheckTouchPress(_Touch_Return);
            	break;
            case _PAGE_AUTHORIZE_FAIL:
            	CheckTouchPress(_Touch_Return);
            	break;
            } // switch
            usleep(5000);
        } //while
    } // if pid
    log_info("Create LCM fork:%d",Pid);
}

void ReadMsgFromLcm(uint8_t *msg, uint8_t readLen)
{
    read(_port, msg, readLen);

//  5a : CMD_TITLE_1
//  a5 : CMD_TITLE_2
//  5
//  81 : CMD_WRITE
//  3  : CMD_REGISTER
//  2  : Data length
//  0  : High byte
//  1  : Low byte

//  printf("-------------------------------------------- \n");
//  printf("msg = %x \n", *msg);            // A5
//  printf("msg = %x \n", *(msg + 1));      // 5A
//  printf("msg = %x \n", *(msg + 2));      // Len : [3] ~ [6] + Data Len
//  printf("msg = %x \n", *(msg + 3));      // cmd : 0x83
//  printf("msg = %x \n", *(msg + 4));      // addr : H
//  printf("msg = %x \n", *(msg + 5));      // addr : L
//  printf("msg = %x \n", *(msg + 6));      // Data Len
//
//  printf("msg = %x \n", *(msg + 7));
//  printf("msg = %x \n", *(msg + 8));
//  printf("msg = %x \n", *(msg + 9));
//  printf("msg = %x \n", *(msg + 10));
//  printf("msg = %x \n", *(msg + 11));
//  printf("msg = %x \n", *(msg + 12));
//  printf("msg = %x \n", *(msg + 13));
//  printf("msg = %x \n", *(msg + 14));
    /*
    for(uint8_t i = 0 ; i<readLen+3; i++) {
        log_info("Read data[%d]:0x%x",i,msg[i]);
    }*/

    if(*msg == CMD_TITLE_1 && *(msg + 1) == CMD_TITLE_2)
    {
        if(*(msg + 3) == CMD_WRITE)
        {
            switch (*(msg + 4))
            {
                case CMD_REGISTER:
                {
                    // 頁面
                    if(strcmp((char *)pSysInfo->LcmHwRev, "") != EQUAL)
                        strcpy((char *)pSysInfo->LcmHwRev, moduleName);

                    _currentPage = *(msg + 7);
                    log_info("Current Page:%d",_currentPage);
//                  if (_currentPage != 1 && _currentPage != 5 && _currentPage != 6 && _currentPage != 7 && _currentPage != 8)
//                      printf("_currentPage = %d \n", _currentPage);
                }
                break;
            }
        }
        else if (*(msg + 3) == CMD_MULTI_READ)
        {
            short key = ((short)(*(msg + 4) << 8) + *(msg + 5));
            if(strcmp((char *)pSysInfo->LcmHwRev, "") != EQUAL)
                strcpy((char *)pSysInfo->LcmHwRev, moduleName);
            if (key == 0x0014)
                _currentPage = *(msg + 8);
            if ( key >= _Touch_IDLE && key <=_Touch_Pay_LinePay ) {

                _btn_press_id = key;
                _btn_press = *(msg + 8);
            }
//          switch ((unsigned short) (*(msg + 4) << 8) + (unsigned short) *(msg + 5))
//          {
//              case BUTTON_GUN_INDEX:
//              {
//                  // 當前選的槍號
//                  _curGunIndex = (*(msg + 8));
//              }
//              break;
//          }
        }
    }
}
void GetHrFormTimeString(char* time,char* hr)
{
    //char tm[] = "2021-12-06 17:29:08:084";
    for(int i = 0 ; i < 2 ; i++) {
        hr[i] = time[i+11];
    }
    if( atoi(hr) == NULL ) {
        strcmp(hr,"");
    }
}
void GetMinFormTimeString(char* time,char* min)
{
    //char tm[] = "2021-12-06 17:29:08:084";
    for(int i = 0 ; i < 2 ; i++) {
        min[i] = time[i+14];
    }
    if( atoi(min) == NULL || atoi(min) > 60) {
        strcmp(min,"");
    }
}
//================================================
// Function
//================================================
void ChangeToOtherPage(short newPage)
{

    uint8_t cmd[10];
    memset(cmd, 0x00, sizeof(cmd));
    uint8_t msg[9];
    memset(msg, 0x00, sizeof(msg));

    cmd[0] = CMD_TITLE_1;
    cmd[1] = CMD_TITLE_2;
    cmd[2] = 0x07;
    cmd[3] = 0x82;
    cmd[4] = 0x00;
    cmd[5] = 0x84;
    cmd[6] = 0x5A;
    cmd[7] = 0x01;
    cmd[8] = newPage >> 8;
    cmd[9] = newPage & 0x00FF;

    WriteCmdToLcm(cmd, ARRAY_SIZE(cmd));
    usleep(5000);
    ReadMsgFromLcm(msg, ARRAY_SIZE(msg));
}

void ChangeBackLight(bool islight)
{
    uint8_t value = 0x01;
    uint8_t msg[9];
    memset(msg, 0x00, sizeof(msg));

    // 0x00 ~ 0x40
    if (islight)
    {
        value = 0x20;
    }
    uint8_t cmd[7];
    memset(cmd, 0x00, sizeof(cmd));

    cmd[0] = CMD_TITLE_1;
    cmd[1] = CMD_TITLE_2;
    cmd[2] = 0x03;
    cmd[3] = CMD_READ;
    cmd[4] = CMD_BACKLIGHT;
    cmd[5] = value;

    WriteCmdToLcm(cmd, ARRAY_SIZE(cmd));
    usleep(10000);
    ReadMsgFromLcm(msg, ARRAY_SIZE(msg));
}

void GetCurrentPage()
{
    uint8_t cmd[7];
    memset(cmd, 0x00, sizeof(cmd));
    uint8_t msg[9];
    memset(msg, 0x00, sizeof(msg));

    cmd[0] = CMD_TITLE_1;
    cmd[1] = CMD_TITLE_2;
    cmd[2] = 0x04;              // 底下總長度
    cmd[3] = 0x83;
    cmd[4] = 0x00;
    cmd[5] = 0x14;
    cmd[6] = 0x01;

    WriteCmdToLcm(cmd, ARRAY_SIZE(cmd));
    usleep(5000);
    ReadMsgFromLcm(msg, ARRAY_SIZE(msg));
}


void DisplayValueToLcm(short address, uint8_t *data, uint8_t len)
{

    uint8_t cmd[256];
    memset(cmd, 0x00, sizeof(cmd));
    uint8_t msg[9];
    memset(msg, 0x00, sizeof(msg));

    cmd[0] = CMD_TITLE_1;
    cmd[1] = CMD_TITLE_2;
    cmd[2] = 0x03 + len;
    cmd[3] = CMD_MULTI_WRITE;
    cmd[4] = address >> 8;
    cmd[5] = address & 0x00FF;

    for(uint8_t count = 0; count < len; count++)
    {
        cmd[6 + count] = *(data + count);
    }

    WriteCmdToLcm(cmd, cmd[2] + 3);
    usleep(10000);
    ReadMsgFromLcm(msg, ARRAY_SIZE(msg));
}

void ChangeDisplay2Value(short address, short value)
{
    uint8_t data[2];
    data[0] = value >> 8;
    data[1] = value & 0x00FF;
    //log_info("Addr:0x%x, value:%d",address,value);
    DisplayValueToLcm(address, data, sizeof(data));
}

//================================================
// Warning process
//================================================
void string2ByteArray(uint8_t *input, uint8_t *output)
{
    int loop;
    int i;

    loop = 0;
    i = 0;

    while (input[loop] != '\0') {
        output[i++] = input[loop++];
    }
    output[loop] = '\0';
}

void RefreshProgressAnimation()
{
	_everyPageRollChange >= 30 ? _everyPageRollChange = 0 : _everyPageRollChange++;
}

//================================================
// Change current page
//================================================
void ChangeCurPage()
{
    //log_info("cur = %d ,system = %d, lcm = %d ",_currentPage, pSysInfo->SystemPage, pSysInfo->PageIndex);

    pSysInfo->PageIndex = pSysInfo->SystemPage;

    if (_currentPage != pSysInfo->PageIndex) {
        switch (pSysInfo->SystemPage) {
        case _PAGE_AUTHORIZE:
            break;
        case _PAGE_PLUGIN:
            break;
        case _PAGE_PRECHARGE:
            break;
        case _PAGE_CHARGING:
        	is_stop = false;
            break;
        case _PAGE_COMPLETE:
            break;
        }
        _currentPage = pSysInfo->PageIndex;
        //log_info("Chagne Page:%d",pSysInfo->PageIndex);
        ChangeToOtherPage(pSysInfo->PageIndex);
    }
}

/*
 * View Page
 *
 */

unsigned long GetTimeoutValue(struct timeval _sour_time)
{
    struct timeval _end_time;
    gettimeofday(&_end_time, NULL);

    return 1000000 * (_end_time.tv_sec - _sour_time.tv_sec) + _end_time.tv_usec - _sour_time.tv_usec;
}
void showGunWorkingType()
{
    if (pSysInfo->CurGunSelected == LEFT_GUN_NUM) {

        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(LEFT_GUN_NUM);
        if (pDcChargingInfo->CCSGunType == _TYPE_CCS1_Liquid ||
                pDcChargingInfo->CCSGunType == _TYPE_CCS1_Natural) {
            ChangeDisplay2Value(_Icon_ShowLeft,_TCC_ShowLeft_CCS1_On);

        } else if (pDcChargingInfo->CCSGunType == _TYPE_CCS2_Liquid ||
                pDcChargingInfo->CCSGunType == _TYPE_CCS2_Natural) {
            ChangeDisplay2Value(_Icon_ShowLeft,_TCC_ShowLeft_CCS2_On);
        } else if (pDcChargingInfo->Type == _Type_Chademo) {
            ChangeDisplay2Value(_Icon_ShowLeft,_TCC_ShowLeft_CHAdeMo_On);
        }

        // Set Right Gun
        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(RIGHT_GUN_NUM);
        if (pDcChargingInfo->CCSGunType == _TYPE_CCS1_Liquid ||
                pDcChargingInfo->CCSGunType == _TYPE_CCS1_Natural) {
            ChangeDisplay2Value(_Icon_ShowRight,_TCC_ShowRight_CCS1_Off);

        } else if (pDcChargingInfo->CCSGunType == _TYPE_CCS2_Liquid ||
                pDcChargingInfo->CCSGunType == _TYPE_CCS2_Natural) {
            ChangeDisplay2Value(_Icon_ShowRight,_TCC_ShowRight_CCS2_Off);
        } else if (pDcChargingInfo->Type == _Type_Chademo) {
            ChangeDisplay2Value(_Icon_ShowRight,_TCC_ShowRight_CHAdeMo_Off);
        }
    } else if (pSysInfo->CurGunSelected == RIGHT_GUN_NUM){
        // Left Gun
        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(LEFT_GUN_NUM);
        if (pDcChargingInfo->CCSGunType == _TYPE_CCS1_Liquid ||
                pDcChargingInfo->CCSGunType == _TYPE_CCS1_Natural) {
            ChangeDisplay2Value(_Icon_ShowLeft,_TCC_ShowLeft_CCS1_Off);

        } else if (pDcChargingInfo->CCSGunType == _TYPE_CCS2_Liquid ||
                pDcChargingInfo->CCSGunType == _TYPE_CCS2_Natural) {
            ChangeDisplay2Value(_Icon_ShowLeft,_TCC_ShowLeft_CCS2_Off);
        } else if (pDcChargingInfo->Type == _Type_Chademo) {
            ChangeDisplay2Value(_Icon_ShowLeft,_TCC_ShowLeft_CHAdeMo_Off);
        }
        // Right Gun
        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(RIGHT_GUN_NUM);
        if (pDcChargingInfo->CCSGunType == _TYPE_CCS1_Liquid ||
                pDcChargingInfo->CCSGunType == _TYPE_CCS1_Natural) {
            ChangeDisplay2Value(_Icon_ShowRight,_TCC_ShowRight_CCS1_On);

        } else if (pDcChargingInfo->CCSGunType == _TYPE_CCS2_Liquid ||
                pDcChargingInfo->CCSGunType == _TYPE_CCS2_Natural) {
            ChangeDisplay2Value(_Icon_ShowRight,_TCC_ShowRight_CCS2_On);
        } else if (pDcChargingInfo->Type == _Type_Chademo) {
            ChangeDisplay2Value(_Icon_ShowRight,_TCC_ShowRight_CHAdeMo_On);
        }
    }
}
void ClearQrCode()
{
    char cmd[200];
    memset(cmd,0,200);
    DisplayValueToLcm(_QRCode_AddLine, cmd, 200);
}
void ChangeQrCode_Idle(char *input)
{
    char cmd[256];
    pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(pSysInfo->CurGunSelected);
    // https://nhoatcc.lineapid.tw/web/tologin?sn=ABC123&cid=2
    memset(cmd,0,256);
    int len = sprintf(cmd,"https://nhoatcc.lineapid.tw/web/tologin?sn=%s&cid=%d",input,ShmDcCommonData->ConnectorID[pSysInfo->CurGunSelected]);
    //int len = sprintf(cmd, "https://nhoatcctest.lineapid.tw/web/tologin?sn=%s&cid=%d", input, ShmDcCommonData->ConnectorID[pSysInfo->CurGunSelected]);
    //log_info("QR Code:URL:%s",cmd);
    if (pSysInfo->SystemPage == _PAGE_BILL)
    	DisplayValueToLcm(_QRCode_AddLine, cmd, len+1);
}

/*
void ChangeRemainTime(int sec)
{
    int h, m, s;
    uint8_t cmd[10];
    uint8_t value[10];

    memset(cmd, 0x00, sizeof(cmd));

//  srand(time(NULL));
//  int min = 0;
//  int max = 65536;
//  sec = rand() % (max - min + 1) + min;

    h = (sec / 3600);
    m = (sec - (3600 * h)) / 60;
    s = (sec - (3600 * h) - (m * 60));
    sprintf((char *)value, "%02d:%02d:%02d", h, m, s);
    string2ByteArray(value, cmd);
    DisplayValueToLcm(_Text_Time, cmd, sizeof(cmd));
}
*/
void ShowSelectGun()
{
	pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(LEFT_GUN_NUM);
	if (pDcChargingInfo->SystemStatus == S_CHARGING) {
		if (pDcChargingInfo->CCSGunType == _TYPE_CCS1_Liquid ||
				pDcChargingInfo->CCSGunType == _TYPE_CCS1_Natural) {
			ChangeDisplay2Value(_Icon_Select_Left,_TCC_ShowLeftGunCharging_CCS1);

		} else if (pDcChargingInfo->CCSGunType == _TYPE_CCS2_Liquid ||
				pDcChargingInfo->CCSGunType == _TYPE_CCS2_Natural) {
			ChangeDisplay2Value(_Icon_Select_Left,_TCC_ShowLeftGunCharging_CCS2);

		} else if (pDcChargingInfo->Type == _Type_Chademo) {
			ChangeDisplay2Value(_Icon_Select_Left,_TCC_ShowLeftGunCharging_CHAdeMo);
		}
	} else {
		if (pDcChargingInfo->CCSGunType == _TYPE_CCS1_Liquid ||
				pDcChargingInfo->CCSGunType == _TYPE_CCS1_Natural) {
			ChangeDisplay2Value(_Icon_Select_Left,_TCC_SelectLeft_CCS1);

		} else if (pDcChargingInfo->CCSGunType == _TYPE_CCS2_Liquid ||
				pDcChargingInfo->CCSGunType == _TYPE_CCS2_Natural) {
			ChangeDisplay2Value(_Icon_Select_Left,_TCC_SelectLeft_CCS2);

		} else if (pDcChargingInfo->Type == _Type_Chademo) {
			ChangeDisplay2Value(_Icon_Select_Left,_TCC_SelectLeft_CHAdeMo);
		}
	}
	pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(RIGHT_GUN_NUM);
	if (pDcChargingInfo->SystemStatus == S_CHARGING) {
		if (pDcChargingInfo->CCSGunType == _TYPE_CCS1_Liquid ||
				pDcChargingInfo->CCSGunType == _TYPE_CCS1_Natural) {
			ChangeDisplay2Value(_Icon_Select_Right,_TCC_ShowRightGunCharging_CCS1);

		} else if (pDcChargingInfo->CCSGunType == _TYPE_CCS2_Liquid ||
				pDcChargingInfo->CCSGunType == _TYPE_CCS2_Natural) {
			ChangeDisplay2Value(_Icon_Select_Right,_TCC_ShowRightGunCharging_CCS2);

		} else if (pDcChargingInfo->Type == _Type_Chademo) {
			ChangeDisplay2Value(_Icon_Select_Right,_TCC_ShowRightGunCharging_CHAdeMo);

		}
	} else {
		if (pDcChargingInfo->CCSGunType == _TYPE_CCS1_Liquid ||
				pDcChargingInfo->CCSGunType == _TYPE_CCS1_Natural) {
			ChangeDisplay2Value(_Icon_Select_Right,_TCC_SelectRight_CCS1);

		} else if (pDcChargingInfo->CCSGunType == _TYPE_CCS2_Liquid ||
				pDcChargingInfo->CCSGunType == _TYPE_CCS2_Natural) {
			ChangeDisplay2Value(_Icon_Select_Right,_TCC_SelectRight_CCS2);

		} else if (pDcChargingInfo->Type == _Type_Chademo) {
			ChangeDisplay2Value(_Icon_Select_Right,_TCC_SelectRight_CHAdeMo);

		}
	}

}
void ChangeChargingPowerValue(float pow)
{
    uint8_t cmd[10];
    uint8_t value[10];

    memset(cmd, 0x00, sizeof(cmd));

    sprintf((char *) value, "%d",(int)pow);
    string2ByteArray(value, cmd);
    DisplayValueToLcm(_String_ChargePower, cmd, sizeof(cmd));
}
void ChangeChargingRateValue(int rate)
{
    uint8_t cmd[10];
    uint8_t value[10];

    memset(cmd, 0x00, sizeof(cmd));
    if (rate == 0) {
        log_info("Doesn't get Charge Fee");
    } 
    
    sprintf((char *) value, "%d",rate);
    string2ByteArray(value, cmd);
    DisplayValueToLcm(_String_ChargeRate, cmd, sizeof(cmd));
}

void ChangeChargingFeeValue(float fee)
{
    uint8_t cmd[10];
    uint8_t value[10];

    memset(cmd, 0x00, sizeof(cmd));

    sprintf((char *) value, "%d", (int)fee);
    string2ByteArray(value, cmd);
    DisplayValueToLcm(_String_Money, cmd, sizeof(cmd));
}
void ChangeCarBonValue(float data)
{
    uint8_t cmd[10];
    uint8_t value[10];
    float _carbon = 0;
    memset(cmd, 0x00, sizeof(cmd));
    _carbon = data * 0.577;
    //log_info("Carbon:%d",(int)_carbon);

	sprintf((char *) value, "%d", (int)_carbon);
    string2ByteArray(value, cmd);
    DisplayValueToLcm(_String_Carbon, cmd, sizeof(cmd));
}
void ChangeChargingEnergyValue(float energy)
{
    uint8_t cmd[10];
    uint8_t value[10];

    memset(cmd, 0x00, sizeof(cmd));
    if (energy >= 0.05) {
        energy -= 0.05;
    }

    if (energy < 0 )
    	ChangeDisplay2Value(_Icon_ChargeBar,_TCC_Charging_Bar0);
    else if (energy > 100)
    	ChangeDisplay2Value(_Icon_ChargeBar,_TCC_Charging_Bar0+100);
    else
    	ChangeDisplay2Value(_Icon_ChargeBar,(int)energy+_TCC_Charging_Bar0);
    if (energy < 10)
    	sprintf((char *) value, "%.1f", energy);
    else
    	sprintf((char *) value, "%d", (int)energy);
    string2ByteArray(value, cmd);
    DisplayValueToLcm(_Strting_Energy, cmd, sizeof(cmd));
}
uint8_t _battery_display_count = 0;
void ChangeBattMapAndValue(int soc)
{
    int i = (soc*36)/100;
    uint8_t cmd[5];
    uint8_t value[5];

	_battery_display_count++;
	if (_battery_display_count == 3 ) {
		if (_battery_display_ani == 0)
			_battery_display_ani= TRUE;
		else
			_battery_display_ani= FALSE ;
		_battery_display_count = 0;
	}

	if (pSysInfo->SystemPage == _PAGE_CHARGING) {
		if (i>=36)
			ChangeDisplay2Value(_Icon_ChargeCircle,_TCC_Charging_Circle0+36);
		else {
			if (_battery_display_ani) {
				ChangeDisplay2Value(_Icon_ChargeCircle, _TCC_Charging_Circle0+i);
			} else {
				ChangeDisplay2Value(_Icon_ChargeCircle, _TCC_Charging_Circle0+i+1);
			}
		}
	} else if (pSysInfo->SystemPage == _PAGE_COMPLETE)
		ChangeDisplay2Value(_Icon_CompleteCircle, _TCC_CompleteCircle0+i);
	else
		ChangeDisplay2Value(_Icon_CompleteCircle, _TCC_CompleteCircle0+i);

    memset(cmd, 0x00, sizeof(cmd));
    memset(value, 0x00, sizeof(value));

    sprintf((char *)value, "%d", soc);

    string2ByteArray(value, cmd);
    DisplayValueToLcm(_String_Battery, cmd, sizeof(cmd));
}
unsigned long GetPreChargeTimeoutValue(struct timeval _sour_time)
{
    struct timeval _end_time;
    gettimeofday(&_end_time, NULL);

    return 1000000 * (_end_time.tv_sec - _sour_time.tv_sec) + _end_time.tv_usec - _sour_time.tv_usec;
}
void ChangeTimeValue(int time)
{
    uint8_t cmd[6];
    uint8_t value[6];

    memset(cmd, 0x00, sizeof(cmd));
    sprintf((char *) value, "%d", time);
    string2ByteArray(value, cmd);
    DisplayValueToLcm(_String_ChargeTime, cmd, sizeof(cmd));
}

void changeWeatherValue(int _weather)
{
	switch (_weather) {
	case _WEATHER_TYPE_SUN:
		ChangeDisplay2Value(_Icon_Weather,_TCC_Sun);
		break;
	case _WEATHER_TYPE_CLOUDY:
		ChangeDisplay2Value(_Icon_Weather,_TCC_Cloudy);
		break;
	case _WEATHER_TYPE_RAIN:
		ChangeDisplay2Value(_Icon_Weather,_TCC_Rain);
		break;
	case _WEATHER_TYPE_THUNDER:
		ChangeDisplay2Value(_Icon_Weather,_TCC_Thunder);
		break;
	case _WEATHER_TYPE_SNOW:
		ChangeDisplay2Value(_Icon_Weather,_TCC_Snow);
		break;
	case _WEATHER_TYPE_FOG:
		ChangeDisplay2Value(_Icon_Weather,_TCC_Fog);
		break;
	}
}
void changeWeekValue(int _week)
{
    time_t timep;
    struct tm* tm;
    time(&timep);
    timep += (ShmDcCommonData->TZOffset * 60);

    tm = localtime(&timep);
	_week = tm->tm_wday;
	if (_week == 0 )
		_week = 7;
	ChangeDisplay2Value(_Icon_Week,_week);
}
void changeDegreeValue(int _degree)
{
    char value[16];
    memset(value, 0x00, sizeof(value));
    sprintf((char *)value,"%d",_degree);
    DisplayValueToLcm(_String_Tempture, (uint8_t *)value, sizeof(value));
}
void changeDateValue(char* _date)
{
    time_t timep;
    struct tm* tm;
    time(&timep);
    timep += (ShmDcCommonData->TZOffset * 60);

    tm = localtime(&timep);

    sprintf(_date, "%04d/%02d/%02d",
        tm->tm_year + 1900,
        tm->tm_mon + 1,
        tm->tm_mday);
    char value[16];
    memset(value, 0x00, sizeof(value));
    sprintf((char *)value,"%s",_date);
	DisplayValueToLcm(_String_Date, (uint8_t *)value, sizeof(value));
}
void changeLocationValue(int _location)
{
	//_location+=1000;
	//log_info("location:%d",_location);
	ChangeDisplay2Value(_Icon_Location,(short)_location);
}
void ShowLineRegisterCountDown()
{
    int _ten, _digits;
    pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(pSysInfo->CurGunSelected);
    if (pDcChargingInfo->TimeoutFlag == Timeout_LineReigster) {
        _ten = (TCC_LINEREGISTER_TIMEOUT - (GetTimeoutValue(pDcChargingInfo->TimeoutTimer) / uSEC_VAL)) / 10;
        _digits = (TCC_LINEREGISTER_TIMEOUT - (GetTimeoutValue(pDcChargingInfo->TimeoutTimer) / uSEC_VAL)) % 10;
        ChangeDisplay2Value(_Icon_ScanCntDownTen, (short)_TCC_CntDownNumber0+_ten);
        ChangeDisplay2Value(_Icon_ScanCntDownDigits, (short)_TCC_CntDownNumber0+ _digits);
    } else {
        log_info("Not get Line Register Count Down");
    }
}
void ShowAuthorizeCountDown()
{
    int _ten, _digits;
    
    if (pSysInfo->SystemTimeoutFlag == Timeout_ScanCard) {
        _ten = (TCC_SCANCARD_TIMEOUT - (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL)) / 10;
        _digits = (TCC_SCANCARD_TIMEOUT - (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL)) % 10;
        ChangeDisplay2Value(_Icon_AuthCntDownTen, (short)_TCC_CntDownNumber0 + _ten);
        ChangeDisplay2Value(_Icon_AuthCntDownDigits, (short)_TCC_CntDownNumber0 + _digits);
    }
    else {
        log_info("Not get Line Register Count Down");
    }
}
int old_money = 0;
int ClearQR_flag[2];
void ProcessPageInfo()
{
    // Show Gun Working and Type

    if (pSysInfo->SystemPage == _PAGE_IDLE) {
    	changeWeatherValue(ShmDcCommonData->WeatherID);
    	changeWeekValue(0);
    	changeDegreeValue((int)ShmDcCommonData->Temperature);
    	changeDateValue(&ShmDcCommonData->PresentTime[0]);
    	changeLocationValue(ShmDcCommonData->Location);
    	return;
    }
    if (pSysInfo->SystemPage == _PAGE_MAINTAIN) {
        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(LEFT_GUN_NUM);
        if (pDcChargingInfo->CCSGunType == _TYPE_CCS1_Liquid ||
                pDcChargingInfo->CCSGunType == _TYPE_CCS1_Natural) {
            ChangeDisplay2Value(_Icon_ShowLeft,_TCC_ShowLeft_CCS1_Off);

        } else if (pDcChargingInfo->CCSGunType == _TYPE_CCS2_Liquid ||
                pDcChargingInfo->CCSGunType == _TYPE_CCS2_Natural) {
            ChangeDisplay2Value(_Icon_ShowLeft,_TCC_ShowLeft_CCS2_Off);
        } else if (pDcChargingInfo->Type == _Type_Chademo) {
            ChangeDisplay2Value(_Icon_ShowLeft,_TCC_ShowLeft_CHAdeMo_Off);
        }

        // Set Right Gun
        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(RIGHT_GUN_NUM);
        if (pDcChargingInfo->CCSGunType == _TYPE_CCS1_Liquid ||
                pDcChargingInfo->CCSGunType == _TYPE_CCS1_Natural) {
            ChangeDisplay2Value(_Icon_ShowRight,_TCC_ShowRight_CCS1_Off);

        } else if (pDcChargingInfo->CCSGunType == _TYPE_CCS2_Liquid ||
                pDcChargingInfo->CCSGunType == _TYPE_CCS2_Natural) {
            ChangeDisplay2Value(_Icon_ShowRight,_TCC_ShowRight_CCS2_Off);
        } else if (pDcChargingInfo->Type == _Type_Chademo) {
            ChangeDisplay2Value(_Icon_ShowRight,_TCC_ShowRight_CHAdeMo_Off);
        }
    	return;
    }
    showGunWorkingType();
    for (uint8_t i = 0; i < pSysConfig->TotalConnectorCount; i++) {

        if (pSysInfo->CurGunSelected == i) {
            pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(pSysInfo->CurGunSelected);

            switch (pSysInfo->SystemPage) {
            case _PAGE_IDLE:
                StopSystemTimeoutDet();
            	break;
            case _PAGE_SELECT_PAY:
            	if (ShmDcCommonData->donate_flag[i] == TRUE) {
            		ChangeDisplay2Value(_Icon_WordAddFriend,_ICON_Empty);
            	} else
            		ChangeDisplay2Value(_Icon_WordAddFriend,_TCC_SelectPayMode);
            	StartSystemTimeoutDet(Timeout_SelectPayMode);
            	break;
            case _PAGE_SELECT_GUN:
            	ShowSelectGun();
            	ClearQR_flag[i] = FALSE;
				break;
            case _PAGE_BILL:
            	if(ClearQR_flag[i] == FALSE) {
            		ClearQrCode();
            		ClearQR_flag[i] = TRUE;
            	}
            	ChangeQrCode_Idle((char *)pSysConfig->SystemId);
            	break;
            case _PAGE_AUTHORIZE:
                StartSystemTimeoutDet(Timeout_ScanCard);
                /*
                int card_result = CreditCardPreAuth(CardReadFd, PREAUTHMONEY,"TCC Test", &ShmDcCommonData->pCreditCard[pSysInfo->CurGunSelected]);
				if (card_result > 0 ) {
					strcpy((char *)pSysConfig->UserId, (char *)ShmDcCommonData->pCreditCard[pSysInfo->CurGunSelected].CardNo);
				} else if (card_result < 0) {
					pSysInfo->SystemPage = _PAGE_AUTHORIZE_FAIL;
				}*/
            	//ChangeDisplay2Value(_Icon_Precharge,0);
            	//ChangeDisplay2Value(_Icon_Precharge,1);
                /*
            	if (ShmDcCommonData->GetCardNo[pSysInfo->CurGunSelected] == TRUE &&
            			ShmDcCommonData->AuthPass_flag[pSysInfo->CurGunSelected] != TRUE) {
            		//ShmDcCommonData->PreAuth_Config = _CREDITCARD_PREAUTH;
            		//ShmDcCommonData->PreAuth_Result = 0;
            		//sleep(3);
            		pSysInfo->SystemPage = _PAGE_SENSING;
            	}
                */
		        ChangeChargingRateValue((int)ShmDcCommonData->ChargingRate);
                ShowAuthorizeCountDown();
            	_Text_Running_Count = 1;
                break;
            case _PAGE_SENSING:
                if (ShmDcCommonData->TradeCancel == TRUE) {
                    TradeRunning(FALSE);
                }
                else
                    TradeRunning(TRUE);
                break;
            case _PAGE_PLUGIN:
            	_everyPageRollChange = 0;

                break;
            case _PAGE_ADD_FRIEND:
                ShowLineRegisterCountDown();
                break;
            case _PAGE_PRECHARGE:
            	//ChangeDisplay2Value(_Icon_Precharge,1);

            	RefreshProgressAnimation();
            	if (_everyPageRollChange == 0) {
            		ChangeDisplay2Value(_Icon_Precharge,_Text_Running_Count);
            		_Text_Running_Count >= 24 ? _Text_Running_Count = 24 : _Text_Running_Count++;
            	}
                break;
            case _PAGE_CHARGING:

                if (pDcChargingInfo->PresentChargingPower >= 0 &&
                        pDcChargingInfo->PresentChargingPower <= POWER_MAX_KW) {

                    ChangeChargingPowerValue(pDcChargingInfo->PresentChargingPower);
                } else {
                    ChangeChargingPowerValue(0);
                }
                if (pDcChargingInfo->PresentChargedEnergy >= 0.1 &&
                        pDcChargingInfo->PresentChargedEnergy <= ENERGY_MAX_KWH) {

                    ChangeChargingEnergyValue(pDcChargingInfo->PresentChargedEnergy);
                } else {
                    ChangeChargingEnergyValue(0);
                }
                if ( pDcChargingInfo->ChargingFee >= 0) {
                    ChangeChargingFeeValue(pDcChargingInfo->ChargingFee);

                }
                if (pDcChargingInfo->RemainChargingDuration >= 0 &&
                        pDcChargingInfo->RemainChargingDuration <= TIME_MAX_SEC) {
                	ChangeTimeValue(pDcChargingInfo->RemainChargingDuration/60);
                } else {
                	ChangeTimeValue(0);
                }
                ChangeBattMapAndValue(pDcChargingInfo->EvBatterySoc);
                StartSystemTimeoutDet(Timeout_ReturnViewPage);
                break;
            case _PAGE_COMPLETE:
            case _PAGE_PAYFAIL:

                if (pDcChargingInfo->PresentChargedEnergy >= 0.1 &&
                        pDcChargingInfo->PresentChargedEnergy <= ENERGY_MAX_KWH) {
                    ChangeChargingEnergyValue(pDcChargingInfo->PresentChargedEnergy);
                } else {
                    ChangeChargingEnergyValue(0);
                }
                if ( ShmDcCommonData->finalcost[i] >= 0 && ShmDcCommonData->finalcost_flag[i] == TRUE) {
                	StopGunInfoTimeoutDet(i);
					ChangeChargingFeeValue(ShmDcCommonData->finalcost[i]);
					//ShmDcCommonData->finalcost_flag[i] = FALSE;
                }
                ChangeCarBonValue(pDcChargingInfo->PresentChargedEnergy);
                ChangeBattMapAndValue(pDcChargingInfo->EvBatterySoc);
                //StartSystemTimeoutDet(Timeout_ReturnViewPage);
				
                break;

            case _PAGE_PLUGOUT:
            	/*
                if (pSysConfig->isQRCode) {
                    if (pSysConfig->QRCodeMadeMode == NO) {
                        //uint8_t len = strlen((char *)pSysConfig->SystemId);
                        ChangeQrCode_Idle((char *)pSysConfig->SystemId);
                    } else {
                        //uint8_t len = strlen((char *)pSysConfig->QRCodeContent);
                        ChangeQrCode_Idle((char *)pSysConfig->QRCodeContent);
                    }
                    //ChangeQrCode_Idle((char *)pSysConfig->SystemId);
                }*/
            	break;
            case _PAGE_PAYING:

            	break;
            }
        }
    }
}
void ChangeWarningFunc()
{
    uint8_t cmd[7] = {0};
    uint8_t i = 0;
    //uint8_t j = 0;
    //log_info("ChangeWarningFunc ");
    // 最多一次五筆
    //log_info("LCM PageIndex = %d ", pSysWarning->PageIndex);
    //log_info("WarningCount = %d ", pSysWarning->WarningCount);
//#if !defined DD360 && !defined DD360Audi && !defined DD360ComBox
    for (i = 0; (i + pSysWarning->PageIndex * 5) < pSysWarning->WarningCount; i++) {
        log_info("Warming Code[%d]:%s",i,&pSysWarning->WarningCode[i][0]);
        memset(cmd, 0x00, sizeof(cmd));
        if ((i) >= 5) {
            break;
        }

        //error code
        string2ByteArray(&pSysWarning->WarningCode[i + pSysWarning->PageIndex * 5][0], cmd);
        DisplayValueToLcm(_Strting_Warming0 + ((i) * 0x10), cmd, sizeof(cmd));
        //警告標示
        memset(cmd, 0x00, sizeof(cmd));

        cmd[0] = 0x00;
        cmd[1] = 1;
        DisplayValueToLcm(_Icon_Warming0 + ((i) * 2), cmd, 2);
    }

    memset(cmd, 0x00, sizeof(cmd));
    for (; i < 5; i++) {
        DisplayValueToLcm(_Strting_Warming0 + ((i) * 0x10), cmd, sizeof(cmd));
        DisplayValueToLcm(_Icon_Warming0 + ((i) * 2), cmd, 2);
    }
}

void ShowCabientVersionDefaultText()
{
    char value[16];
    memset(value, 0x00, sizeof(value));
    sprintf((char *)value,"%s","Cabient:");
    DisplayValueToLcm(_Version_Cabient_Name_Text, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s","BootLoader:");
    DisplayValueToLcm(_Version_Cabient_BootLoader_Text, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s","Kernel Fw:");
    DisplayValueToLcm(_Version_Cabient_Kernel_Text, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s","CSU Fw:");
    DisplayValueToLcm(_Version_Cabient_CSU_Text, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s","Priamry Fw:");
    DisplayValueToLcm(_Version_Cabient_Priamry_Text, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s","Relay(0) Fw:");
    DisplayValueToLcm(_Version_Cabient_Relay0_Text, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s","Relay(1) Fw:");
    DisplayValueToLcm(_Version_Cabient_Relay1_Text, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s","Fan Fw:");
    DisplayValueToLcm(_Version_Cabient_Fan_Text, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s","IP Addr:");
    DisplayValueToLcm(_Version_Cabient_IPAddr_Text, (uint8_t *)value, sizeof(value));
    if (ShmDcCommonData->PSU_Number > 0 && ShmDcCommonData->PSU_Number <= 12) {
        sprintf((char *)value,"%s","Primary");
        DisplayValueToLcm(_Version_Cabient_Primary_Text, (uint8_t *)value, sizeof(value));
        sprintf((char *)value,"%s","Secondary");
        DisplayValueToLcm(_Version_Cabient_Secondary_Text, (uint8_t *)value, sizeof(value));
        for(uint8_t i = 0 ; i < ShmDcCommonData->PSU_Number ; i++) {
            sprintf((char *)value,"PSU(%d):",i+1);
            DisplayValueToLcm(_Version_Cabient_PSU1_Text+i*0x10, (uint8_t *)value, sizeof(value));
        }
    }
}
void ShowDispenserVersionDefautlText()
{
    char value[16];
    memset(value, 0x00, sizeof(value));
    sprintf((char *)value,"%s","Dispenser:");
    DisplayValueToLcm(_Version_Dispenser_Name_Text, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s","BootLoader:");
    DisplayValueToLcm(_Version_Dispenser_BootLoader_Text, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s","Kernel Fw:");
    DisplayValueToLcm(_Version_Dispenser_Kernel_Text, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s","CSU Fw:");
    DisplayValueToLcm(_Version_Dispenser_CSU_Text, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s","Relay Fw:");
    DisplayValueToLcm(_Version_Dispenser_Relay_Text, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s","Fan Fw:");
    DisplayValueToLcm(_Version_Dispenser_Fan_Text, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s","Prim Fw:");
    DisplayValueToLcm(_Version_Dispenser_Priamry_Text, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s","LCM Hw:");
    DisplayValueToLcm(_Version_Dispenser_LCM_Text, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s","LED Fw:");
    DisplayValueToLcm(_Version_Dispenser_LED_Text, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s","Connector(0):");
    DisplayValueToLcm(_Version_Dispenser_Connector0_Text, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s","Connector(1):");
    DisplayValueToLcm(_Version_Dispenser_Connector1_Text, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s","IP Addr:");
    DisplayValueToLcm(_Version_Dispenser_IPAddr_Text, (uint8_t *)value, sizeof(value));
}
void ShowCabientVersion()
{
    char value[16];
    memset(value, 0x00, sizeof(value));
    sprintf((char *)value,"%s",ShmDcCommonData->CabinetModelName);
    DisplayValueToLcm(_Version_Cabient_Model_value, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s",ShmDcCommonData->CabinetBoolLoaderVersion);
    DisplayValueToLcm(_Version_Cabient_BootLoader_value, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s",ShmDcCommonData->CabinetKernelVersion);
    DisplayValueToLcm(_Version_Cabient_Kernel_value, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s",ShmDcCommonData->CabinetRFSystemVersion);
    DisplayValueToLcm(_Version_Cabient_CSU_value, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s",ShmDcCommonData->CabinetPrimaryVersion);
    DisplayValueToLcm(_Version_Cabient_Priamry_value, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s",ShmDcCommonData->CabinetRelay0Version);
    DisplayValueToLcm(_Version_Cabient_Relay0_value, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s",ShmDcCommonData->CabinetRelay1Version);
    DisplayValueToLcm(_Version_Cabient_Relay1_value, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s",ShmDcCommonData->CabinetFanVersion);
    DisplayValueToLcm(_Version_Cabient_Fan_value, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s",ShmDcCommonData->CabinetIPAddr);
    DisplayValueToLcm(_Version_Cabient_IPAddr_value, (uint8_t *)value, sizeof(value));
    if (ShmDcCommonData->PSU_Number > 0 && ShmDcCommonData->PSU_Number < 12) {
        for(uint8_t i = 0 ; i < ShmDcCommonData->PSU_Number ; i++) {
            if (i>=6) {
                sprintf((char *)value,"%s",ShmDcCommonData->PsuVer[(i-6)].DCVersion);
                DisplayValueToLcm(_Version_Cabient_PSU_Prim7_value+(i-6)*0x10, (uint8_t *)value, sizeof(value));
                sprintf((char *)value,"%s",ShmDcCommonData->PsuVer[(i-6)].FPCVersion);
                DisplayValueToLcm(_Version_Cabient_PSU_Sec7_value+(i-6)*0x10, (uint8_t *)value, sizeof(value));
                continue;
            }
            sprintf((char *)value,"%s",ShmDcCommonData->PsuVer[i].DCVersion);
            DisplayValueToLcm(_Version_Cabient_PSU_Prim1_value+i*0x10, (uint8_t *)value, sizeof(value));
            sprintf((char *)value,"%s",ShmDcCommonData->PsuVer[i].FPCVersion);
            DisplayValueToLcm(_Version_Cabient_PSU_Sec1_value+i*0x10, (uint8_t *)value, sizeof(value));
        }
    }
}
void ShowDispenserVersion()
{
    char value[32];
    memset(value, 0x00, sizeof(value));
    sprintf((char *)value,"%s",pSysConfig->ModelName);
    DisplayValueToLcm(_Version_Dispenser_Model_value, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s",pSysInfo->CsuBootLoadFwRev);
    DisplayValueToLcm(_Version_Dispenser_BootLoader_value, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s",pSysInfo->CsuKernelFwRev);
    DisplayValueToLcm(_Version_Dispenser_Kernel_value, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s",pSysInfo->CsuRootFsFwRev);
    DisplayValueToLcm(_Version_Dispenser_CSU_value, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s",pSysInfo->RelayModuleFwRev);
    DisplayValueToLcm(_Version_Dispenser_Relay_value, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s",pSysInfo->FanModuleFwRev);
    DisplayValueToLcm(_Version_Dispenser_Fan_value, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s",pSysInfo->CsuPrimFwRev);
    DisplayValueToLcm(_Version_Dispenser_Priamry_value, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s",pSysInfo->LcmHwRev);
    DisplayValueToLcm(_Version_Dispenser_LCM_value, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s",pSysInfo->LedModuleFwRev);
    DisplayValueToLcm(_Version_Dispenser_LED_value, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s",pSysInfo->Connector1FwRev);
    DisplayValueToLcm(_Version_Dispenser_Connector0_value, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s",pSysInfo->Connector2FwRev);
    DisplayValueToLcm(_Version_Dispenser_Connector1_value, (uint8_t *)value, sizeof(value));
    sprintf((char *)value,"%s",pSysConfig->Eth0Interface.EthIpAddress);
    DisplayValueToLcm(_Version_Dispenser_IPAddr_value, (uint8_t *)value, sizeof(value));
}
/*
void InformationShow()
{
    is_show = true;
    if (_showInformIndex == 0 ) {
        pSysInfo->PageIndex = __SHOW_CABIENT_VERSION;
    } else {
        pSysInfo->PageIndex = __SHOW_DISPENSER_VERASION;
        ShowDispenserVersion();
    }
}
*/

void DefautLayOut()
{
	int i;
	for (i = 0 ; i <= 0x5C ; i+=2 ) {
		ChangeDisplay2Value(0x1000+i,1);
		if (i==0x28 || i ==0x2A)
			continue;
	}
	ChangeDisplay2Value(_Icon_MobilePay,0);
	ChangeDisplay2Value(_Icon_CardPay,0);
	ChangeDisplay2Value(0x5000,1);

	ShowSelectGun();
}
/*
static int InitialRfidPort(void)
{
    int fd = open(rfidPortName, O_RDWR);
    struct termios tios;
    struct AlarmCodeData *pAlarmCode = (struct AlarmCodeData *)GetShmAlarmCodeData();

    if (fd != FAIL) {
        ioctl (fd, TCGETS, &tios);
        tios.c_cflag = B115200 | CS8 | CLOCAL | CREAD;
        tios.c_lflag = 0;
        tios.c_iflag = 0;
        tios.c_oflag = 0;
        tios.c_cc[VMIN] = 0;
        tios.c_cc[VTIME] = (uint8_t) 1;
        tios.c_lflag = 0;
        tcflush(fd, TCIFLUSH);
        ioctl(fd, TCSETS, &tios);
    }

    if (fd < 0) {
        pAlarmCode->AlarmEvents.bits.RfidModuleCommFail = 1;
    }

    return fd;
}
*/
int main(void)
{
    bool defaulttext = false;
    if (CreateAllCsuShareMemory() == FAIL) {
        log_error("create share memory error");
        return FAIL;
    }

    MappingGunChargingInfo("LCM Control Task");

    pSysConfig = (struct SysConfigData *)GetShmSysConfigData();
    pSysInfo = (struct SysInfoData *)GetShmSysInfoData();
    pSysWarning = (struct WARNING_CODE_INFO *)GetShmSysWarningInfo();
    ShmFanModuleData = (struct FanModuleData *)GetShmFanModuleData();;
    ShmPrimaryMcuData = (struct PrimaryMcuData *)GetShmPrimaryMcuData();
    ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo();
    ShmDcCommonData = (DcCommonInfo *)GetShmDcCommonData();
    ShmOCPP16Data = (struct OCPP16Data *)GetShmOCPP16Data();
    struct StatusCodeData *ShmStatusCodeData = (struct StatusCodeData *)GetShmStatusCodeData();;

    _port = CreateCommunicationLcmPort();
    uint8_t changeWarningPriority = 0;
    uint8_t curWarningCount = 255;
    ChangeBackLight(true);
    _totalCount = pSysConfig->TotalConnectorCount;
    _everyPageRollChange = 0;
    //Initialization();

    //printf("_LCM_COMPLETE ");
    //ChangeToOtherPage(_LCM_COMPLETE);
    DefautLayOut();
    //return 0;
    //uint8_t index = 1;

	int result = 0;

    ShmDcCommonData->PSU_Number = 12;
    /*
    CardReadFd = InitialRfidPort();
    if (CardReadFd <0) {
    	log_info("Card Read Port open fail!");
    }*/

    CheckLCMPressed();

    while (_port != -1) {
        if (strcmp((char *)pSysInfo->LcmHwRev, moduleName) != 0x00) {
            GetCurrentPage();
            sleep(1);

            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.LcmModuleCommFail = true;

        } else {
            UpdateLcmFunction(ShmDcCommonData,_port);

            ///*
            // Warning 處理
            if (curWarningCount != pSysWarning->WarningCount) {
                changeWarningPriority = 0;
                pSysWarning->PageIndex = 0;
                curWarningCount = pSysWarning->WarningCount;
                ChangeWarningFunc();
            } else if (pSysWarning->WarningCount > 5 && changeWarningPriority == 0) {
                // 當有兩頁 Warning 則每隔三秒改變一次
                if (pSysWarning->PageIndex == 0) {
                    pSysWarning->PageIndex = 1;
                } else {
                    pSysWarning->PageIndex = 0;
                }

                ChangeWarningFunc();
            }
            ///*
            // Show Default Text
            if (!defaulttext) {
                ShowCabientVersionDefaultText();
                ShowDispenserVersionDefautlText();
                defaulttext = true;
            }
            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.LcmModuleCommFail = false;

            // 頁面資訊處理
            ProcessPageInfo();

            // 換頁處理
            //GetCurrentPage(); //DS60-120 add
            /*
            if (pSysConfig->ShowInformation == YES && pSysInfo->SystemPage == _PAGE_AUTHORIZE) {
                InformationShow();
                ChangeToOtherPage(pSysInfo->PageIndex);
                usleep(100000);
                continue;
            } else {
                if (is_show)
                    _showInformIndex >= 1 ? _showInformIndex = 0 : _showInformIndex++;
                is_show = false;
            }*/
            GetCurrentPage(); //DS60-120 add

            ChangeCurPage();
            changeWarningPriority >= 30 ? changeWarningPriority = 0 : changeWarningPriority++;

            usleep(10000); //*/

            /*
            ProcessPageInfo();
            GetCurrentPage();
            ChangeCurPage();
            usleep(10000);
            //*/
        }
    } //while

    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.LcmModuleCommFail = true;

    log_info("Close LCM Uart Port");
    CloseCommunicationLcmPort();

    return FAIL;
}