#include    <sys/time.h>
#include    <sys/timeb.h>
#include    <sys/types.h>
#include    <sys/stat.h>
#include    <sys/types.h>
#include    <sys/ioctl.h>
#include    <sys/socket.h>
#include    <sys/ipc.h>
#include    <sys/shm.h>
#include    <sys/shm.h>
#include    <sys/mman.h>
#include    <linux/can.h>
#include    <linux/can/raw.h>
#include    <linux/wireless.h>
#include    <arpa/inet.h>
#include    <netinet/in.h>
#include <signal.h>
#include    <unistd.h>
#include    <stdarg.h>
#include    <stdio.h>      /*標準輸入輸出定義*/
#include    <stdlib.h>     /*標準函數庫定義*/
#include    <unistd.h>     /*Unix 標準函數定義*/
#include    <fcntl.h>      /*檔控制定義*/
#include    <termios.h>    /*PPSIX 終端控制定義*/
#include    <errno.h>      /*錯誤號定義*/
#include    <errno.h>
#include    <string.h>
#include    <time.h>
#include    <ctype.h>
#include    <ifaddrs.h>
#include    "../../define.h"
#include    "Config.h"

//#define Debug

#define DoIPAddress "192.168.100.1"
#define DoTcpPort       36000
#define TriggerMsgeNum      20

int StoreLogMsg(const char *fmt, ...);
#define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
#define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
#define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args)

struct ApplicationPacket {
    unsigned char Se;
    unsigned char Id;
    unsigned char Op;
    unsigned char Len;
    unsigned char RegisterNum;
    unsigned char Data[250];
};

struct SysConfigAndInfo         *ShmSysConfigAndInfo;
struct StatusCodeData           *ShmStatusCodeData;
struct PsuData              *ShmPsuData;
struct OCPP16Data               *ShmOCPP16Data;
struct PrimaryMcuData           *ShmPrimaryMcuData;
int                             TcpSock = 0;
unsigned char                   PacketSe;
struct ChargingInfoData         *ChargingData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
struct timeb                    TriggerTimeUp[2][TriggerMsgeNum];
struct WARNING_CODE_INFO        PreSysWarningInfo;
int DisconnectFlag;

int StoreLogMsg(const char *fmt, ...)
{
    char Buf[4096 + 256];
    char buffer[4096];
    va_list args;
    struct timeb  SeqEndTime;
    struct tm *tm;

    va_start(args, fmt);
    int rc = vsnprintf(buffer, sizeof(buffer), fmt, args);
    va_end(args);

    memset(Buf, 0, sizeof(Buf));
    ftime(&SeqEndTime);
    SeqEndTime.time = time(NULL);
    tm = localtime(&SeqEndTime.time);

    if (ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag == 1) {
        sprintf(Buf, "%02d:%02d:%02d:%03d - %s",
                tm->tm_hour, tm->tm_min, tm->tm_sec, SeqEndTime.millitm, buffer);
        printf("%s \n", Buf);
    } else {
        sprintf(Buf, "echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog",
                tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, SeqEndTime.millitm,
                buffer,
                tm->tm_year + 1900, tm->tm_mon + 1);
        system(Buf);
    }

    return rc;
}

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

    StartTime = (unsigned int)ST.time;
    StopTime = (unsigned int)ET.time;
    return (StopTime - StartTime) * 1000 + ET.millitm - ST.millitm;
}

int InitShareMemory()
{
    int result = 1;
    int MeterSMId;

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

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

    if ((MeterSMId = shmget(ShmPrimaryMcuKey, sizeof(struct PrimaryMcuData), 0777)) < 0) {
        DEBUG_ERROR("shmget ShmPrimaryMcuData NG\n");
        result = 0;
    } else if ((ShmPrimaryMcuData = shmat(MeterSMId, NULL, 0)) == (void *) - 1) {
        DEBUG_ERROR("shmat ShmPrimaryMcuData NG\n");
        result = 0;
    }
    return result;
}

int CheckNetworkStatus()
{
    //printf("ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress=%s\n",ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress);
    if (strstr(ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress, "192.168.100") != NULL) {
        return 1;
    } else {
        return 0;
    }
}

int TcpConnected()
{
    struct sockaddr_in dest;
    struct timeval tv;
    int flag;

    if (TcpSock > 0) {
        close(TcpSock);
    }

    if ((TcpSock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        DEBUG_ERROR("Open TCP socket NG");
        return -1;
    }
    /*   flag=fcntl (TcpSock, F_GETFL, 0);
       if(flag>=0)
       {
           flag |= O_NONBLOCK;
           fcntl(TcpSock,F_SETFL, flag );
       }*/
    tv.tv_sec = 0;
    tv.tv_usec = 100000;
    setsockopt(TcpSock, SOL_SOCKET,  SO_RCVTIMEO, &tv, sizeof(struct timeval));
    setsockopt(TcpSock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(struct timeval));
    flag = 1;
    setsockopt(TcpSock, SOL_SOCKET, MSG_NOSIGNAL, &flag, sizeof(flag));

    memset(&dest, 0, sizeof(dest));
    dest.sin_family = AF_INET;
    dest.sin_port = htons(DoTcpPort);
    inet_aton(DoIPAddress, (struct in_addr *) &dest.sin_addr.s_addr);

    if (connect(TcpSock, (struct sockaddr *) &dest, sizeof(dest)) != 0) {
        close(TcpSock);
        return -1;
    }
    return TcpSock;
}
void AddFaultCodeToBuf(unsigned char *Code)
{
    if (ShmSysConfigAndInfo->SysWarningInfo.WarningCount < 10) {
        memcpy(&ShmSysConfigAndInfo->SysWarningInfo.WarningCode[ShmSysConfigAndInfo->SysWarningInfo.WarningCount][0], Code, strlen(Code));
        ShmSysConfigAndInfo->SysWarningInfo.WarningCount++;
    }
}

void RemoveFaultCodeToBuf(unsigned char *Code)
{
    unsigned char find = 0x01;
    char _code[7];
    sprintf(_code, "%s", Code);

    // 把相關的錯誤碼一次移除,避免重複顯示
    while (find) {
        find = 0x00;
        for (unsigned char i = 0; i < ShmSysConfigAndInfo->SysWarningInfo.WarningCount; i++) {
            if (find == 0x00) {
                if (memcmp(&ShmSysConfigAndInfo->SysWarningInfo.WarningCode[i][0], _code, 7) == 0) {
                    find = 0x01;
                }
            } else {
                memcpy(&ShmSysConfigAndInfo->SysWarningInfo.WarningCode[i - 1][0],
                       &ShmSysConfigAndInfo->SysWarningInfo.WarningCode[i][0], 7);
            }
        }

        if (find) {
            ShmSysConfigAndInfo->SysWarningInfo.WarningCount--;
        }
    }
}

int StatusCodeProcessing(unsigned char *StatusCode)
{
    unsigned char Rtn = 0;
    int ByteCount, BitCount;
    unsigned char tmp, EventCodeTmp[7];

    if (strlen(StatusCode) != 6) {
        return 0;
    }
    memset(EventCodeTmp, 0, sizeof(EventCodeTmp));
    memcpy(EventCodeTmp, StatusCode, strlen(StatusCode));

    if (*(StatusCode + 1) == 0x34) { //alarm from power cabinet itself
        if (StatusCode[0] == 0x30) { //trigger
            for (unsigned char i = 0; i < ShmSysConfigAndInfo->SysWarningInfo.WarningCount; i++) {
                if (memcmp(&ShmSysConfigAndInfo->SysWarningInfo.WarningCode[i][0], EventCodeTmp, 7) == 0) {
                    Rtn = 1;
                    break;
                }
            }
            if (Rtn == 0) {
                AddFaultCodeToBuf(EventCodeTmp);
            }
            Rtn = 1;
        } else if (StatusCode[0] == 0x31) { //recovery
            RemoveFaultCodeToBuf(EventCodeTmp);
            Rtn = 1;
        }
    } else {
        switch (*(StatusCode + 2)) {
        case 0x31://Fault
            for (ByteCount = 0; ByteCount < (sizeof(FaultStatusCode) / 6); ByteCount++) {
                if (memcmp(FaultStatusCode[ByteCount] + 1, StatusCode + 1, 5) == 0) {
                    if (StatusCode[0] == 0x30) { //trigger
                        ShmStatusCodeData->FaultCode.FaultEvents.FaultVal[ByteCount / 8] |= 1 << (ByteCount % 8);
                    } else if (StatusCode[0] == 0x31) { //recovery
                        ShmStatusCodeData->FaultCode.FaultEvents.FaultVal[ByteCount / 8] &= 0 << (ByteCount % 8);
                    }
                    Rtn = 1;
                    break;
                }
            }
            break;
        case 0x32://Alarm
            for (ByteCount = 0; ByteCount < (sizeof(AlarmStatusCode) / 6); ByteCount++) {
                if (memcmp(AlarmStatusCode[ByteCount] + 1, StatusCode + 1, 5) == 0) {

                    if (StatusCode[0] == 0x30) { //trigger
                        ShmStatusCodeData->AlarmCode.AlarmEvents.AlarmVal[ByteCount / 8] |= 1 << (ByteCount % 8);
                    } else if (StatusCode[0] == 0x31) { //recovery
                        ShmStatusCodeData->AlarmCode.AlarmEvents.AlarmVal[ByteCount / 8] &= 0 << (ByteCount % 8);
                    }
                    Rtn = 1;
                    break;
                }
            }
            break;
        case 0x33://Information
            for (ByteCount = 0; ByteCount < (sizeof(InfoStatusCode) / 6); ByteCount++) {
                if (memcmp(InfoStatusCode[ByteCount] + 1, StatusCode + 1, 5) == 0) {
                    if (StatusCode[0] == 0x30) { //trigger
                        ShmStatusCodeData->InfoCode.InfoEvents.InfoVal[ByteCount / 8] |= 1 << (ByteCount % 8);
                    } else if (StatusCode[0] == 0x31) { //recovery
                        ShmStatusCodeData->InfoCode.InfoEvents.InfoVal[ByteCount / 8] &= 0 << (ByteCount % 8);
                    }
                    Rtn = 1;
                    break;
                }
            }
            break;
        default:
            break;
        }
    }

    return Rtn;
}

int SendPacket(unsigned char Id, unsigned char Op, unsigned char RegNum, unsigned char DataLen, unsigned char *Data)
{
    int Rtn = 0, PacketLen, Tmp;
    struct ApplicationPacket SendBuffer;
    struct timeb ST, ET;

    memset(&SendBuffer, 0, sizeof(struct ApplicationPacket));
    SendBuffer.Se = (PacketSe++);
    SendBuffer.Id = Id;
    SendBuffer.Op = Op;
    SendBuffer.Len = DataLen + 1;
    SendBuffer.RegisterNum = RegNum;
    if (DataLen > 0) {
        memcpy(SendBuffer.Data, Data, DataLen);
    }
    PacketLen = SendBuffer.Len + 4;
    ftime(&ST);
    while (Rtn < PacketLen) {
        Tmp = send(TcpSock, &SendBuffer + Rtn, PacketLen - Rtn, MSG_NOSIGNAL);
        if (Tmp > 0) {
            Rtn += Tmp;
        }
        ftime(&ET);
        if (DiffTimeb(ST, ET) > 500) {
            DisconnectFlag++;
            if (DisconnectFlag >= 10) {
                DisconnectFlag = 10;
            }
#ifdef Debug
            printf("Send Packet Timeout(%d/%d): SE=%d, ID=%d, OP=%d, Reg=%d",
                   Rtn, PacketLen, PacketSe, Id, Op, RegNum);
#endif
            return 0;
        }
    }
    return Rtn;
}

int RecvPacket(unsigned char *DataLen, struct ApplicationPacket *Packet)
{
    int Rtn = 0, Tmp;
    unsigned char TmpBuf[250];
    struct timeb ST, ET;

    memset(Packet, 0, sizeof(struct ApplicationPacket));
    memset(TmpBuf, 0, sizeof(TmpBuf));
    ftime(&ST);
    while (Rtn < 5) {
        Tmp = recv(TcpSock, TmpBuf + Rtn, 5 - Rtn, 0);
        if (Tmp > 0) {
            Rtn += Tmp;
        }
        ftime(&ET);
        if (DiffTimeb(ST, ET) > 500) {
            DisconnectFlag++;
            if (DisconnectFlag >= 10) {
                DisconnectFlag = 10;
            }
#ifdef Debug
            printf("Recv Packet header Timeout(%d/5)(disconnect count=%d): SE=%d, ID=%d, OP=%d, Len=%d, Reg=%d",
                   Rtn, DisconnectFlag, TmpBuf[0], TmpBuf[1], TmpBuf[2], TmpBuf[3], TmpBuf[4]);
#endif
            return 0;
        }
    }
    if ((TmpBuf[0] > 255)/*||(TmpBuf[1]>2)*/ || (TmpBuf[2] > 3) || (TmpBuf[3] > 250)) {
        DEBUG_INFO("Recv Wrong Packet header (%d/5): SE=%d, ID=%d, OP=%d, Len=%d, Reg=%d",
                   Rtn, TmpBuf[0], TmpBuf[1], TmpBuf[2], TmpBuf[3], TmpBuf[4]);
        return 0;
    }
    memcpy(Packet, TmpBuf, 5);
    *DataLen = Packet->Len - 1;
    memset(TmpBuf, 0, sizeof(TmpBuf));
    Rtn = 0;
    ftime(&ST);
    while (Rtn < *DataLen) {
        Tmp = recv(TcpSock, TmpBuf + Rtn, *DataLen - Rtn, 0);
        if (Tmp > 0) {
            Rtn += Tmp;
        }
        ftime(&ET);
        if (DiffTimeb(ST, ET) > 500) {
            DEBUG_INFO("Recv Packet Timeout(%d/%d): SE=%d, ID=%d, OP=%d, Reg=%d",
                       Rtn, *DataLen, Packet->Se, Packet->Id, Packet->Op, Packet->RegisterNum);
            return 0;
        }
    }
    memcpy(Packet->Data, TmpBuf, *DataLen);
    DisconnectFlag = 0;
    return Rtn;
}

int WriteModelName()
{
    unsigned char Tmp = 0;
    unsigned char TmpBuf[255];
    struct ApplicationPacket PacketData;

    memset(TmpBuf, 0, sizeof(TmpBuf));
    memset(&PacketData, 0, sizeof(struct ApplicationPacket));

    memcpy(TmpBuf, ShmSysConfigAndInfo->SysConfig.ModelName, strlen(ShmSysConfigAndInfo->SysConfig.ModelName));
    Tmp = (unsigned char)(ShmPrimaryMcuData->InputDet.bits.Key2 << 2 | ShmPrimaryMcuData->InputDet.bits.Key1 << 1 | ShmPrimaryMcuData->InputDet.bits.Key0);
    TmpBuf[strlen(ShmSysConfigAndInfo->SysConfig.ModelName)] = Tmp; //Dispenser switch value
#ifdef Debug
    printf("WriteModelName(%s)(%d) => ", ShmSysConfigAndInfo->SysConfig.ModelName, Tmp);
#endif
    if (SendPacket(0xFF, 0x02, 0x01, strlen(ShmSysConfigAndInfo->SysConfig.ModelName) + 1, TmpBuf) <= 0) {
#ifdef Debug
        printf("SendPacket Fail\n");
#endif
        return -1;
    }
    if (RecvPacket(&Tmp, &PacketData) <= 0) {
#ifdef Debug
        printf("RecvPacket Fail\n");
#endif
        return -1;
    }
    if (PacketData.Data[0] != 1) { //!=OK
#ifdef Debug
        printf("NG\n");
#endif
        return -1;
    }
#ifdef Debug
    printf("OK\n");
#endif
    return 1;
}

int ReadConnectorID()
{
    unsigned char Tmp = 0;
    struct ApplicationPacket PacketData;

    memset(&PacketData, 0, sizeof(struct ApplicationPacket));
#ifdef Debug
    printf("ReadConnectorID => ");
#endif
    if (SendPacket(0xFF, 0x01, 0x02, 0, PacketData.Data) <= 0) {
#ifdef Debug
        printf("SendPacket Fail\n");
#endif
        return -1;
    }
    if (RecvPacket(&Tmp, &PacketData) <= 0) {
#ifdef Debug
        printf("RecvPacket Fail\n");
#endif
        return -1;
    }
    if (PacketData.Data[0] != 1) { //!=OK
#ifdef Debug
        printf("NG\n");
#endif
        return -1;
    }
#ifdef Debug
    printf("OK (Left connector ID = %d, Right connector ID = %d)\n", PacketData.Data[1], PacketData.Data[2]);
#endif
    return 1;
}

int ReadDoStatus()
{
    unsigned char Tmp = 0, count, Rtn;
    struct ApplicationPacket PacketData;
    unsigned char StatusArray[20][6];
    unsigned char EventCodeTmp[7];

    memset(&PacketData, 0, sizeof(struct ApplicationPacket));
    memset(StatusArray, 0, sizeof(StatusArray));
#ifdef Debug
    printf("ReadDoStatus => ");
#endif
    if (SendPacket(0x01, 0x01, 0x03, 0, PacketData.Data) <= 0) {
#ifdef Debug
        printf("SendPacket Fail\n");
#endif
        return -1;
    }
    if (RecvPacket(&Tmp, &PacketData) <= 0) {
#ifdef Debug
        printf("RecvPacket Fail\n");
#endif
        return -1;
    }
    if (PacketData.Data[0] != 1) { //!=OK
#ifdef Debug
        printf("NG\n");
#endif
        return -1;
    }
    Tmp--;//decrase OK/NG byte
    if (Tmp < 6) {
        if (ShmSysConfigAndInfo->SysWarningInfo.WarningCount > 0) {
            for (unsigned char i = 0; i < ShmSysConfigAndInfo->SysWarningInfo.WarningCount; i++) {
                if (ShmSysConfigAndInfo->SysWarningInfo.WarningCode[i][1] >= 0x33) { //from backend or power cabinet
                    memset(EventCodeTmp, 0, sizeof(EventCodeTmp));
                    memcpy(EventCodeTmp, ShmSysConfigAndInfo->SysWarningInfo.WarningCode[i], sizeof(EventCodeTmp));
                    RemoveFaultCodeToBuf(EventCodeTmp);
                }
            }
        }
#ifdef Debug
        printf("no alarm (%d)\n", Tmp);
#endif
        return -1;
    }
#ifdef Debug
    printf("OK, (%d) ", Tmp);
    //printf("PacketData.Se=%d\n",PacketData.Se);
    //printf("PacketData.Id=%d\n",PacketData.Id);
    //printf("PacketData.Op=%d\n",PacketData.Op);
    //printf("PacketData.Len=%d\n",PacketData.Len);
    //printf("PacketData.RegisterNum=%d\n",PacketData.RegisterNum);
    //for(Rtn=0;Rtn<=PacketData.Len-1;Rtn++)
    //printf("PacketData.Data[%d]=0x%x\n",Rtn,PacketData.Data[Rtn]);
#endif
    for (count = 0; count < Tmp; count += 6) {
        //if((Tmp-count)<6)
        strncpy(StatusArray[count / 6], (PacketData.Data + 1) + count, 6);
        Rtn = 0;
        for (unsigned char i = 0; i < ShmSysConfigAndInfo->SysWarningInfo.WarningCount; i++) {
            if (memcmp(&ShmSysConfigAndInfo->SysWarningInfo.WarningCode[i][0], StatusArray[count / 6], 6) == 0) {
                Rtn = 1;
                break;
            }
        }
        if (Rtn == 0) {
            AddFaultCodeToBuf(StatusArray[count / 6]);
        }
        //Rtn=StatusCodeProcessing(StatusArray[count/6]);
#ifdef Debug
        printf("(%d)(%s) = %s,  ", count / 6, Rtn == 1 ? "Process OK" : "Process NG", StatusArray[count / 6]);
#endif
    }
    for (unsigned char i = 0; i < ShmSysConfigAndInfo->SysWarningInfo.WarningCount; i++) {
        if (ShmSysConfigAndInfo->SysWarningInfo.WarningCode[i][1] >= 0x33) { //from backend or power cabinet
            Rtn = 0;
            for (count = 0; count < (Tmp / 6); count++) {
                if (memcmp(&ShmSysConfigAndInfo->SysWarningInfo.WarningCode[i][0], StatusArray[count], 6) == 0) {
                    Rtn = 1;
                    break;
                }
            }
            if (Rtn == 0) {
                memset(EventCodeTmp, 0, sizeof(EventCodeTmp));
                memcpy(EventCodeTmp, ShmSysConfigAndInfo->SysWarningInfo.WarningCode[i], sizeof(EventCodeTmp));
                RemoveFaultCodeToBuf(EventCodeTmp);
            }
        }
    }
#ifdef Debug
    printf("\n");
#endif
    return 1;
}

int WriteDdStatus()
{
    unsigned char Tmp = 0, count;
    unsigned char TmpBuf[255], CurWarnCodeTmp[10][6], PreWarnCodeTmp[10][6];
    struct ApplicationPacket PacketData;

    if ((ShmSysConfigAndInfo->SysWarningInfo.WarningCount <= 0) && (PreSysWarningInfo.WarningCount <= 0)) {
        return -1;
    }
    memset(CurWarnCodeTmp, 0, sizeof(CurWarnCodeTmp));
    Tmp = ShmSysConfigAndInfo->SysWarningInfo.WarningCount;
    for (count = 0; count < Tmp; count++) {
        memcpy(CurWarnCodeTmp[count], ShmSysConfigAndInfo->SysWarningInfo.WarningCode[count], 6);
    }
    memset(PreWarnCodeTmp, 0, sizeof(PreWarnCodeTmp));
    Tmp = PreSysWarningInfo.WarningCount;
    for (count = 0; count < Tmp; count++) {
        memcpy(PreWarnCodeTmp[count], PreSysWarningInfo.WarningCode[count], 6);
    }
    if (strcmp(CurWarnCodeTmp, PreWarnCodeTmp) == 0) {
        return -1;
    }


    /*memset(TmpBuf,0,sizeof(TmpBuf));
    Tmp=ShmSysConfigAndInfo->SysWarningInfo.WarningCount;
    for(count=0;count<Tmp;count++)
    {
        memcpy(TmpBuf+(count*6),ShmSysConfigAndInfo->SysWarningInfo.WarningCode[count],6);
        #ifdef Debug
        printf("WriteDdStatus(%d) = %s", count, ShmSysConfigAndInfo->SysWarningInfo.WarningCode[count]);
        #endif
    }
    if(SendPacket(0x01, 0x02, 0x04,strlen(TmpBuf), TmpBuf)<=0)
        return -1;
    */
#ifdef Debug
    printf("WriteDdStatus => ");
#endif
    if (SendPacket(0x01, 0x02, 0x04, strlen(CurWarnCodeTmp), CurWarnCodeTmp) <= 0) {
#ifdef Debug
        printf("SendPacket Fail\n");
#endif
        return -1;
    }
    memset(&PacketData, 0, sizeof(struct ApplicationPacket));
    if (RecvPacket(&Tmp, &PacketData) <= 0) {
#ifdef Debug
        printf("RecvPacket Fail\n");
#endif
        return -1;
    }
    if (PacketData.Data[0] != 1) { //!=OK
#ifdef Debug
        printf("NG\n");
#endif
        return -1;
    }
    memset(&PreSysWarningInfo, 0, sizeof(struct WARNING_CODE_INFO));
    memcpy(&PreSysWarningInfo, &(ShmSysConfigAndInfo->SysWarningInfo), sizeof(struct WARNING_CODE_INFO));
#ifdef Debug
    printf("OK,  ");
    Tmp = ShmSysConfigAndInfo->SysWarningInfo.WarningCount;
    for (count = 0; count < Tmp; count++) {
        printf("(%d)%s,  ", count, ShmSysConfigAndInfo->SysWarningInfo.WarningCode[count]);
    }
    printf("\n");
#endif
    return 1;
}

int ReadChargingCapability(unsigned char PlugNum)
{
    unsigned char Tmp = 0;
    struct ApplicationPacket PacketData;
    float MaxVolt, MaxCurrent, MaxPower;

#ifdef Debug
    printf("Read Charging Capability => ");
#endif
    memset(&PacketData, 0, sizeof(struct ApplicationPacket));
    if (SendPacket(PlugNum, 0x01, 0x05, 0, PacketData.Data) <= 0) {
#ifdef Debug
        printf("SendPacket Fail\n");
#endif
        return -1;
    }
    if (RecvPacket(&Tmp, &PacketData) <= 0) {
#ifdef Debug
        printf("RecvPacket Fail\n");
#endif
        return -1;
    }
    if (PacketData.Data[0] != 1) { //!=OK
#ifdef Debug
        printf("NG\n");
#endif
        return -1;
    }
    MaxVolt = (float)(PacketData.Data[1] << 8 | PacketData.Data[2]);
    MaxCurrent = (float)(PacketData.Data[3] << 8 | PacketData.Data[4]);
    MaxPower = (float)(PacketData.Data[5] << 8 | PacketData.Data[6]);
    if ((MaxVolt >= 0) && (MaxVolt <= 10000)) {
        ChargingData[PlugNum - 1]->MaximumChargingVoltage = MaxVolt;
    }
    if ((MaxCurrent >= 0) && (MaxCurrent <= 5000)) {
        ChargingData[PlugNum - 1]->AvailableChargingCurrent = MaxCurrent;
    }
    if ((MaxPower >= 0) && (MaxPower <= 3600)) {
        ChargingData[PlugNum - 1]->AvailableChargingPower = MaxPower;
    }
#ifdef Debug
    printf(" MaxVolt=%f, MaxCurrent=%f, MaxPower=%f,\n", MaxVolt, MaxCurrent, MaxPower);
#endif
    return 1;
}

int WriteChargingTarget(unsigned char PlugNum)
{
    unsigned char Tmp = 0;
    unsigned char TmpBuf[255];
    struct ApplicationPacket PacketData;
    float ChargingVolt, ChargingAmp;

    memset(TmpBuf, 0, sizeof(TmpBuf));
    memset(&PacketData, 0, sizeof(struct ApplicationPacket));

    ChargingVolt = ChargingData[PlugNum - 1]->EvBatterytargetVoltage;
    ChargingAmp = ChargingData[PlugNum - 1]->EvBatterytargetCurrent;
    ChargingVolt *= 10;
    ChargingAmp *= 10;
    TmpBuf[0] = ((unsigned short)ChargingVolt >> 8) & 0xFF;
    TmpBuf[1] = ((unsigned short)ChargingVolt) & 0xFF;
    TmpBuf[2] = ((unsigned short)ChargingAmp >> 8) & 0xFF;
    TmpBuf[3] = ((unsigned short)ChargingAmp) & 0xFF;
#ifdef Debug
    printf("WriteChargingTarget(%d), EvBatterytargetVoltage=%f,EvBatteryMaxVoltage=%f => ",
           PlugNum, ChargingData[PlugNum - 1]->EvBatterytargetVoltage, ChargingData[PlugNum - 1]->EvBatteryMaxVoltage);
#endif
    if (SendPacket(PlugNum, 0x02, 0x06, 4, TmpBuf) <= 0) {
#ifdef Debug
        printf("SendPacket Fail\n");
#endif
        return -1;
    }
    if (RecvPacket(&Tmp, &PacketData) <= 0) {
#ifdef Debug
        printf("RecvPacket Fail\n");
#endif
        return -1;
    }
    if (PacketData.Data[0] != 1) { //!=OK
#ifdef Debug
        printf("NG\n");
#endif
        return -1;
    }
#ifdef Debug
    printf("ChargingVolt=%f, ChargingAmp=%f\n", ChargingVolt / 10, ChargingAmp / 10);
#endif

    return 1;
}
int ReadSoftwareUpdate()
{
    unsigned char Tmp = 0;
    struct ApplicationPacket PacketData;

    memset(&PacketData, 0, sizeof(struct ApplicationPacket));

    if (SendPacket(0x01, 0x01, 0x07, 0, PacketData.Data) <= 0) {
        return -1;
    }
    if (RecvPacket(&Tmp, &PacketData) <= 0) {
        return -1;
    }
    if (PacketData.Data[0] != 1) { //!=OK
        return -1;
    }
    if (PacketData.Data[1] != 0x01) { //not update
        return -1;
    }
    return PacketData.Data[1];
}
int WritePlugInStatus(unsigned char PlugNum)
{
    unsigned char Tmp = 0;
    unsigned char TmpBuf[255];
    struct ApplicationPacket PacketData;

    memset(TmpBuf, 0, sizeof(TmpBuf));
    memset(&PacketData, 0, sizeof(struct ApplicationPacket));
    TmpBuf[0] = ChargingData[PlugNum - 1]->ConnectorPlugIn;
#ifdef Debug
    printf("WritePlugInStatus(%d) =>", PlugNum);
#endif
    if (SendPacket(PlugNum, 0x02, 0x08, 1, TmpBuf) <= 0) {
#ifdef Debug
        printf("SendPacket Fail\n");
#endif
        return -1;
    }
    if (RecvPacket(&Tmp, &PacketData) <= 0) {
#ifdef Debug
        printf("RecvPacket Fail\n");
#endif
        return -1;
    }
    if (PacketData.Data[0] != 1) { //!=OK
#ifdef Debug
        printf("NG\n");
#endif
        return -1;
    }
#ifdef Debug
    printf(" %s\n", TmpBuf[0] == 1 ? "Plug-in" : "Un-plug");
#endif

    return 1;
}

int WriteConnectorState(unsigned char PlugNum)
{
    unsigned char Tmp = 0;
    unsigned char TmpBuf[255];
    struct ApplicationPacket PacketData;


    memset(TmpBuf, 0, sizeof(TmpBuf));
    memset(&PacketData, 0, sizeof(struct ApplicationPacket));

    if (ChargingData[PlugNum - 1]->SystemStatus <= 2) {
        TmpBuf[0] = 0;    //idle
    } else if ((ChargingData[PlugNum - 1]->SystemStatus <= 7) || (ChargingData[PlugNum - 1]->SystemStatus == 17) || (ChargingData[PlugNum - 1]->SystemStatus == 18)) {
        TmpBuf[0] = 1;    //preparing
    } else if (ChargingData[PlugNum - 1]->SystemStatus == 8) {
        TmpBuf[0] = 2;    //charging
    } else if (ChargingData[PlugNum - 1]->SystemStatus == 9) {
        TmpBuf[0] = 3;    //terminating
    }

#ifdef Debug
    printf("WriteConnectorState(%d) SystemStatus=%d,TmpBuf[0]=%d => ", PlugNum, ChargingData[PlugNum - 1]->SystemStatus, TmpBuf[0]);
#endif
    if (SendPacket(PlugNum, 0x02, 0x09, 1, TmpBuf) <= 0) {
#ifdef Debug
        printf("SendPacket Fail\n");
#endif
        return -1;
    }
    if (RecvPacket(&Tmp, &PacketData) <= 0) {
#ifdef Debug
        printf("RecvPacket Fail\n");
#endif
        return -1;
    }
    if (PacketData.Data[0] != 1) { //!=OK
#ifdef Debug
        printf("NG\n");
#endif
        return -1;
    }
#ifdef Debug
    printf(" %d\n", TmpBuf[0]);
#endif

    return 1;
}

int WriteUserID(unsigned char ConnectorID, unsigned char *UserID)
{
    unsigned char Tmp = 0;
    unsigned char TmpBuf[255];
    struct ApplicationPacket PacketData;

    if (strlen(UserID) <= 0) {
        return -1;
    }
    memset(TmpBuf, 0, sizeof(TmpBuf));
    memset(&PacketData, 0, sizeof(struct ApplicationPacket));
    strcpy(TmpBuf, UserID);
#ifdef Debug
    printf("WriteUserID(%d) => ", ConnectorID);
#endif
    if (SendPacket(ConnectorID, 0x02, 0x0A, strlen(TmpBuf), TmpBuf) <= 0) {
#ifdef Debug
        printf("SendPacket Fail\n");
#endif
        return -1;
    }
    if (RecvPacket(&Tmp, &PacketData) <= 0) {
#ifdef Debug
        printf("RecvPacket Fail\n");
#endif
        return -1;
    }
    if (PacketData.Data[0] != 1) { //!=OK
#ifdef Debug
        printf("NG\n");
#endif
        return -1;
    }
#ifdef Debug
    printf(" StartUserId=%s, PacketData.Data[1]=%d\n", TmpBuf, PacketData.Data[1]);
#endif
    return PacketData.Data[1];
}

int ReadChargePermission(unsigned char PlugNum)
{
    unsigned char Tmp = 0;
    struct ApplicationPacket PacketData;


    memset(&PacketData, 0, sizeof(struct ApplicationPacket));
#ifdef Debug
    printf("ReadChargePermission[%d] => ", PlugNum);
#endif
    if (SendPacket(PlugNum, 0x01, 0x0B, 0, PacketData.Data) <= 0) {
#ifdef Debug
        printf("SendPacket Fail\n");
#endif
        return -1;
    }
    if (RecvPacket(&Tmp, &PacketData) <= 0) {
#ifdef Debug
        printf("RecvPacket Fail\n");
#endif
        return -1;
    }
    if (PacketData.Data[0] != 1) { //!=OK
#ifdef Debug
        printf("NG\n");
#endif
        return -1;
    }
#ifdef Debug
    printf(" %s\n", PacketData.Data[1] == 1 ? "Permitted" : "NOT permitted" );
#endif

    return PacketData.Data[1];
}

int FindChargingInfoData(byte target, struct ChargingInfoData **chargingData)
{
    for (byte index = 0; index < CHAdeMO_QUANTITY; index++) {
        if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == target) {
            chargingData[target] = &ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index];
            return 1;
        }
    }

    for (byte index = 0; index < CCS_QUANTITY; index++) {
        if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == target) {
            chargingData[target] = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[index];
            return 1;
        }
    }

    for (byte index = 0; index < GB_QUANTITY; index++) {
        if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == target) {
            chargingData[target] = &ShmSysConfigAndInfo->SysInfo.GbChargingData[index];
            return 1;
        }
    }

    return 0;
}

int MessageTrigger(unsigned char connectorID)
{
    struct timeb  NowTime;
    unsigned char Reg;
    for (Reg = 0; Reg < TriggerMsgeNum; Reg++) {
        ftime(&NowTime);
        switch (Reg) {
        case 3://ReadDoStatus
            if (DiffTimeb(TriggerTimeUp[connectorID - 1][Reg], NowTime) > 1000) {
                if (ReadDoStatus()) {
                    ftime(&TriggerTimeUp[connectorID - 1][Reg]);
                }
            }
            break;
        case 4://WriteDdStatus
            if (DiffTimeb(TriggerTimeUp[connectorID - 1][Reg], NowTime) > 1000) {
                if (WriteDdStatus()) {
                    ftime(&TriggerTimeUp[connectorID - 1][Reg]);
                }
            }
            break;
        /*case 5://ReadChargingCapability
            if(DiffTimeb(TriggerTimeUp[connectorID-1][Reg],NowTime)>200)
            {
                if(ReadChargingCapability(connectorID))
                {
                    ftime(&TriggerTimeUp[connectorID-1][Reg]);
                }
            }
            break;
        case 6://WriteChargingTarget
            if(DiffTimeb(TriggerTimeUp[connectorID-1][Reg],NowTime)>100)
            {
                if(WriteChargingTarget(connectorID))
                {
                    ftime(&TriggerTimeUp[connectorID-1][Reg]);
                }
            }
            break;*/
        case 8://WritePlugInStatus
            if (DiffTimeb(TriggerTimeUp[connectorID - 1][Reg], NowTime) > 1000) {
                if (WritePlugInStatus(connectorID)) {
                    ftime(&TriggerTimeUp[connectorID - 1][Reg]);
                }
            }
            break;
        case 9://WriteConnectorState
            if (DiffTimeb(TriggerTimeUp[connectorID - 1][Reg], NowTime) > 1000) {
                if (WriteConnectorState(connectorID)) {
                    ftime(&TriggerTimeUp[connectorID - 1][Reg]);
                }
            }
            break;
        /*case 0x0B://ReadChargePermission
            if(DiffTimeb(TriggerTimeUp[connectorID-1][Reg],NowTime)>1000)
            {
                if(ReadChargePermission(connectorID))
                {
                    ftime(&TriggerTimeUp[connectorID-1][Reg]);
                }
            }
            break;*/
        default:
            break;
        }
    }
}

int main(int argc, char *argv[])
{
    unsigned char Tmp, PlugNum;
    int Rtn;
    struct timeb  AuthNowTime;

    /**************** Initialization **********/
    if (InitShareMemory() == 0) {
#ifdef SystemLogMessage
        DEBUG_ERROR("InitShareMemory NG\n");
#endif
        if (ShmStatusCodeData != NULL) {
            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory = 1;
        }
        sleep(5);
        return 0;
    }

ReConnect:
    memset(&PreSysWarningInfo, 0, sizeof(struct WARNING_CODE_INFO));
    PacketSe = 0;
    DisconnectFlag = 0;
    for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++) {
        if (!FindChargingInfoData(_index, &ChargingData[0])) {
            DEBUG_ERROR("FindChargingInfoData false \n");
            break;
        }
    }

    /**************** Check Network **********/
    DEBUG_INFO("Check Dispenser Network Information");
    while (!CheckNetworkStatus()) {
        sleep(1);
        if (DisconnectFlag >= 10) {
            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DisconnectedFromDo = 1;
        } else {
            DisconnectFlag++;
        }
    }
    DEBUG_INFO("Dispenser Network Information checked: IP=%s Netmask=%s, Gateway=%s",
               ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress,
               ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthSubmaskAddress,
               ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthGatewayAddress);

    /**************** Power cabinet connection **********/
    DEBUG_INFO("Connect to Power Cabinet");
    while (TcpConnected() < 0) {
        sleep(1);
        if (DisconnectFlag >= 5) {
            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DisconnectedFromDo = 1;
        } else {
            DisconnectFlag++;
        }
    }
    DEBUG_INFO("Power cabinet connected(TcpSock=%d): IP=%s Netmask=%s, Gateway=%s",
               TcpSock,
               ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress,
               ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthSubmaskAddress,
               ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthGatewayAddress);

    /**************** Write Model Name**********/
    DEBUG_INFO("Write Model Name");
    while (WriteModelName() < 0) {
        sleep(1);
        if (DisconnectFlag >= 5) {
            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DisconnectedFromDo = 1;
        } else {
            DisconnectFlag++;
        }
    }
    DEBUG_INFO("Write Model Name OK: %s", ShmSysConfigAndInfo->SysConfig.ModelName);

    /**************** Get Connector ID**********/
    DEBUG_INFO("Get Connector ID");
    while (ReadConnectorID() < 0) {
        sleep(1);
        if (DisconnectFlag >= 5) {
            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DisconnectedFromDo = 1;
        } else {
            DisconnectFlag++;
        }
    }
    DEBUG_INFO("Get Connector ID OK");
    /*while(1)
    {
        //for self testin main.c
        if(ShmSysConfigAndInfo->SysInfo.SelfTestSeq >= _STEST_PSU_DETECT)
        {
            ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_PSU_CAP;
            break;
        }
    }*/
    for (Tmp = 0; Tmp < TriggerMsgeNum; Tmp++) {
        ftime(&TriggerTimeUp[0][Tmp]);
        ftime(&TriggerTimeUp[1][Tmp]);
        usleep(50000);
    }
    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DisconnectedFromDo = 0;
    DEBUG_INFO("Start Communication");
    /**************** Data transmission**********/
    while (1) {
        if ((ShmOCPP16Data->SpMsg.bits.AuthorizeReq == 1) || (ShmSysConfigAndInfo->SysInfo.AuthorizeFlag == 1)) {
            ftime(&AuthNowTime);
            if (DiffTimeb(TriggerTimeUp[0][10], AuthNowTime) > 1000) {
                Rtn = WriteUserID(ShmSysConfigAndInfo->SysInfo.CurGunSelected, ShmSysConfigAndInfo->SysConfig.UserId);
                if (Rtn >= 0) {
                    memset(ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, 0, sizeof(ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status));
                    if (Rtn == 0) {
                        strcpy(ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Invalid");
                    } else {
                        strcpy(ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted");
                    }
                    ShmOCPP16Data->SpMsg.bits.AuthorizeConf = 1; //isAuthorizedComplete
                    ShmOCPP16Data->SpMsg.bits.AuthorizeReq = 0;
                    ShmSysConfigAndInfo->SysInfo.AuthorizeFlag = 0;
                    ShmPsuData->SystemAvailablePower = 0;
                    ShmPsuData->SystemPresentPsuQuantity = 0;
                }
                ftime(&TriggerTimeUp[0][10]);
            }
        }

        for (PlugNum = 1; PlugNum <= ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; PlugNum++) {
            //printf("ChargingData[PlugNum-1]->SystemStatus=%d\n",ChargingData[PlugNum-1]->SystemStatus);
            //printf("ShmOCPP16Data->SpMsg.bits.AuthorizeReq=%d\n",ShmOCPP16Data->SpMsg.bits.AuthorizeReq);
            //printf("ShmSysConfigAndInfo->SysInfo.AuthorizeFlag=%d\n",ShmSysConfigAndInfo->SysInfo.AuthorizeFlag);
            //printf("ChargingData[%d]->FireChargingVoltage=%f\n",PlugNum,ChargingData[PlugNum-1]->FireChargingVoltage);
            //printf("ChargingData[%d]->PresentChargingCurrent=%f\n",PlugNum,ChargingData[PlugNum-1]->PresentChargingCurrent);
            switch (ChargingData[PlugNum - 1]->SystemStatus) {
            case S_IDLE:
            case S_RESERVATION:
            case S_MAINTAIN:
            case S_ALARM:
            case S_AUTHORIZING:
                if ((ShmOCPP16Data->SpMsg.bits.AuthorizeReq == 1) || (ShmSysConfigAndInfo->SysInfo.AuthorizeFlag == 1)) {
                    ftime(&AuthNowTime);
                    if (DiffTimeb(TriggerTimeUp[PlugNum - 1][10], AuthNowTime) > 1000) {
                        Rtn = WriteUserID(ShmSysConfigAndInfo->SysInfo.CurGunSelected, ShmSysConfigAndInfo->SysConfig.UserId);
                        if (Rtn >= 0) {
                            memset(ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, 0, sizeof(ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status));
                            if (Rtn == 0) {
                                strcpy(ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Invalid");
                            } else {
                                strcpy(ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status, "Accepted");
                            }
                            ShmOCPP16Data->SpMsg.bits.AuthorizeConf = 1; //isAuthorizedComplete
                            ShmOCPP16Data->SpMsg.bits.AuthorizeReq = 0;
                            ShmSysConfigAndInfo->SysInfo.AuthorizeFlag = 0;
                            ShmPsuData->SystemAvailablePower = 0;
                            ShmPsuData->SystemPresentPsuQuantity = 0;
                            ftime(&TriggerTimeUp[PlugNum - 1][10]);

                        }
                        ftime(&TriggerTimeUp[PlugNum - 1][10]);
                    }
                }
                /*if(ReadSoftwareUpdate())//0x07
                {
                    //firmware update
                }*/
                break;
            case S_PREPARNING: //get permission
                //printf("S_PREPARNING\n");
                ftime(&AuthNowTime);
                if (DiffTimeb(TriggerTimeUp[PlugNum - 1][11], AuthNowTime) > 1000) {
                    if ((ReadChargePermission(PlugNum)) && (ReadChargingCapability(PlugNum))) {
                        ShmPsuData->SystemAvailablePower = ChargingData[0]->AvailableChargingPower + ChargingData[1]->AvailableChargingPower;
                        ShmPsuData->SystemPresentPsuQuantity = ShmPsuData->SystemAvailablePower / 30;
                    }
                    ftime(&TriggerTimeUp[PlugNum - 1][11]);
                }
                break;
            case S_PREPARING_FOR_EV://wait connector lock
                //printf("S_PREPARING_FOR_EV\n");
                ftime(&AuthNowTime);
                if (DiffTimeb(TriggerTimeUp[PlugNum - 1][5], AuthNowTime) > 1000) {
                    ReadChargingCapability(PlugNum);
                    ftime(&TriggerTimeUp[PlugNum - 1][5]);
                }
                ftime(&AuthNowTime);
                if (DiffTimeb(TriggerTimeUp[PlugNum - 1][11], AuthNowTime) > 1000) {
                    if (ReadChargePermission(PlugNum) == 0) {
                        DEBUG_INFO("Stop charging by power cabinet's permission");
                        ChargingData[PlugNum - 1]->StopChargeFlag = 1;
                    }
                    ftime(&TriggerTimeUp[PlugNum - 1][11]);
                }
                break;
            case S_PREPARING_FOR_EVSE: //insaulation test
            case S_CCS_PRECHARGE_ST0:
            case S_CCS_PRECHARGE_ST1:
                //printf("S_PREPARING_FOR_EVSE\n");
                WriteChargingTarget(PlugNum);
                ftime(&AuthNowTime);
                if (DiffTimeb(TriggerTimeUp[PlugNum - 1][5], AuthNowTime) > 1000) {
                    ReadChargingCapability(PlugNum);
                    ftime(&TriggerTimeUp[PlugNum - 1][5]);
                }
                ftime(&AuthNowTime);
                if (DiffTimeb(TriggerTimeUp[PlugNum - 1][11], AuthNowTime) > 1000) {
                    if (ReadChargePermission(PlugNum) == 0) {
                        DEBUG_INFO("Stop charging by power cabinet's permission");
                        ChargingData[PlugNum - 1]->StopChargeFlag = 1;
                    }
                    ftime(&TriggerTimeUp[PlugNum - 1][11]);
                }
                break;
            case S_CHARGING: //charging
            case S_TERMINATING:
                //printf("S_CHARGING,S_TERMINATING\n");
                ftime(&AuthNowTime);
                if (DiffTimeb(TriggerTimeUp[PlugNum - 1][5], AuthNowTime) > 1000) {
                    ReadChargingCapability(PlugNum);
                    ftime(&TriggerTimeUp[PlugNum - 1][5]);
                }
                ftime(&AuthNowTime);
                if (DiffTimeb(TriggerTimeUp[PlugNum - 1][11], AuthNowTime) > 1000) {
                    if (ReadChargePermission(PlugNum) == 0) {
                        DEBUG_INFO("Stop charging by power cabinet's permission");
                        ChargingData[PlugNum - 1]->StopChargeFlag = 1;
                    }
                    ftime(&TriggerTimeUp[PlugNum - 1][11]);
                }
                WriteChargingTarget(PlugNum);
                //printf("ChargingData[%d]->FireChargingVoltage=%f\n",PlugNum,ChargingData[PlugNum-1]->FireChargingVoltage);
                //printf("ChargingData[%d]->PresentChargingCurrent=%f\n",PlugNum,ChargingData[PlugNum-1]->PresentChargingCurrent);
                break;
            default:
                break;
            }//switch   case
            MessageTrigger(PlugNum);
        }//for connector #
        if (DisconnectFlag >= 10) {
            if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DisconnectedFromDo == 0) {
                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DisconnectedFromDo = 1;
                DEBUG_INFO("Disconnected from power cabinet...re-connecting");
            }
            goto ReConnect;
        }
    }//while(1)
}